Compare commits

...

347 Commits

Author SHA1 Message Date
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
James Cole
4dea3a5f55 Merge branch 'release/5.2.0-alpha.1' 2020-03-24 07:22:23 +01:00
James Cole
7303d8b899 Meta files for release 5.2.0-alpha.1 2020-03-24 07:13:13 +01:00
James Cole
fa0caa6518 Meta files for release 5.2.0-alpha.1 2020-03-24 07:11:30 +01:00
James Cole
26be90eff1 Meta files for release 5.2.0-alpha.1 2020-03-24 07:11:05 +01:00
James Cole
db3c9fbd28 Can't remove your own admin rights. 2020-03-24 05:57:04 +01:00
James Cole
87b62e2e72 New strings. 2020-03-24 05:53:05 +01:00
James Cole
1e6224f041 Fix #3203 2020-03-23 20:23:38 +01:00
James Cole
d6797b8428 Allow users to hand out admin rights. 2020-03-23 17:54:49 +01:00
James Cole
76c89a8efa Fix #3202 2020-03-23 11:01:00 +01:00
James Cole
1797880488 Code for #3057 2020-03-22 18:27:20 +01:00
James Cole
cdebde5a2b Fixed #3048 2020-03-22 17:28:25 +01:00
James Cole
5ee1f322d0 hide button and checkbox [skip ci] 2020-03-22 08:18:38 +01:00
James Cole
87273e232a hide button and checkbox [skip ci] 2020-03-22 08:18:05 +01:00
James Cole
53b77e6bf9 hide cat and bud [skip ci] 2020-03-22 08:17:02 +01:00
James Cole
b8696bf8b5 hide date [skip ci] 2020-03-22 08:15:52 +01:00
James Cole
8436a86536 Hide icon [skip ci] 2020-03-22 08:14:47 +01:00
James Cole
c598151c68 Hide some fields. 2020-03-22 08:13:39 +01:00
James Cole
53938f3c12 Make table responsive. 2020-03-22 08:10:09 +01:00
James Cole
0813464fe0 Hard stop if feature flag is disabled. 2020-03-22 08:06:36 +01:00
James Cole
4436c9939e Add error message. 2020-03-22 08:04:35 +01:00
James Cole
5e323b958f Update strings and view for telemetry (inactive) 2020-03-22 07:55:57 +01:00
James Cole
367f225f38 Limit to 50. 2020-03-22 06:59:46 +01:00
James Cole
a97d7058ff Telemetry cron job. 2020-03-21 21:32:17 +01:00
James Cole
9d7fb0efe1 Remove slash 2020-03-21 21:13:41 +01:00
James Cole
1e9596bba0 Add URL of (inactive) telemetry endpoint. 2020-03-21 21:08:41 +01:00
James Cole
c6d17e9bd7 Reformat code. 2020-03-21 15:43:41 +01:00
James Cole
f76585dc9b Update (disabled) telemetry settings. 2020-03-21 15:42:37 +01:00
James Cole
cf4f76f211 Fix bar, also multi currency #2977 2020-03-21 15:12:23 +01:00
James Cole
790e29f15e Update the amount, not yet the bar #2977 2020-03-21 14:50:54 +01:00
James Cole
2107406d8b Clean up and simplify 2020-03-21 14:20:40 +01:00
James Cole
b91a21a081 Move more code to trait. 2020-03-21 09:41:04 +01:00
James Cole
170e35aecc Wrong variable name. 2020-03-21 09:35:25 +01:00
James Cole
5701597e20 Some more moved to traits. 2020-03-21 09:01:14 +01:00
James Cole
d16389748f Move code to traits. 2020-03-21 08:54:38 +01:00
James Cole
ee844e970f Move to separate traits. 2020-03-21 08:11:14 +01:00
James Cole
62757812ff Refactor group validation 2020-03-21 06:01:27 +01:00
James Cole
c15b72b6b0 Refactor currency validation 2020-03-21 06:00:36 +01:00
James Cole
11e3834235 Refactor validation method. 2020-03-21 05:56:27 +01:00
James Cole
affc198b03 Cleanup for #2999 2020-03-21 05:47:49 +01:00
James Cole
d5b315e3c8 Experimental chart for #2999 2020-03-21 05:26:39 +01:00
James Cole
eb31ff4ebb Remove comma 2020-03-20 18:23:21 +01:00
James Cole
9ab36d4598 Update composer files. 2020-03-20 18:15:24 +01:00
James Cole
bf06f8eac3 Add telemetry config (inactive) 2020-03-20 18:06:24 +01:00
James Cole
fa9befba11 Remove TODO [skip ci] 2020-03-20 18:06:08 +01:00
James Cole
3b0c061ec7 Model and some basic code for Telemetry (inactive) 2020-03-20 18:05:58 +01:00
James Cole
d021be6a25 Add telemetry (inactive) 2020-03-20 18:05:40 +01:00
James Cole
69ee691497 Fix null pointer. 2020-03-20 17:59:56 +01:00
James Cole
5a7152ceec Clean up config. 2020-03-20 17:31:54 +01:00
James Cole
7b216543fa Update instructions 2020-03-20 17:21:45 +01:00
James Cole
cd3f3fd781 Fix #2985 2020-03-20 15:52:20 +01:00
James Cole
4b0e46af2b Whoops 2020-03-20 15:42:56 +01:00
James Cole
470ab6340c Fix #2985 2020-03-20 08:41:20 +01:00
James Cole
9e54ebe6a9 Fix #2958 2020-03-20 04:42:19 +01:00
James Cole
7eb2451e3d Improved chart for #2938 2020-03-20 04:37:45 +01:00
James Cole
6dba44ba71 Show attachments to tags #2828 2020-03-19 18:51:47 +01:00
James Cole
64683647bd Piggy supports view of attachments #2828 2020-03-19 18:44:45 +01:00
James Cole
1f919b6d0e Attachments for categories #2828 2020-03-19 18:37:57 +01:00
James Cole
417a0d0f83 Show attachments for budgets #2828 2020-03-19 18:28:02 +01:00
James Cole
9b53576fc2 Show attachments for bills #2828 2020-03-19 18:23:34 +01:00
James Cole
2a46756838 Attachments for accounts are visible #2828 2020-03-19 18:20:23 +01:00
James Cole
cdf055065f Remove unused method. 2020-03-19 15:21:44 +01:00
James Cole
2cee008e4a Clean up a little bit. 2020-03-19 15:16:59 +01:00
James Cole
d889e39aad Clean up method. 2020-03-19 14:33:41 +01:00
James Cole
72b9ecf07e Simplify trait. 2020-03-19 14:28:38 +01:00
James Cole
14f4351920 Can upload attachments for all models #2828 2020-03-19 09:14:49 +01:00
James Cole
12e81364a0 Make sure all controllers can store attachment when creating models #2828 2020-03-19 09:01:35 +01:00
James Cole
d489244c00 Add attachment helper to relevant classes #2828 2020-03-19 08:58:55 +01:00
James Cole
aceaf5f891 Add attachment thing to views #2828 2020-03-19 08:56:00 +01:00
James Cole
6129b9d25c Make upload size globally available #2828 2020-03-19 08:43:52 +01:00
James Cole
75afe35e98 API can deal with attachments for more models. #2828 2020-03-19 08:32:42 +01:00
James Cole
3246b7eb9f Allow more models to accept transactions #2828 2020-03-18 21:36:26 +01:00
James Cole
c412ffc195 Short array syntax #3197 2020-03-18 20:58:25 +01:00
James Cole
7c3b5fe714 Merge pull request #3197 from rubenverhoef/CSV-ING
Fix small issue from #3146
2020-03-18 19:57:42 +00:00
James Cole
ae967c027b Merge branch 'develop' into CSV-ING 2020-03-18 19:56:50 +00:00
James Cole
3e74fce885 Simplify method. 2020-03-18 20:55:31 +01:00
James Cole
2c7891bfb2 Merge pull request #3196 from firefly-iii/analysis-3wxmk5
Apply fixes from StyleCI
2020-03-18 19:46:02 +00:00
James Cole
712ba00c9e Apply fixes from StyleCI 2020-03-18 19:45:45 +00:00
James Cole
74683b18f2 Fix bad namespace. 2020-03-18 15:38:28 +01:00
James Cole
d0d129d965 Fix #3193 2020-03-18 15:29:32 +01:00
Ruben Verhoef
87d459c5ff Check if Valutadatum is found in row 8, when not found do nothing! 2020-03-17 19:43:03 +01:00
James Cole
5b591ff744 Whoops 2020-03-17 17:41:59 +01:00
James Cole
63f00cbb7b Remove unused index 2020-03-17 17:41:43 +01:00
James Cole
c90b26c181 Simplify method. 2020-03-17 17:41:06 +01:00
James Cole
c136c60eae Merge pull request #3195 from firefly-iii/analysis-rdjLrQ
Apply fixes from StyleCI
2020-03-17 16:07:00 +00:00
James Cole
ba4c1d95a7 Apply fixes from StyleCI 2020-03-17 16:06:30 +00:00
James Cole
9a25d6a741 Code cleanup that (hopefully) matches style CI 2020-03-17 16:46:00 +01:00
James Cole
91c067ac9f Code cleanup that (hopefully) matches style CI 2020-03-17 15:03:08 +01:00
James Cole
24129ab69c Code cleanup that (hopefully) matches style CI 2020-03-17 15:02:57 +01:00
James Cole
2b6c3fd743 Code cleanup that (hopefully) matches style CI 2020-03-17 15:01:00 +01:00
James Cole
bd2f064eeb Code cleanup that (hopefully) matches style CI 2020-03-17 14:57:04 +01:00
James Cole
b0c9fc0792 Code cleanup that (hopefully) matches style CI 2020-03-17 14:54:25 +01:00
James Cole
e02e747f1b Code cleanup that (hopefully) matches style CI 2020-03-17 14:53:17 +01:00
James Cole
64462812fc Two small method improvements. 2020-03-17 14:46:17 +01:00
James Cole
46382b0d21 Simplify method. 2020-03-16 19:45:23 +01:00
James Cole
a7fffa5868 Make method smaller. 2020-03-16 19:40:48 +01:00
James Cole
4334928fbd Add sort to language. 2020-03-16 06:54:18 +01:00
James Cole
a478d1b544 Add sort to language. 2020-03-16 06:53:10 +01:00
James Cole
08b69dfbf6 Update language strings for Vietnamese. 2020-03-16 06:50:51 +01:00
James Cole
b631adbbf2 Update language strings. 2020-03-16 06:47:06 +01:00
James Cole
fbd88d03c5 Add support for Vietnamese. 2020-03-16 06:46:48 +01:00
James Cole
4982f6f919 Cleanup method 2020-03-15 18:12:36 +01:00
James Cole
6a6bf102b6 Cleanup method. 2020-03-15 18:05:24 +01:00
James Cole
524f85b9c1 Delete import related tests 2020-03-15 15:33:00 +01:00
James Cole
328c960950 Fix API tests 2020-03-15 15:32:09 +01:00
James Cole
208bece7ea Clean up validation 2020-03-15 15:31:59 +01:00
James Cole
16f918a294 Mark all import related code as deprecated 2020-03-15 15:31:51 +01:00
James Cole
9d90beb790 update libraries for better keyboard use. 2020-03-15 15:17:07 +01:00
James Cole
d7e953d38c Clean up complicated method. 2020-03-15 09:54:44 +01:00
James Cole
6967bb003e Do some code cleanup. 2020-03-15 08:16:16 +01:00
James Cole
f63e51fea2 Fix issue with null pointers. 2020-03-15 07:48:02 +01:00
James Cole
33c73701d8 Button to duplicate rule. #2957 2020-03-14 21:01:21 +01:00
James Cole
50b710b4f6 Expand charts. 2020-03-14 20:30:31 +01:00
James Cole
d1325ffbd8 New charts for #2726 2020-03-14 19:12:32 +01:00
James Cole
bfc6a70c9f Fix #3154 2020-03-14 16:56:58 +01:00
James Cole
a00f46faa9 Also create initial budget limit. 2020-03-14 15:18:32 +01:00
James Cole
c475f05652 Updated library. 2020-03-14 10:29:32 +01:00
James Cole
d42b9ee017 Initial changelog. 2020-03-14 10:29:23 +01:00
James Cole
cccaae49a5 Dont forget to enable recurring cron job. 2020-03-14 10:27:43 +01:00
James Cole
1dd3018cb2 Basic cron job for budgeting. 2020-03-14 10:25:12 +01:00
James Cole
7ea32046af Add icon. 2020-03-14 08:03:43 +01:00
James Cole
9bb2f1cfd3 Edit works again 2020-03-14 07:55:00 +01:00
James Cole
fdffed636f Make sure create uses the right fields. 2020-03-14 07:49:11 +01:00
James Cole
bde0732135 Can now update (and remove) auto budget over api 2020-03-14 07:43:49 +01:00
James Cole
d1d11ae717 Can now create auto budget over API 2020-03-14 07:30:55 +01:00
James Cole
309633069c can edit, delete and see in api autobudget 2020-03-14 07:01:31 +01:00
James Cole
2ece754927 Can now store and validate auto budget 2020-03-13 21:35:22 +01:00
James Cole
6f98fc0dff First attempt at form. 2020-03-13 21:15:54 +01:00
James Cole
cd65971f5e Some new strings for new model. 2020-03-13 21:15:37 +01:00
James Cole
81d7b7b6a1 New model and migration. 2020-03-13 21:15:21 +01:00
James Cole
92ba56ae2b Clean up some forms. 2020-03-13 20:56:26 +01:00
James Cole
e1bcfb9ac9 Merge tag '5.1.1' into develop
5.1.1
2020-03-13 19:40:00 +01:00
James Cole
b398924706 Merge branch 'release/5.1.1' 2020-03-13 19:39:59 +01:00
James Cole
d6f46e23c5 update libraries. 2020-03-13 19:36:12 +01:00
James Cole
8b4066a981 Update language strings. 2020-03-13 19:32:58 +01:00
James Cole
f8a695d7e1 update language strings. 2020-03-13 19:32:11 +01:00
James Cole
630b24716d update changelog 2020-03-13 19:25:33 +01:00
James Cole
be41049e72 Remove some debug. 2020-03-13 18:18:07 +01:00
James Cole
b726e7d106 Improved account list for #2768 2020-03-13 18:17:53 +01:00
James Cole
1058bcd31d Add liabilities to home screen #2768 2020-03-13 15:47:26 +01:00
James Cole
8724ba05ca Fix #2672 2020-03-13 12:46:52 +01:00
James Cole
5145707b94 Test facades. 2020-03-13 08:02:38 +01:00
James Cole
3746cb8c71 Some updated translations. 2020-03-13 07:25:27 +01:00
James Cole
624f2d0bfd Update language strings. 2020-03-13 06:39:25 +01:00
James Cole
1c397ad0ad Add revolut import tool. 2020-03-13 06:23:01 +01:00
James Cole
a2c0f0666f Update transaction form 2020-03-13 06:22:50 +01:00
James Cole
72a4e86e2f Throw better exception. 2020-03-12 05:11:19 +01:00
James Cole
5e8d94d16a Better handling of errors. 2020-03-12 05:06:42 +01:00
James Cole
d92b741088 Remove debug 2020-03-11 14:18:20 +01:00
James Cole
2a4107940f Test debug 2020-03-11 14:17:20 +01:00
James Cole
16d5282929 Better count of transactions. 2020-03-11 14:14:51 +01:00
James Cole
f6ecb143fe Catch some more weird exceptions. 2020-03-11 10:39:53 +01:00
James Cole
f375934b41 Prep for a new auto-complete, and enable foreign currency select. 2020-03-11 10:25:38 +01:00
James Cole
9f8bf6d495 A bunch of empty pages as a place-holder for future telemetry efforts. 2020-03-11 08:13:23 +01:00
James Cole
9e9b55da8e Slightly improved help text. 2020-03-11 07:31:37 +01:00
James Cole
c1654f1d04 Fix #3160 2020-03-11 06:50:23 +01:00
James Cole
c526c4ae1a Update language strings. 2020-03-11 06:44:31 +01:00
James Cole
dcf1609c61 Enable Greek again #3176 2020-03-11 06:41:20 +01:00
James Cole
dd84c7f966 Fix #3182 2020-03-11 06:41:02 +01:00
James Cole
bccde86c0c Do some extra validation, fixes #3182 2020-03-11 05:45:37 +01:00
James Cole
2f17c45b3f Update version. 2020-03-10 19:53:56 +01:00
James Cole
b6bab003cd Clean up and optimize fonts. 2020-03-10 19:51:26 +01:00
James Cole
27d7eb4832 Enable file import because 5.1.1 will probably preclude 5.2.0 2020-03-10 19:24:30 +01:00
James Cole
774f7d88c2 Code for #3180 2020-03-10 18:29:27 +01:00
James Cole
086e4d5880 Fix #3177 2020-03-09 18:25:47 +01:00
James Cole
50f4bf568b Auto enable HIBP check 2020-03-09 18:13:20 +01:00
James Cole
c218c70b1f Make modifiers case insensitive. 2020-03-09 18:13:04 +01:00
James Cole
a939a5ba30 Extra code for #3172 2020-03-08 06:20:27 +01:00
James Cole
25be550e6d Disable file import, add links. 2020-03-07 12:47:22 +01:00
James Cole
9331f8985a Fix #3172 2020-03-07 12:09:18 +01:00
James Cole
41e6c8f73e Fix #3173 2020-03-06 18:23:08 +01:00
James Cole
a29f8d5849 Push minimum password length to 16 characters. 2020-03-06 18:22:44 +01:00
James Cole
9817c0807a Add ability to disable running of rules on transactions. 2020-03-06 09:41:27 +01:00
James Cole
4818baee39 Merge tag '5.1.0' into develop
5.1.0
2020-03-06 05:27:28 +01:00
James Cole
379916ee08 Merge branch 'release/5.1.0' 2020-03-06 05:27:27 +01:00
James Cole
60dbd51259 New meta files and translations. 2020-03-06 05:25:36 +01:00
James Cole
0927b0c8ae Accept strings like a good boy. 2020-03-03 19:36:03 +01:00
James Cole
40cc510057 Fix bad location storage. 2020-02-29 14:08:11 +01:00
James Cole
d580bf8f43 Fix untranslatable strings #3159 2020-02-29 13:58:34 +01:00
James Cole
4434ea40ee Add info about timezones. 2020-02-29 13:58:17 +01:00
James Cole
2ba6ffccbc Catch null pointers 2020-02-28 18:56:27 +01:00
James Cole
ec335ae88c Fix possible null pointer. 2020-02-28 18:53:20 +01:00
James Cole
542c64154c Fix for #3154 2020-02-27 17:35:21 +01:00
James Cole
e4fa437f78 Update libraries. 2020-02-26 20:29:04 +01:00
James Cole
61f3f995ad Update changelog, version and strings. 2020-02-26 20:28:54 +01:00
James Cole
8182cf1efa New texts. 2020-02-26 19:50:36 +01:00
James Cole
10d578503c Merge pull request #3146 from rubenverhoef/ING-CSV
Better CSV import for ING (NL)
2020-02-25 19:21:02 +00:00
Ruben Verhoef
75ee331f36 Move "Valutadatum" to own column
The new column has no name right now, need to fix this
2020-02-23 18:46:17 +01:00
Ruben Verhoef
a32c484fd5 fix typo row -> column 2020-02-23 18:45:56 +01:00
Ruben Verhoef
62d74e05f2 Fix saving accounts copy of account number to row 1 and name to row 3 2020-02-23 18:45:36 +01:00
Ruben Verhoef
23ec5cbaa7 Remove "Omschrijving" but not it's value, only the word. 2020-02-23 18:39:39 +01:00
Ruben Verhoef
21fcb6f853 Correctly remove the "Naam" and it's value 2020-02-23 18:38:21 +01:00
Ruben Verhoef
9b0a890531 Add also "Divers" transaction type 2020-02-23 18:37:41 +01:00
James Cole
af503597e6 Fix #3145 2020-02-23 14:01:08 +01:00
James Cole
e0c99fa80c Fix #3145 2020-02-23 13:15:48 +01:00
James Cole
a486d65893 Fix #3145 2020-02-23 12:42:28 +01:00
James Cole
08a6e22556 Fix redirect, courtesy of @SuperSandro2000 2020-02-23 11:11:38 +01:00
James Cole
2d5c4c8101 Merge tag '5.1.0-beta.1' into develop
5.1.0-beta.1
2020-02-23 07:47:40 +01:00
James Cole
4b7460c1cf Merge branch 'release/5.1.0-beta.1' 2020-02-23 07:47:37 +01:00
James Cole
8c8a2a1596 Fix query for attachment icon. 2020-02-23 07:38:23 +01:00
James Cole
ee7731b1a1 Render new JS 2020-02-23 07:09:51 +01:00
James Cole
36e4462957 Update some language strings. 2020-02-23 07:09:09 +01:00
James Cole
e71a4a5595 update version 2020-02-23 07:05:45 +01:00
James Cole
287aa76d8d update composer 2020-02-23 07:05:36 +01:00
James Cole
a9738fc2a9 Update changelog. 2020-02-23 07:05:30 +01:00
James Cole
bc485363ca Restore attachment icon (not yet in all views). Fixes #3142 2020-02-23 06:59:41 +01:00
James Cole
f53e9d91c0 Fix #3143 2020-02-23 06:37:37 +01:00
James Cole
99fd90ee49 Add installation ID 2020-02-23 06:37:04 +01:00
James Cole
fb77210f2c Add installation ID 2020-02-23 06:36:58 +01:00
James Cole
6c163ebef3 Add debug information. 2020-02-22 11:05:16 +01:00
James Cole
1d8f34275a Flash success message. 2020-02-22 06:28:18 +01:00
James Cole
1fcc2f6b39 Updated a lot of language strings. 2020-02-22 06:21:56 +01:00
James Cole
2eaa31163c Fix link #3140 2020-02-21 20:58:20 +01:00
James Cole
3de4441bcd Trigger cache to fix #3141 2020-02-21 20:47:10 +01:00
James Cole
cbc43b9dc1 Merge pull request #3137 from DanYoSon/trans-format-fix
add 2 <th> to fix header row border, fix alignment on action btn
2020-02-21 05:05:10 +00:00
Daniel Idzerda
d018c57b17 add 2 <th> to fix header row border, fix alignment on action btn 2020-02-20 20:21:03 -05:00
James Cole
a5d0658241 Fix #3135 2020-02-19 20:13:09 +01:00
James Cole
ce29beaf55 Fix bad role names #3129 2020-02-19 20:06:41 +01:00
James Cole
b11bcc1fbe Trigger cache, fixes #3127 2020-02-19 19:55:35 +01:00
James Cole
ab0e77a2e8 New and optimised Vue code, courtesy of @GaryQ 2020-02-19 17:13:01 +01:00
James Cole
80f0637c77 Fix #3130 2020-02-19 07:17:58 +01:00
James Cole
a280319a0b Merge pull request #3131 from cpmsmith/patch-1
Fix search modifiers claiming the whole query
2020-02-18 04:19:51 +00:00
Calum Smith
eb3a55d6e0 Fix search modifiers claiming the whole query
The regex was only restricting to characters without the Unicode property Other, which is most characters, including spaces.
2020-02-17 20:35:15 -05:00
James Cole
64a6661ea4 Update email address. 2020-02-16 14:00:57 +01:00
James Cole
7f46cf805c Update email address. 2020-02-16 13:59:55 +01:00
James Cole
d0d5dea5ce Update email address. 2020-02-16 13:59:41 +01:00
James Cole
018ca29184 Update email address. 2020-02-16 13:58:48 +01:00
James Cole
4b4f78b9eb Update email address. 2020-02-16 13:58:33 +01:00
James Cole
f084e742c9 Update email address. 2020-02-16 13:58:22 +01:00
James Cole
ab4de3fdd6 Update email address. 2020-02-16 13:57:18 +01:00
James Cole
9f7d5b8e88 Update email address. 2020-02-16 13:57:05 +01:00
James Cole
4958f6e4a6 Update email address. 2020-02-16 13:56:52 +01:00
James Cole
b3e3a17add Update email address. 2020-02-16 13:56:35 +01:00
James Cole
0b25fdd043 Update email address. 2020-02-16 13:56:25 +01:00
James Cole
cfc48ccc26 Update email address. 2020-02-16 13:55:59 +01:00
James Cole
3810085ea6 Update email address. 2020-02-16 13:55:52 +01:00
James Cole
0088886915 Update email address. 2020-02-16 13:55:32 +01:00
James Cole
c427404e5d Merge tag '5.1.0-alpha.1' into develop
5.1.0-alpha.1
2020-02-16 06:57:54 +01:00
James Cole
e8bf53ad11 Merge branch 'release/5.1.0-alpha.1' 2020-02-16 06:57:52 +01:00
James Cole
5f7f4328c1 Final files for the 5.1.0-alpha.1 release. 2020-02-16 06:53:52 +01:00
James Cole
1f1829e3b5 Fix a rare issue where ID's are missing. Probably the root cause is something else. 2020-02-15 06:56:39 +01:00
James Cole
8079fab472 Final file update before alpha release. 2020-02-14 13:54:26 +01:00
James Cole
19a428bf2d Fix null pointers. 2020-02-14 13:14:06 +01:00
James Cole
39cdbc461e Fix #3114 2020-02-14 08:43:57 +01:00
James Cole
ccc80dd437 Commit untranslated sentences. 2020-02-14 08:43:23 +01:00
James Cole
f1539c4cba Fix budget limit redirect for #3111 2020-02-14 08:13:12 +01:00
James Cole
796188603b Remove HTML from string. 2020-02-14 08:09:05 +01:00
James Cole
b7210e296f Update JS + language strings. 2020-02-14 08:08:51 +01:00
James Cole
6df03e2537 Updated and new strings. 2020-02-14 08:07:45 +01:00
James Cole
7843e781da Fix #3073 2020-02-14 07:49:29 +01:00
James Cole
bf2d1c223b Throw error for invalid transactions. 2020-02-14 05:46:34 +01:00
James Cole
400c0ccaca Add checks to fix #3119 2020-02-14 05:40:46 +01:00
James Cole
db05839b87 Add checks to fix #3119 2020-02-14 05:39:21 +01:00
James Cole
50d4774907 Merge tag '5.0.5' into develop
5.0.5

# Conflicts:
#	changelog.md
2020-02-13 20:16:17 +01:00
James Cole
4cdc2ade01 update libraries and config. 2020-02-13 20:13:17 +01:00
James Cole
dee6c0e1e4 New string for #3118 2020-02-13 20:11:10 +01:00
James Cole
72491250b7 Add more details to 500 page if user has debug disabled. 2020-02-13 20:10:54 +01:00
James Cole
88e2d8cd55 Fix 500 page. 2020-02-13 20:10:09 +01:00
James Cole
fd04a38359 Fix some button issues. 2020-02-13 20:09:59 +01:00
James Cole
529cb3d387 Fix #3118 2020-02-13 20:09:27 +01:00
James Cole
8d806e6a1d Fix issues related to #3111 2020-02-11 05:34:36 +01:00
James Cole
2a38c9b4ef Fix a rare null pointer 2020-02-10 19:15:35 +01:00
James Cole
2e3e18d836 Merge pull request #3104 from GeoffreyFrogeye/fix_attach_dialog
Fixed Transaction page attachment broken due to #3097
2020-02-09 15:27:33 +00:00
Geoffrey “Frogeye” Preud'homme
156c51798d Fixed Transaction attachment broken due to #3097 2020-02-09 15:36:20 +01:00
James Cole
8fb72fe697 Add todo, uncomment cache line. Expand count 2020-02-09 10:06:38 +01:00
James Cole
ccb1f56573 Various JS changes. 2020-02-09 09:32:33 +01:00
James Cole
c8d2053500 Append changelog. 2020-02-09 09:22:38 +01:00
James Cole
4b5b47a078 Merge branch 'develop' of github.com:firefly-iii/firefly-iii into develop 2020-02-09 09:21:27 +01:00
James Cole
930695b188 Add line 2020-02-09 09:21:20 +01:00
James Cole
d51e5798ef Merge pull request #3100 from Agraphie/master
Move redis comment to different line
2020-02-08 13:40:08 +00:00
Agraphie
edaa2c168a Move redis comment to different line
The comment in the variable caused redis to use `"0" #always use quotes` as redis db index instead of just "0"
2020-02-08 13:55:31 +01:00
James Cole
4dc24939ba Merge branch 'develop' of github.com:firefly-iii/firefly-iii into develop 2020-02-08 12:59:56 +01:00
James Cole
4cd642b8da Fix #3099 2020-02-08 12:59:43 +01:00
James Cole
b77b3f0c21 Merge pull request #3098 from GeoffreyFrogeye/link_type_id
API: Add link_type_id when reading TransactionLink
2020-02-08 11:54:27 +00:00
James Cole
0acc2c5727 Merge pull request #3097 from GeoffreyFrogeye/att_unif
API: Unified attachment_* and model_* for Attachments
2020-02-08 11:54:01 +00:00
Geoffrey “Frogeye” Preud'homme
5aae8b7743 API: Add link_type_id when reading TransactionLink 2020-02-08 12:38:15 +01:00
Geoffrey “Frogeye” Preud'homme
e81ce3317c API: Unified attachment_* and model_* for Attachments 2020-02-08 12:29:23 +01:00
James Cole
cebc0d7568 Add a debug view for transactions. 2020-02-08 06:42:07 +01:00
James Cole
d5cfc12bf3 Clone button. 2020-02-07 20:52:13 +01:00
James Cole
ac931698d3 Code for #3052 2020-02-07 20:51:25 +01:00
James Cole
0c13ac2e93 Fix some old debug code. 2020-02-07 20:50:46 +01:00
James Cole
685107e950 Add DNS to debug. 2020-02-07 18:27:49 +01:00
James Cole
ae57be74e0 Add port to DSN 2020-02-07 18:26:47 +01:00
James Cole
58c0a69737 Fix #3083 2020-02-07 11:16:52 +01:00
James Cole
ab73322c58 Update email addresses. 2020-02-07 11:16:38 +01:00
James Cole
c2e7e00cdd Demo user can trigger error. 2020-02-06 22:01:59 +01:00
James Cole
554a702c0a A special commit for @SuperSandro2000 😉 2020-02-06 21:54:47 +01:00
James Cole
2a3775968c Merge branch 'develop' of github.com:firefly-iii/firefly-iii into develop 2020-02-06 21:48:44 +01:00
James Cole
3cb01a9b50 Update groups.twig 2020-02-06 15:05:29 +01:00
James Cole
e54a011e0c More validation for #3080 2020-02-05 20:37:23 +01:00
James Cole
fc81833b50 Update email address 2020-02-05 05:53:12 +01:00
James Cole
067246be79 Check if object is countable, fix #3080 2020-02-04 19:20:34 +01:00
James Cole
11997f0f97 Fix #3082 2020-02-04 17:39:38 +01:00
James Cole
635ef0de77 Fix #3075 2020-02-03 20:00:02 +01:00
James Cole
7f3522339c Simplify update check. 2020-02-02 10:39:37 +01:00
James Cole
f99f166623 Merge tag '5.0.4' into develop
5.0.4

# Conflicts:
#	changelog.md
#	config/firefly.php
2020-02-01 16:17:24 +01:00
James Cole
fb574cb173 Expand changelog. 2020-02-01 15:54:36 +01:00
James Cole
cf4adae604 Refactor category chart code. 2020-02-01 15:54:26 +01:00
James Cole
3f6719dc70 Add Lando to readme. 2020-02-01 15:44:03 +01:00
James Cole
7cdfbc48a9 Fix #3070 2020-02-01 06:32:28 +01:00
James Cole
28b7bd4d71 Improve box for #3071 2020-02-01 06:19:12 +01:00
James Cole
d056f0d221 Allows the user to set the default language for new and unauthenticated visitors. 2020-01-31 07:39:24 +01:00
James Cole
3771cc3b75 Update email address 2020-01-31 07:32:04 +01:00
James Cole
c7f25c5486 Middleware to generate unique ID for Firefly III installation. 2020-01-31 07:24:41 +01:00
James Cole
b697b71e59 Some updates to the tag overview for #3066 and #3067 2020-01-30 18:56:08 +01:00
James Cole
a6fab50c20 Fix #3064 2020-01-30 18:35:00 +01:00
James Cole
43232c208f Merge tag '5.0.3' into develop
5.0.3

# Conflicts:
#	config/firefly.php
2020-01-30 04:49:28 +01:00
James Cole
1c502667b1 Merge tag '5.0.2' into develop
5.0.2
2020-01-30 04:44:24 +01:00
James Cole
d28bf1f8a4 Update email address 2020-01-28 08:46:01 +01:00
James Cole
091cd05527 Update email address 2020-01-28 08:45:38 +01:00
James Cole
08b9cfa221 Update email address 2020-01-28 08:45:28 +01:00
James Cole
42f585f630 Update email address 2020-01-28 08:44:57 +01:00
James Cole
67fb906855 Expand accounts for #2999 2020-01-27 19:53:05 +01:00
James Cole
6655d2e3d0 Add startofday 2020-01-27 19:37:22 +01:00
James Cole
3711cbd9d7 Fix name of language. 2020-01-27 19:37:14 +01:00
James Cole
17c8be37f5 Update language configuration. 2020-01-27 19:33:58 +01:00
James Cole
90b3bce361 Fix #3042 2020-01-26 07:36:11 +01:00
James Cole
51aca7f415 Second try for #3050 2020-01-26 07:15:47 +01:00
James Cole
a381dc1cfe It's the little things. Fixed #3050 2020-01-25 23:29:26 +01:00
James Cole
bf07859718 Various CSS fixes. 2020-01-25 06:40:41 +01:00
James Cole
996fc4dc7c Code for #2575 2020-01-25 06:32:15 +01:00
James Cole
f598c39c6e Add debug info for #3051 2020-01-25 06:17:17 +01:00
James Cole
f4fd9e5a15 Update email address 2020-01-25 06:08:56 +01:00
James Cole
3adc43938e Make 'stack' log to 'stdout' AND 'daily' to satisfy both Docker and self-hosted users. 2020-01-24 20:40:23 +01:00
James Cole
3f7891f4e8 Fix #3045 2020-01-24 06:02:18 +01:00
James Cole
68d53a2066 Merge tag '5.0.1' into develop
5.0.1
2020-01-24 05:39:29 +01:00
1899 changed files with 32083 additions and 25562 deletions

View File

@@ -15,3 +15,5 @@ el_GR
sv_SE
zh-hans_CN
zh-hant_CN
fi_FI
vi_VN

View File

@@ -15,9 +15,16 @@ SITE_OWNER=mail@example.com
# If you use Docker or similar, you can set this variable from a file by using APP_KEY_FILE
APP_KEY=SomeRandomStringOf32CharsExactly
#
# Firefly III will launch using this language (for new users and unauthenticated visitors)
# For a list of available languages: https://github.com/firefly-iii/firefly-iii/tree/master/resources/lang
#
# If text is still in English, remember that not everything may have been translated.
DEFAULT_LANGUAGE=en_US
# 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
@@ -29,14 +36,16 @@ APP_URL=http://localhost
TRUSTED_PROXIES=
# The log channel defines where your log entries go to.
# - Docker + versions <= 4.8.1.8 and before: use "stdout"
# - Docker + versions > 4.8.1.8: use "docker_out"
# - For everything else, use 'daily'
# Several other options exist. You can use 'single' for one big fat error log (not recommended).
# Also available are 'syslog', 'errorlog' and 'stdout' which will log to the system itself.
# A rotating log option is 'daily', creates 5 files that (surprise) rotate.
# Default setting 'stack' will log to 'daily' and to 'stdout' at the same time.
# - Docker + versions <= 4.8.1.8 and before: use "stdout"
# - Docker + versions > 4.8.1.8 : use "docker_out"
# - Docker + versions >= 5.1.1 : use "stack"
# - For everything else (als not Docker) : use 'stack'
LOG_CHANNEL=stack
# Log level. You can set this from least severe to most severe:
@@ -48,8 +57,9 @@ 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_HOST=fireflyiiidb
DB_PORT=5432
DB_DATABASE=firefly
DB_USERNAME=firefly
@@ -73,7 +83,8 @@ SESSION_DRIVER=file
REDIS_HOST=127.0.0.1
REDIS_PASSWORD=null
REDIS_PORT=6379
REDIS_DB="0" # always use quotes
# always use quotes and make sure redis db "0" and "1" exists. Otherwise change accordingly.
REDIS_DB="0"
REDIS_CACHE_DB="1"
# Cookie settings. Should not be necessary to change these.
@@ -206,6 +217,11 @@ DISABLE_CSP_HEADER=false
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:
SEND_TELEMETRY=false
# You can fine tune the start-up of a Docker container by editing these environment variables.
# Use this at your own risk. Disabling certain checks and features may result in lost of inconsistent data.
# However if you know what you're doing you can significantly speed up container start times.

View File

@@ -19,7 +19,7 @@ I am running Firefly III version x.x.x, and my problem is:
<!-- Earn bonus points by checking the boxes -->
- [ ] Nobody reported this bug before
- [ ] I have added a stack trace from my log files.
- [ ] 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 :wink:)-->

View File

@@ -18,6 +18,6 @@ I am running Firefly III version x.x.x.
- [ ] 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 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:)-->

View File

@@ -34,7 +34,7 @@ This Code of Conduct applies both within project spaces and in public spaces whe
## Enforcement
Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting the project team at thegrumpydictator@gmail.com. The project team will review and investigate all complaints, and will respond in a way that it deems appropriate to the circumstances. The project team is obligated to maintain confidentiality with regard to the reporter of an incident. Further details of specific enforcement policies may be posted separately.
Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting the project team at james@firefly-iii.org. The project team will review and investigate all complaints, and will respond in a way that it deems appropriate to the circumstances. The project team is obligated to maintain confidentiality with regard to the reporter of an incident. Further details of specific enforcement policies may be posted separately.
Project maintainers who do not follow or enforce the Code of Conduct in good faith may face temporary or permanent repercussions as determined by other members of the project's leadership.

View File

@@ -4,7 +4,7 @@
## Feature requests
I am always interested in expanding Firefly III's many features. Just open a ticket or [drop me a line](mailto:thegrumpydictator@gmail.com).
I am always interested in expanding Firefly III's many features. Just open a ticket or [drop me a line](mailto:james@firefly-iii.org).
## Pull requests

2
.github/security.md vendored
View File

@@ -6,7 +6,7 @@ Only the latest version of Firefly III is supported. If you're not running the l
## Reporting a Vulnerability
If you find something that compromises the security of Firefly III, you should [send me a message](mailto:thegrumpydictator@gmail.com) as soon as possible. These issues will be fixed immediately. You can also open an issue, but if you feel the issue is sensitive, please drop me a message instead.
If you find something that compromises the security of Firefly III, you should [send me a message](mailto:james@firefly-iii.org) as soon as possible. These issues will be fixed immediately. You can also open an issue, but if you feel the issue is sensitive, please drop me a message instead.
You can use my [GPG key](https://keybase.io/jc5) for extra security. My [GitHub commits](https://github.com/firefly-iii/firefly-iii/commits/master) are almost always signed with this key.

View File

@@ -31,6 +31,7 @@ use FireflyIII\Repositories\Account\AccountRepositoryInterface;
use FireflyIII\Support\Http\Api\AccountFilter;
use FireflyIII\Support\Http\Api\TransactionFilter;
use FireflyIII\Transformers\AccountTransformer;
use FireflyIII\Transformers\AttachmentTransformer;
use FireflyIII\Transformers\PiggyBankTransformer;
use FireflyIII\Transformers\TransactionGroupTransformer;
use FireflyIII\User;
@@ -73,6 +74,35 @@ class AccountController extends Controller
);
}
/**
* @param Account $account
*
* @return JsonResponse
* @codeCoverageIgnore
*/
public function attachments(Account $account): JsonResponse
{
$manager = $this->getManager();
$pageSize = (int) app('preferences')->getForUser(auth()->user(), 'listPageSize', 50)->data;
$collection = $this->repository->getAttachments($account);
$count = $collection->count();
$attachments = $collection->slice(($this->parameters->get('page') - 1) * $pageSize, $pageSize);
// make paginator:
$paginator = new LengthAwarePaginator($attachments, $count, $pageSize, $this->parameters->get('page'));
$paginator->setPath(route('api.v1.accounts.attachments', [$account->id]) . $this->buildParams());
/** @var AttachmentTransformer $transformer */
$transformer = app(AttachmentTransformer::class);
$transformer->setParameters($this->parameters);
$resource = new FractalCollection($attachments, $transformer, 'attachments');
$resource->setPaginator(new IlluminatePaginatorAdapter($paginator));
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', 'application/vnd.api+json');
}
/**
* Remove the specified resource from storage.
*
@@ -104,7 +134,7 @@ class AccountController extends Controller
// types to get, page size:
$types = $this->mapAccountTypes($this->parameters->get('type'));
$pageSize = (int)app('preferences')->getForUser(auth()->user(), 'listPageSize', 50)->data;
$pageSize = (int) app('preferences')->getForUser(auth()->user(), 'listPageSize', 50)->data;
// get list of accounts. Count it and split it.
$collection = $this->repository->getAccountsByType($types);
@@ -142,7 +172,7 @@ class AccountController extends Controller
$manager = $this->getManager();
// types to get, page size:
$pageSize = (int)app('preferences')->getForUser(auth()->user(), 'listPageSize', 50)->data;
$pageSize = (int) app('preferences')->getForUser(auth()->user(), 'listPageSize', 50)->data;
// get list of budgets. Count it and split it.
$collection = $this->repository->getPiggyBanks($account);
@@ -218,7 +248,7 @@ class AccountController extends Controller
*/
public function transactions(Request $request, Account $account): JsonResponse
{
$pageSize = (int)app('preferences')->getForUser(auth()->user(), 'listPageSize', 50)->data;
$pageSize = (int) app('preferences')->getForUser(auth()->user(), 'listPageSize', 50)->data;
$type = $request->get('type') ?? 'default';
$this->parameters->set('type', $type);
@@ -227,10 +257,8 @@ class AccountController extends Controller
if (null !== $limit && $limit > 0) {
$pageSize = $limit;
}
$types = $this->mapTransactionTypes($this->parameters->get('type'));
$manager = $this->getManager();
/** @var User $admin */
$admin = auth()->user();
@@ -240,7 +268,6 @@ class AccountController extends Controller
$collector->setUser($admin)->setAccounts(new Collection([$account]))
->withAPIInformation()->setLimit($pageSize)->setPage($this->parameters->get('page'))->setTypes($types);
// set range if necessary:
if (null !== $this->parameters->get('start') && null !== $this->parameters->get('end')) {
$collector->setRange($this->parameters->get('start'), $this->parameters->get('end'));
}

View File

@@ -92,8 +92,8 @@ class AttachmentController extends Controller
* @param Attachment $attachment
*
* @codeCoverageIgnore
* @return LaravelResponse
* @throws FireflyException
* @return LaravelResponse
*/
public function download(Attachment $attachment): LaravelResponse
{
@@ -108,7 +108,7 @@ class AttachmentController extends Controller
if ('' === $content) {
throw new FireflyException('200002: File is empty (zero bytes).');
}
$quoted = sprintf('"%s"', addcslashes(basename($attachment->filename), '"\\'));
$quoted = sprintf('"%s"', addcslashes(basename($attachment->filename), '"\\'));
/** @var LaravelResponse $response */
$response = response($content);
@@ -139,7 +139,7 @@ class AttachmentController extends Controller
$manager = $this->getManager();
// types to get, page size:
$pageSize = (int)app('preferences')->getForUser(auth()->user(), 'listPageSize', 50)->data;
$pageSize = (int) app('preferences')->getForUser(auth()->user(), 'listPageSize', 50)->data;
// get list of accounts. Count it and split it.
$collection = $this->repository->get();
@@ -184,8 +184,8 @@ class AttachmentController extends Controller
*
* @param AttachmentStoreRequest $request
*
* @return JsonResponse
* @throws FireflyException
* @return JsonResponse
*/
public function store(AttachmentStoreRequest $request): JsonResponse
{

View File

@@ -92,7 +92,7 @@ class AvailableBudgetController extends Controller
$manager = $this->getManager();
// types to get, page size:
$pageSize = (int)app('preferences')->getForUser(auth()->user(), 'listPageSize', 50)->data;
$pageSize = (int) app('preferences')->getForUser(auth()->user(), 'listPageSize', 50)->data;
$start = $this->parameters->get('start');
$end = $this->parameters->get('end');

View File

@@ -85,7 +85,7 @@ class BillController extends Controller
public function attachments(Bill $bill): JsonResponse
{
$manager = $this->getManager();
$pageSize = (int)app('preferences')->getForUser(auth()->user(), 'listPageSize', 50)->data;
$pageSize = (int) app('preferences')->getForUser(auth()->user(), 'listPageSize', 50)->data;
$collection = $this->repository->getAttachments($bill);
$count = $collection->count();
@@ -130,7 +130,7 @@ class BillController extends Controller
{
$bills = $this->repository->getBills();
$manager = $this->getManager();
$pageSize = (int)app('preferences')->getForUser(auth()->user(), 'listPageSize', 50)->data;
$pageSize = (int) app('preferences')->getForUser(auth()->user(), 'listPageSize', 50)->data;
$count = $bills->count();
$bills = $bills->slice(($this->parameters->get('page') - 1) * $pageSize, $pageSize);
$paginator = new LengthAwarePaginator($bills, $count, $pageSize, $this->parameters->get('page'));
@@ -158,7 +158,7 @@ class BillController extends Controller
$manager = $this->getManager();
// types to get, page size:
$pageSize = (int)app('preferences')->getForUser(auth()->user(), 'listPageSize', 50)->data;
$pageSize = (int) app('preferences')->getForUser(auth()->user(), 'listPageSize', 50)->data;
// get list of budgets. Count it and split it.
$collection = $this->repository->getRulesForBill($bill);
@@ -206,8 +206,8 @@ class BillController extends Controller
*
* @param BillRequest $request
*
* @return JsonResponse
* @throws FireflyException
* @return JsonResponse
*/
public function store(BillRequest $request): JsonResponse
{
@@ -235,7 +235,7 @@ class BillController extends Controller
*/
public function transactions(Request $request, Bill $bill): JsonResponse
{
$pageSize = (int)app('preferences')->getForUser(auth()->user(), 'listPageSize', 50)->data;
$pageSize = (int) app('preferences')->getForUser(auth()->user(), 'listPageSize', 50)->data;
$type = $request->get('type') ?? 'default';
$this->parameters->set('type', $type);

View File

@@ -25,13 +25,15 @@ namespace FireflyIII\Api\V1\Controllers;
use Exception;
use FireflyIII\Api\V1\Requests\BudgetLimitRequest;
use FireflyIII\Api\V1\Requests\BudgetRequest;
use FireflyIII\Api\V1\Requests\BudgetStoreRequest;
use FireflyIII\Api\V1\Requests\BudgetUpdateRequest;
use FireflyIII\Exceptions\FireflyException;
use FireflyIII\Helpers\Collector\GroupCollectorInterface;
use FireflyIII\Models\Budget;
use FireflyIII\Repositories\Budget\BudgetLimitRepositoryInterface;
use FireflyIII\Repositories\Budget\BudgetRepositoryInterface;
use FireflyIII\Support\Http\Api\TransactionFilter;
use FireflyIII\Transformers\AttachmentTransformer;
use FireflyIII\Transformers\BudgetLimitTransformer;
use FireflyIII\Transformers\BudgetTransformer;
use FireflyIII\Transformers\TransactionGroupTransformer;
@@ -89,7 +91,7 @@ class BudgetController extends Controller
public function budgetLimits(Budget $budget): JsonResponse
{
$manager = $this->getManager();
$pageSize = (int)app('preferences')->getForUser(auth()->user(), 'listPageSize', 50)->data;
$pageSize = (int) app('preferences')->getForUser(auth()->user(), 'listPageSize', 50)->data;
$this->parameters->set('budget_id', $budget->id);
$collection = $this->blRepository->getBudgetLimits($budget, $this->parameters->get('start'), $this->parameters->get('end'));
$count = $collection->count();
@@ -108,6 +110,35 @@ class BudgetController extends Controller
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', 'application/vnd.api+json');
}
/**
* @param Budget $budget
*
* @return JsonResponse
* @codeCoverageIgnore
*/
public function attachments(Budget $budget): JsonResponse
{
$manager = $this->getManager();
$pageSize = (int) app('preferences')->getForUser(auth()->user(), 'listPageSize', 50)->data;
$collection = $this->repository->getAttachments($budget);
$count = $collection->count();
$attachments = $collection->slice(($this->parameters->get('page') - 1) * $pageSize, $pageSize);
// make paginator:
$paginator = new LengthAwarePaginator($attachments, $count, $pageSize, $this->parameters->get('page'));
$paginator->setPath(route('api.v1.budgets.attachments', [$budget->id]) . $this->buildParams());
/** @var AttachmentTransformer $transformer */
$transformer = app(AttachmentTransformer::class);
$transformer->setParameters($this->parameters);
$resource = new FractalCollection($attachments, $transformer, 'attachments');
$resource->setPaginator(new IlluminatePaginatorAdapter($paginator));
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', 'application/vnd.api+json');
}
/**
* Remove the specified resource from storage.
*
@@ -134,7 +165,7 @@ class BudgetController extends Controller
$manager = $this->getManager();
// types to get, page size:
$pageSize = (int)app('preferences')->getForUser(auth()->user(), 'listPageSize', 50)->data;
$pageSize = (int) app('preferences')->getForUser(auth()->user(), 'listPageSize', 50)->data;
// get list of budgets. Count it and split it.
$collection = $this->repository->getBudgets();
@@ -179,13 +210,13 @@ class BudgetController extends Controller
/**
* Store a budget.
*
* @param BudgetRequest $request
* @param BudgetStoreRequest $request
*
* @return JsonResponse
* @throws FireflyException
*
* @return JsonResponse
*/
public function store(BudgetRequest $request): JsonResponse
public function store(BudgetStoreRequest $request): JsonResponse
{
$budget = $this->repository->store($request->getAll());
$manager = $this->getManager();
@@ -205,8 +236,8 @@ class BudgetController extends Controller
* @param BudgetLimitRequest $request
* @param Budget $budget
*
* @return JsonResponse
* @throws Exception
* @return JsonResponse
*/
public function storeBudgetLimit(BudgetLimitRequest $request, Budget $budget): JsonResponse
{
@@ -236,7 +267,7 @@ class BudgetController extends Controller
*/
public function transactions(Request $request, Budget $budget): JsonResponse
{
$pageSize = (int)app('preferences')->getForUser(auth()->user(), 'listPageSize', 50)->data;
$pageSize = (int) app('preferences')->getForUser(auth()->user(), 'listPageSize', 50)->data;
// user can overrule page size with limit parameter.
$limit = $this->parameters->get('limit');
@@ -291,12 +322,12 @@ class BudgetController extends Controller
/**
* Update a budget.
*
* @param BudgetRequest $request
* @param Budget $budget
* @param BudgetUpdateRequest $request
* @param Budget $budget
*
* @return JsonResponse
*/
public function update(BudgetRequest $request, Budget $budget): JsonResponse
public function update(BudgetUpdateRequest $request, Budget $budget): JsonResponse
{
$data = $request->getAll();
$budget = $this->repository->update($budget, $data);

View File

@@ -102,9 +102,9 @@ class BudgetLimitController extends Controller
public function index(Request $request): JsonResponse
{
$manager = $this->getManager();
$budgetId = (int)($request->get('budget_id') ?? 0);
$budgetId = (int) ($request->get('budget_id') ?? 0);
$budget = $this->repository->findNull($budgetId);
$pageSize = (int)app('preferences')->getForUser(auth()->user(), 'listPageSize', 50)->data;
$pageSize = (int) app('preferences')->getForUser(auth()->user(), 'listPageSize', 50)->data;
$this->parameters->set('budget_id', $budgetId);
$collection = new Collection;
@@ -156,16 +156,16 @@ class BudgetLimitController extends Controller
*
* @param BudgetLimitRequest $request
*
* @return JsonResponse
* @throws FireflyException
*
* @return JsonResponse
*/
public function store(BudgetLimitRequest $request): JsonResponse
{
$data = $request->getAll();
$budget = $this->repository->findNull($data['budget_id']);
if (null === $budget) {
throw new FireflyException('200004: Budget does not exist.');
throw new FireflyException('200004: Budget does not exist.'); // @codeCoverageIgnore
}
$data['budget'] = $budget;
$budgetLimit = $this->blRepository->storeBudgetLimit($data);
@@ -191,7 +191,7 @@ class BudgetLimitController extends Controller
*/
public function transactions(Request $request, BudgetLimit $budgetLimit): JsonResponse
{
$pageSize = (int)app('preferences')->getForUser(auth()->user(), 'listPageSize', 50)->data;
$pageSize = (int) app('preferences')->getForUser(auth()->user(), 'listPageSize', 50)->data;
$type = $request->get('type') ?? 'default';
$this->parameters->set('type', $type);

View File

@@ -29,6 +29,7 @@ use FireflyIII\Helpers\Collector\GroupCollectorInterface;
use FireflyIII\Models\Category;
use FireflyIII\Repositories\Category\CategoryRepositoryInterface;
use FireflyIII\Support\Http\Api\TransactionFilter;
use FireflyIII\Transformers\AttachmentTransformer;
use FireflyIII\Transformers\CategoryTransformer;
use FireflyIII\Transformers\TransactionGroupTransformer;
use FireflyIII\User;
@@ -71,6 +72,35 @@ class CategoryController extends Controller
);
}
/**
* @param Category $category
*
* @return JsonResponse
* @codeCoverageIgnore
*/
public function attachments(Category $category): JsonResponse
{
$manager = $this->getManager();
$pageSize = (int) app('preferences')->getForUser(auth()->user(), 'listPageSize', 50)->data;
$collection = $this->repository->getAttachments($category);
$count = $collection->count();
$attachments = $collection->slice(($this->parameters->get('page') - 1) * $pageSize, $pageSize);
// make paginator:
$paginator = new LengthAwarePaginator($attachments, $count, $pageSize, $this->parameters->get('page'));
$paginator->setPath(route('api.v1.categories.attachments', [$category->id]) . $this->buildParams());
/** @var AttachmentTransformer $transformer */
$transformer = app(AttachmentTransformer::class);
$transformer->setParameters($this->parameters);
$resource = new FractalCollection($attachments, $transformer, 'attachments');
$resource->setPaginator(new IlluminatePaginatorAdapter($paginator));
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', 'application/vnd.api+json');
}
/**
* Remove the specified resource from storage.
*
@@ -97,7 +127,7 @@ class CategoryController extends Controller
$manager = $this->getManager();
// types to get, page size:
$pageSize = (int)app('preferences')->getForUser(auth()->user(), 'listPageSize', 50)->data;
$pageSize = (int) app('preferences')->getForUser(auth()->user(), 'listPageSize', 50)->data;
// get list of budgets. Count it and split it.
$collection = $this->repository->getCategories();
@@ -146,13 +176,13 @@ class CategoryController extends Controller
*
* @param CategoryRequest $request
*
* @return JsonResponse
* @throws FireflyException
* @return JsonResponse
*/
public function store(CategoryRequest $request): JsonResponse
{
$category = $this->repository->store($request->getAll());
$manager = $this->getManager();
$manager = $this->getManager();
/** @var CategoryTransformer $transformer */
$transformer = app(CategoryTransformer::class);
@@ -175,7 +205,7 @@ class CategoryController extends Controller
*/
public function transactions(Request $request, Category $category): JsonResponse
{
$pageSize = (int)app('preferences')->getForUser(auth()->user(), 'listPageSize', 50)->data;
$pageSize = (int) app('preferences')->getForUser(auth()->user(), 'listPageSize', 50)->data;
$type = $request->get('type') ?? 'default';
$this->parameters->set('type', $type);

View File

@@ -99,10 +99,10 @@ class AccountController extends Controller
// loop the end balances. This is an array for each account ($expenses)
foreach ($endBalances as $accountId => $expenses) {
$accountId = (int)$accountId;
$accountId = (int) $accountId;
// loop each expense entry (each entry can be a different currency).
foreach ($expenses as $currencyId => $endAmount) {
$currencyId = (int)$currencyId;
$currencyId = (int) $currencyId;
// see if there is an accompanying start amount.
// grab the difference and find the currency.
@@ -114,7 +114,7 @@ class AccountController extends Controller
$tempData[] = [
'name' => $accountNames[$accountId],
'difference' => $diff,
'diff_float' => (float)$diff,
'diff_float' => (float) $diff,
'currency_id' => $currencyId,
];
}
@@ -247,10 +247,10 @@ class AccountController extends Controller
// loop the end balances. This is an array for each account ($expenses)
foreach ($endBalances as $accountId => $expenses) {
$accountId = (int)$accountId;
$accountId = (int) $accountId;
// loop each expense entry (each entry can be a different currency).
foreach ($expenses as $currencyId => $endAmount) {
$currencyId = (int)$currencyId;
$currencyId = (int) $currencyId;
// see if there is an accompanying start amount.
// grab the difference and find the currency.
@@ -263,7 +263,7 @@ class AccountController extends Controller
'name' => $accountNames[$accountId],
'difference' => bcmul($diff, '-1'),
// For some reason this line is never covered in code coverage:
'diff_float' => ((float)$diff) * -1, // @codeCoverageIgnore
'diff_float' => ((float) $diff) * -1, // @codeCoverageIgnore
'currency_id' => $currencyId,
];
}

View File

@@ -83,9 +83,9 @@ class AvailableBudgetController extends Controller
$spent = $spentInfo['amount'];
}
}
$left = bcadd($availableBudget->amount, (string)$spent);
$left = bcadd($availableBudget->amount, (string) $spent);
// left less than zero? Set to zero.
if (bccomp($left, '0') === -1) {
if (-1 === bccomp($left, '0')) {
$left = '0';
}

View File

@@ -95,7 +95,7 @@ class CategoryController extends Controller
$categories = [];
foreach ([$spentWith, $earnedWith] as $set) {
foreach ([$spentWith, $earnedWith, $spentWithout, $earnedWithout] as $set) {
foreach ($set as $currency) {
foreach ($currency['categories'] as $category) {
$categories[] = $category['name'];
@@ -104,7 +104,7 @@ class CategoryController extends Controller
// 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']]),
'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'],
@@ -117,7 +117,7 @@ class CategoryController extends Controller
];
$tempData[$outKey] = $tempData[$outKey] ?? [
'currency_id' => $currency['currency_id'],
'label' => (string)trans('firefly.box_spent_in_currency', ['currency' => $currency['currency_name']]),
'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'],
@@ -141,48 +141,48 @@ class CategoryController extends Controller
}
}
foreach ([$spentWithout, $earnedWithout] 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']);
}
}
}
// 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) {

View File

@@ -51,7 +51,6 @@ class ConfigurationController extends Controller
parent::__construct();
$this->middleware(
function ($request, $next) {
/** @noinspection UnusedConstructorDependenciesInspection */
$this->repository = app(UserRepositoryInterface::class);
/** @var User $admin */
$admin = auth()->user();
@@ -109,13 +108,12 @@ class ConfigurationController extends Controller
$lastCheck = app('fireflyconfig')->get('last_update_check');
/** @var Configuration $singleUser */
$singleUser = app('fireflyconfig')->get('single_user_mode');
$data = [
return [
'is_demo_site' => null === $isDemoSite ? null : $isDemoSite->data,
'permission_update_check' => null === $updateCheck ? null : (int)$updateCheck->data,
'last_update_check' => null === $lastCheck ? null : (int)$lastCheck->data,
'permission_update_check' => null === $updateCheck ? null : (int) $updateCheck->data,
'last_update_check' => null === $lastCheck ? null : (int) $lastCheck->data,
'single_user_mode' => null === $singleUser ? null : $singleUser->data,
];
return $data;
}
}

View File

@@ -104,7 +104,7 @@ class Controller extends BaseController
private function getParameters(): ParameterBag
{
$bag = new ParameterBag;
$page = (int)request()->get('page');
$page = (int) request()->get('page');
if (0 === $page) {
$page = 1;
}
@@ -131,7 +131,7 @@ class Controller extends BaseController
foreach ($integers as $integer) {
$value = request()->query->get($integer);
if (null !== $value) {
$bag->set($integer, (int)$value);
$bag->set($integer, (int) $value);
}
}

View File

@@ -116,7 +116,7 @@ class CurrencyController extends Controller
// types to get, page size:
$types = $this->mapAccountTypes($this->parameters->get('type'));
$pageSize = (int)app('preferences')->getForUser(auth()->user(), 'listPageSize', 50)->data;
$pageSize = (int) app('preferences')->getForUser(auth()->user(), 'listPageSize', 50)->data;
// get list of accounts. Count it and split it.
/** @var AccountRepositoryInterface $accountRepository */
@@ -126,7 +126,7 @@ class CurrencyController extends Controller
// filter list on currency preference:
$collection = $unfiltered->filter(
static function (Account $account) use ($currency, $accountRepository) {
$currencyId = (int)$accountRepository->getMetaValue($account, 'currency_id');
$currencyId = (int) $accountRepository->getMetaValue($account, 'currency_id');
return $currencyId === $currency->id;
}
@@ -165,7 +165,7 @@ class CurrencyController extends Controller
$manager = $this->getManager();
// types to get, page size:
$pageSize = (int)app('preferences')->getForUser(auth()->user(), 'listPageSize', 50)->data;
$pageSize = (int) app('preferences')->getForUser(auth()->user(), 'listPageSize', 50)->data;
// get list of available budgets. Count it and split it.
@@ -209,7 +209,7 @@ class CurrencyController extends Controller
/** @var BillRepositoryInterface $repository */
$repository = app(BillRepositoryInterface::class);
$pageSize = (int)app('preferences')->getForUser(auth()->user(), 'listPageSize', 50)->data;
$pageSize = (int) app('preferences')->getForUser(auth()->user(), 'listPageSize', 50)->data;
$unfiltered = $repository->getBills();
// filter and paginate list:
@@ -249,7 +249,7 @@ class CurrencyController extends Controller
$blRepository = app(BudgetLimitRepositoryInterface::class);
$manager = $this->getManager();
$pageSize = (int)app('preferences')->getForUser(auth()->user(), 'listPageSize', 50)->data;
$pageSize = (int) app('preferences')->getForUser(auth()->user(), 'listPageSize', 50)->data;
$collection = $blRepository->getAllBudgetLimitsByCurrency($currency, $this->parameters->get('start'), $this->parameters->get('end'));
$count = $collection->count();
$budgetLimits = $collection->slice(($this->parameters->get('page') - 1) * $pageSize, $pageSize);
@@ -278,7 +278,7 @@ class CurrencyController extends Controller
{
// create some objects:
$manager = $this->getManager();
$pageSize = (int)app('preferences')->getForUser(auth()->user(), 'listPageSize', 50)->data;
$pageSize = (int) app('preferences')->getForUser(auth()->user(), 'listPageSize', 50)->data;
$collection = $this->repository->getExchangeRates($currency);
@@ -302,9 +302,9 @@ class CurrencyController extends Controller
*
* @param TransactionCurrency $currency
*
* @return JsonResponse
* @throws FireflyException
* @codeCoverageIgnore
* @return JsonResponse
*/
public function delete(TransactionCurrency $currency): JsonResponse
{
@@ -318,6 +318,10 @@ class CurrencyController extends Controller
if ($this->repository->currencyInUse($currency)) {
throw new FireflyException('200006: Currency in use.'); // @codeCoverageIgnore
}
if ($this->repository->isFallbackCurrency($currency)) {
throw new FireflyException('200026: Currency is fallback.'); // @codeCoverageIgnore
}
$this->repository->destroy($currency);
return response()->json([], 204);
@@ -387,7 +391,7 @@ class CurrencyController extends Controller
*/
public function index(): JsonResponse
{
$pageSize = (int)app('preferences')->getForUser(auth()->user(), 'listPageSize', 50)->data;
$pageSize = (int) app('preferences')->getForUser(auth()->user(), 'listPageSize', 50)->data;
$collection = $this->repository->getAll();
$count = $collection->count();
// slice them:
@@ -451,7 +455,7 @@ class CurrencyController extends Controller
{
$manager = $this->getManager();
// types to get, page size:
$pageSize = (int)app('preferences')->getForUser(auth()->user(), 'listPageSize', 50)->data;
$pageSize = (int) app('preferences')->getForUser(auth()->user(), 'listPageSize', 50)->data;
// get list of budgets. Count it and split it.
/** @var RecurringRepositoryInterface $repository */
@@ -502,7 +506,7 @@ class CurrencyController extends Controller
public function rules(TransactionCurrency $currency): JsonResponse
{
$manager = $this->getManager();
$pageSize = (int)app('preferences')->getForUser(auth()->user(), 'listPageSize', 50)->data;
$pageSize = (int) app('preferences')->getForUser(auth()->user(), 'listPageSize', 50)->data;
// get list of budgets. Count it and split it.
/** @var RuleRepositoryInterface $repository */
@@ -563,13 +567,33 @@ class CurrencyController extends Controller
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', 'application/vnd.api+json');
}
/**
* Show a currency.
*
* @return JsonResponse
* @codeCoverageIgnore
*/
public function showDefault(): JsonResponse
{
$manager = $this->getManager();
$currency = app('amount')->getDefaultCurrencyByUser(auth()->user());
/** @var CurrencyTransformer $transformer */
$transformer = app(CurrencyTransformer::class);
$transformer->setParameters($this->parameters);
$resource = new Item($currency, $transformer, 'currencies');
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', 'application/vnd.api+json');
}
/**
* Store new currency.
*
* @param CurrencyRequest $request
*
* @return JsonResponse
* @throws FireflyException
* @return JsonResponse
*/
public function store(CurrencyRequest $request): JsonResponse
{
@@ -603,7 +627,7 @@ class CurrencyController extends Controller
*/
public function transactions(Request $request, TransactionCurrency $currency): JsonResponse
{
$pageSize = (int)app('preferences')->getForUser(auth()->user(), 'listPageSize', 50)->data;
$pageSize = (int) app('preferences')->getForUser(auth()->user(), 'listPageSize', 50)->data;
$type = $request->get('type') ?? 'default';
$this->parameters->set('type', $type);

View File

@@ -69,8 +69,8 @@ class CurrencyExchangeRateController extends Controller
*
* @param Request $request
*
* @return JsonResponse
* @throws FireflyException
* @return JsonResponse
*/
public function index(Request $request): JsonResponse
{

View File

@@ -40,6 +40,9 @@ use League\Fractal\Resource\Item;
/**
* Class ImportController
*
* @deprecated
* @codeCoverageIgnore
*/
class ImportController extends Controller
{
@@ -75,7 +78,7 @@ class ImportController extends Controller
{
// create some objects:
$manager = $this->getManager();
$pageSize = (int)app('preferences')->getForUser(auth()->user(), 'listPageSize', 50)->data;
$pageSize = (int) app('preferences')->getForUser(auth()->user(), 'listPageSize', 50)->data;
// get list of accounts. Count it and split it.
$collection = $this->repository->get();
@@ -125,7 +128,7 @@ class ImportController extends Controller
*/
public function transactions(Request $request, ImportJob $importJob): JsonResponse
{
$pageSize = (int)app('preferences')->getForUser(auth()->user(), 'listPageSize', 50)->data;
$pageSize = (int) app('preferences')->getForUser(auth()->user(), 'listPageSize', 50)->data;
$type = $request->get('type') ?? 'default';
$this->parameters->set('type', $type);

View File

@@ -79,9 +79,9 @@ class LinkTypeController extends Controller
*
* @param LinkType $linkType
*
* @return JsonResponse
* @throws FireflyException
* @codeCoverageIgnore
* @return JsonResponse
*/
public function delete(LinkType $linkType): JsonResponse
{
@@ -103,7 +103,7 @@ class LinkTypeController extends Controller
{
// create some objects:
$manager = $this->getManager();
$pageSize = (int)app('preferences')->getForUser(auth()->user(), 'listPageSize', 50)->data;
$pageSize = (int) app('preferences')->getForUser(auth()->user(), 'listPageSize', 50)->data;
// get list of accounts. Count it and split it.
$collection = $this->repository->get();
@@ -151,8 +151,8 @@ class LinkTypeController extends Controller
*
* @param LinkTypeRequest $request
*
* @return JsonResponse
* @throws FireflyException
* @return JsonResponse
*/
public function store(LinkTypeRequest $request): JsonResponse
{
@@ -187,7 +187,7 @@ class LinkTypeController extends Controller
*/
public function transactions(Request $request, LinkType $linkType): JsonResponse
{
$pageSize = (int)app('preferences')->getForUser(auth()->user(), 'listPageSize', 50)->data;
$pageSize = (int) app('preferences')->getForUser(auth()->user(), 'listPageSize', 50)->data;
$type = $request->get('type') ?? 'default';
$this->parameters->set('type', $type);
@@ -241,8 +241,8 @@ class LinkTypeController extends Controller
* @param LinkTypeRequest $request
* @param LinkType $linkType
*
* @return JsonResponse
* @throws FireflyException
* @return JsonResponse
*/
public function update(LinkTypeRequest $request, LinkType $linkType): JsonResponse
{

View File

@@ -27,6 +27,7 @@ use FireflyIII\Api\V1\Requests\PiggyBankRequest;
use FireflyIII\Exceptions\FireflyException;
use FireflyIII\Models\PiggyBank;
use FireflyIII\Repositories\PiggyBank\PiggyBankRepositoryInterface;
use FireflyIII\Transformers\AttachmentTransformer;
use FireflyIII\Transformers\PiggyBankEventTransformer;
use FireflyIII\Transformers\PiggyBankTransformer;
use FireflyIII\User;
@@ -83,6 +84,36 @@ class PiggyBankController extends Controller
return response()->json([], 204);
}
/**
* @param PiggyBank $piggyBank
*
* @return JsonResponse
* @codeCoverageIgnore
*/
public function attachments(PiggyBank $piggyBank): JsonResponse
{
$manager = $this->getManager();
$pageSize = (int) app('preferences')->getForUser(auth()->user(), 'listPageSize', 50)->data;
$collection = $this->repository->getAttachments($piggyBank);
$count = $collection->count();
$attachments = $collection->slice(($this->parameters->get('page') - 1) * $pageSize, $pageSize);
// make paginator:
$paginator = new LengthAwarePaginator($attachments, $count, $pageSize, $this->parameters->get('page'));
$paginator->setPath(route('api.v1.piggy_banks.attachments', [$piggyBank->id]) . $this->buildParams());
/** @var AttachmentTransformer $transformer */
$transformer = app(AttachmentTransformer::class);
$transformer->setParameters($this->parameters);
$resource = new FractalCollection($attachments, $transformer, 'attachments');
$resource->setPaginator(new IlluminatePaginatorAdapter($paginator));
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', 'application/vnd.api+json');
}
/**
* List all of them.
*
@@ -93,7 +124,7 @@ class PiggyBankController extends Controller
{
$manager = $this->getManager();
// types to get, page size:
$pageSize = (int)app('preferences')->getForUser(auth()->user(), 'listPageSize', 50)->data;
$pageSize = (int) app('preferences')->getForUser(auth()->user(), 'listPageSize', 50)->data;
// get list of budgets. Count it and split it.
$collection = $this->repository->getPiggyBanks();
@@ -126,7 +157,7 @@ class PiggyBankController extends Controller
public function piggyBankEvents(PiggyBank $piggyBank): JsonResponse
{
// types to get, page size:
$pageSize = (int)app('preferences')->getForUser(auth()->user(), 'listPageSize', 50)->data;
$pageSize = (int) app('preferences')->getForUser(auth()->user(), 'listPageSize', 50)->data;
$manager = $this->getManager();
$collection = $this->repository->getEvents($piggyBank);
@@ -175,13 +206,13 @@ class PiggyBankController extends Controller
*
* @param PiggyBankRequest $request
*
* @return JsonResponse
* @throws FireflyException
* @return JsonResponse
*/
public function store(PiggyBankRequest $request): JsonResponse
{
$piggyBank = $this->repository->store($request->getAll());
$manager = $this->getManager();
$manager = $this->getManager();
/** @var PiggyBankTransformer $transformer */
$transformer = app(PiggyBankTransformer::class);

View File

@@ -147,10 +147,10 @@ class PreferenceController extends Controller
$newValue = explode(',', $data['data']);
break;
case 'listPageSize':
$newValue = (int)$data['data'];
$newValue = (int) $data['data'];
break;
case 'customFiscalYear':
$newValue = 1 === (int)$data['data'];
$newValue = 1 === (int) $data['data'];
break;
}
$result = app('preferences')->set($preference->name, $newValue);

View File

@@ -99,7 +99,7 @@ class RecurrenceController extends Controller
$manager = $this->getManager();
// types to get, page size:
$pageSize = (int)app('preferences')->getForUser(auth()->user(), 'listPageSize', 50)->data;
$pageSize = (int) app('preferences')->getForUser(auth()->user(), 'listPageSize', 50)->data;
// get list of budgets. Count it and split it.
$collection = $this->repository->getAll();
@@ -149,8 +149,8 @@ class RecurrenceController extends Controller
*
* @param RecurrenceStoreRequest $request
*
* @return JsonResponse
* @throws FireflyException
* @return JsonResponse
*/
public function store(RecurrenceStoreRequest $request): JsonResponse
{
@@ -178,7 +178,7 @@ class RecurrenceController extends Controller
*/
public function transactions(Request $request, Recurrence $recurrence): JsonResponse
{
$pageSize = (int)app('preferences')->getForUser(auth()->user(), 'listPageSize', 50)->data;
$pageSize = (int) app('preferences')->getForUser(auth()->user(), 'listPageSize', 50)->data;
$type = $request->get('type') ?? 'default';
$this->parameters->set('type', $type);
@@ -224,9 +224,9 @@ class RecurrenceController extends Controller
}
/**
* @return JsonResponse
* @throws FireflyException
* @codeCoverageIgnore
* @return JsonResponse
*/
public function trigger(): JsonResponse
{

View File

@@ -105,7 +105,7 @@ class RuleController extends Controller
$manager = $this->getManager();
// types to get, page size:
$pageSize = (int)app('preferences')->getForUser(auth()->user(), 'listPageSize', 50)->data;
$pageSize = (int) app('preferences')->getForUser(auth()->user(), 'listPageSize', 50)->data;
// get list of budgets. Count it and split it.
$collection = $this->ruleRepository->getAll();
@@ -214,12 +214,12 @@ class RuleController extends Controller
* @param RuleTestRequest $request
* @param Rule $rule
*
* @return JsonResponse
* @throws FireflyException
* @return JsonResponse
*/
public function testRule(RuleTestRequest $request, Rule $rule): JsonResponse
{
$pageSize = (int)app('preferences')->getForUser(auth()->user(), 'listPageSize', 50)->data;
$pageSize = (int) app('preferences')->getForUser(auth()->user(), 'listPageSize', 50)->data;
$parameters = $request->getTestParameters();
/** @var Rule $rule */
Log::debug(sprintf('Now testing rule #%d, "%s"', $rule->id, $rule->title));

View File

@@ -106,7 +106,7 @@ class RuleGroupController extends Controller
{
$manager = $this->getManager();
// types to get, page size:
$pageSize = (int)app('preferences')->getForUser(auth()->user(), 'listPageSize', 50)->data;
$pageSize = (int) app('preferences')->getForUser(auth()->user(), 'listPageSize', 50)->data;
// get list of rule groups. Count it and split it.
$collection = $this->ruleGroupRepository->get();
@@ -177,7 +177,7 @@ class RuleGroupController extends Controller
{
$manager = $this->getManager();
// types to get, page size:
$pageSize = (int)app('preferences')->getForUser(auth()->user(), 'listPageSize', 50)->data;
$pageSize = (int) app('preferences')->getForUser(auth()->user(), 'listPageSize', 50)->data;
// get list of budgets. Count it and split it.
$collection = $this->ruleGroupRepository->getRules($group);
@@ -246,13 +246,13 @@ class RuleGroupController extends Controller
* @param RuleGroupTestRequest $request
* @param RuleGroup $group
*
* @return JsonResponse
* @throws FireflyException
*
* @return JsonResponse
*/
public function testGroup(RuleGroupTestRequest $request, RuleGroup $group): JsonResponse
{
$pageSize = (int)app('preferences')->getForUser(auth()->user(), 'listPageSize', 50)->data;
$pageSize = (int) app('preferences')->getForUser(auth()->user(), 'listPageSize', 50)->data;
Log::debug('Now in testGroup()');
/** @var Collection $rules */
$rules = $this->ruleGroupRepository->getActiveRules($group);
@@ -305,8 +305,8 @@ class RuleGroupController extends Controller
* @param RuleGroupTriggerRequest $request
* @param RuleGroup $group
*
* @return JsonResponse
* @throws Exception
* @return JsonResponse
*/
public function triggerGroup(RuleGroupTriggerRequest $request, RuleGroup $group): JsonResponse
{

View File

@@ -1,4 +1,5 @@
<?php
declare(strict_types=1);
/**
* AccountController.php
* Copyright (c) 2019 james@firefly-iii.org
@@ -21,7 +22,6 @@
namespace FireflyIII\Api\V1\Controllers\Search;
use FireflyIII\Api\V1\Controllers\Controller;
use FireflyIII\Support\Http\Api\AccountFilter;
use FireflyIII\Support\Search\AccountSearch;
@@ -32,6 +32,7 @@ use Illuminate\Http\Response;
use Illuminate\Pagination\LengthAwarePaginator;
use League\Fractal\Pagination\IlluminatePaginatorAdapter;
use League\Fractal\Resource\Collection as FractalCollection;
use Log;
/**
* Class AccountController
@@ -62,6 +63,7 @@ class AccountController extends Controller
*/
public function search(Request $request)
{
Log::debug('Now in account search()');
$manager = $this->getManager();
$query = $request->get('query');
$field = $request->get('field');
@@ -70,6 +72,8 @@ class AccountController extends Controller
return response(null, 422);
}
$types = $this->mapAccountTypes($type);
Log::debug(sprintf('Going to search for "%s" in types', $query), $types);
/** @var AccountSearch $search */
$search = app(AccountSearch::class);
$search->setUser(auth()->user());
@@ -79,6 +83,8 @@ class AccountController extends Controller
$accounts = $search->search();
Log::debug(sprintf('Found %d accounts', $accounts->count()));
/** @var AccountTransformer $transformer */
$transformer = app(AccountTransformer::class);
$transformer->setParameters($this->parameters);
@@ -91,5 +97,4 @@ class AccountController extends Controller
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', 'application/vnd.api+json');
}
}
}

View File

@@ -1,4 +1,5 @@
<?php
declare(strict_types=1);
/**
* TransactionController.php
* Copyright (c) 2019 james@firefly-iii.org
@@ -21,13 +22,8 @@
namespace FireflyIII\Api\V1\Controllers\Search;
use FireflyIII\Api\V1\Controllers\Controller;
use FireflyIII\Support\Search\SearchInterface;
use FireflyIII\Support\Search\TransactionSearch;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Http\Response;
/**
* Class TransactionController
@@ -35,13 +31,13 @@ use Illuminate\Http\Response;
class TransactionController extends Controller
{
/** @var string */
const SEARCH_ALL = 'all';
public const SEARCH_ALL = 'all';
/** @var string */
const SEARCH_DESCRIPTION = 'description';
public const SEARCH_DESCRIPTION = 'description';
/** @var string */
const SEARCH_NOTES = 'notes';
public const SEARCH_NOTES = 'notes';
/** @var string */
const SEARCH_ACCOUNTS = 'accounts';
public const SEARCH_ACCOUNTS = 'accounts';
/** @var array */
private $validFields;
@@ -59,11 +55,10 @@ class TransactionController extends Controller
/**
* @param Request $request
*
* @return JsonResponse|Response
* @return void
*/
public function search(Request $request)
public function search(Request $request): void
{
die('the route is present but nobody\'s home.');
}
}
}

View File

@@ -1,4 +1,5 @@
<?php
declare(strict_types=1);
/**
* TransferController.php
* Copyright (c) 2019 james@firefly-iii.org
@@ -21,16 +22,13 @@
namespace FireflyIII\Api\V1\Controllers\Search;
use FireflyIII\Api\V1\Controllers\Controller;
use FireflyIII\Api\V1\Requests\Search\TransferRequest;
use FireflyIII\Exceptions\FireflyException;
use FireflyIII\Helpers\Collector\GroupCollectorInterface;
use FireflyIII\Support\Search\TransferSearch;
use FireflyIII\Transformers\TransactionGroupTransformer;
use FireflyIII\User;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Http\Response;
use League\Fractal\Pagination\IlluminatePaginatorAdapter;
use League\Fractal\Resource\Collection as FractalCollection;
@@ -41,10 +39,9 @@ use League\Fractal\Resource\Collection as FractalCollection;
class TransferController extends Controller
{
/**
* @param Request $request
* @param TransferRequest $request
*
* @return JsonResponse|Response
* @throws FireflyException
*/
public function search(TransferRequest $request)
{
@@ -82,7 +79,7 @@ class TransferController extends Controller
}
// collector to return results.
$pageSize = (int)app('preferences')->getForUser(auth()->user(), 'listPageSize', 50)->data;
$pageSize = (int) app('preferences')->getForUser(auth()->user(), 'listPageSize', 50)->data;
$manager = $this->getManager();
/** @var User $admin */
$admin = auth()->user();
@@ -113,4 +110,4 @@ class TransferController extends Controller
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', 'application/vnd.api+json');
}
}
}

View File

@@ -24,7 +24,6 @@ declare(strict_types=1);
namespace FireflyIII\Api\V1\Controllers;
use Carbon\Carbon;
use Exception;
use FireflyIII\Api\V1\Requests\DateRequest;
@@ -42,7 +41,6 @@ use FireflyIII\Repositories\Budget\OperationsRepositoryInterface;
use FireflyIII\Repositories\Currency\CurrencyRepositoryInterface;
use FireflyIII\User;
use Illuminate\Http\JsonResponse;
use Illuminate\Support\Collection;
/**
* Class SummaryController
@@ -98,8 +96,8 @@ class SummaryController extends Controller
/**
* @param DateRequest $request
*
* @return JsonResponse
* @throws Exception
* @return JsonResponse
*/
public function basic(DateRequest $request): JsonResponse
{
@@ -125,7 +123,6 @@ class SummaryController extends Controller
}
return response()->json($return);
}
/**
@@ -152,25 +149,6 @@ class SummaryController extends Controller
return $result;
}
/**
* This method will scroll through the results of the spentInPeriodMc() array and return the correct info.
*
* @param array $spentInfo
* @param TransactionCurrency $currency
*
* @return string
*/
private function findInSpentArray(array $spentInfo, TransactionCurrency $currency): string
{
foreach ($spentInfo as $array) {
if ($array['currency_id'] === $currency->id) {
return (string)$array['amount'];
}
}
return '0'; // @codeCoverageIgnore
}
/**
* @param Carbon $start
* @param Carbon $end
@@ -198,8 +176,7 @@ class SummaryController extends Controller
$set = $collector->getExtractedJournals();
/** @var array $transactionJournal */
foreach ($set as $transactionJournal) {
$currencyId = (int)$transactionJournal['currency_id'];
$currencyId = (int) $transactionJournal['currency_id'];
$incomes[$currencyId] = $incomes[$currencyId] ?? '0';
$incomes[$currencyId] = bcadd($incomes[$currencyId], bcmul($transactionJournal['amount'], '-1'));
$sums[$currencyId] = $sums[$currencyId] ?? '0';
@@ -221,7 +198,7 @@ class SummaryController extends Controller
/** @var array $transactionJournal */
foreach ($set as $transactionJournal) {
$currencyId = (int)$transactionJournal['currency_id'];
$currencyId = (int) $transactionJournal['currency_id'];
$expenses[$currencyId] = $expenses[$currencyId] ?? '0';
$expenses[$currencyId] = bcadd($expenses[$currencyId], $transactionJournal['amount']);
$sums[$currencyId] = $sums[$currencyId] ?? '0';
@@ -295,7 +272,7 @@ class SummaryController extends Controller
$return = [];
foreach ($paidAmount as $currencyId => $amount) {
$amount = bcmul($amount, '-1');
$currency = $this->currencyRepos->findNull((int)$currencyId);
$currency = $this->currencyRepos->findNull((int) $currencyId);
if (null === $currency) {
continue;
}
@@ -315,7 +292,7 @@ class SummaryController extends Controller
foreach ($unpaidAmount as $currencyId => $amount) {
$amount = bcmul($amount, '-1');
$currency = $this->currencyRepos->findNull((int)$currencyId);
$currency = $this->currencyRepos->findNull((int) $currencyId);
if (null === $currency) {
continue;
}
@@ -340,8 +317,8 @@ class SummaryController extends Controller
* @param Carbon $start
* @param Carbon $end
*
* @return array
* @throws Exception
* @return array
*/
private function getLeftToSpendInfo(Carbon $start, Carbon $end): array
{
@@ -360,7 +337,7 @@ class SummaryController extends Controller
$days = $today->diffInDays($end) + 1;
$perDay = '0';
if (0 !== $days && bccomp($leftToSpend, '0') > -1) {
$perDay = bcdiv($leftToSpend, (string)$days);
$perDay = bcdiv($leftToSpend, (string) $days);
}
$return[] = [
@@ -373,14 +350,18 @@ class SummaryController extends Controller
'currency_decimal_places' => $row['currency_decimal_places'],
'value_parsed' => app('amount')->formatFlat($row['currency_symbol'], $row['currency_decimal_places'], $leftToSpend, false),
'local_icon' => 'money',
'sub_title' => (string)trans(
'firefly.box_spend_per_day', ['amount' => app('amount')->formatFlat(
$row['currency_symbol'], $row['currency_decimal_places'], $perDay, false
)]
'sub_title' => (string) trans(
'firefly.box_spend_per_day',
['amount' => app('amount')->formatFlat(
$row['currency_symbol'],
$row['currency_decimal_places'],
$perDay,
false
)]
),
];
}
return $return;
}
@@ -443,5 +424,4 @@ class SummaryController extends Controller
return $return;
}
}

View File

@@ -25,12 +25,13 @@ namespace FireflyIII\Api\V1\Controllers;
use Carbon\Carbon;
use FireflyIII\Api\V1\Requests\DateRequest;
use FireflyIII\Api\V1\Requests\TagUpdateRequest;
use FireflyIII\Api\V1\Requests\TagStoreRequest;
use FireflyIII\Api\V1\Requests\TagUpdateRequest;
use FireflyIII\Helpers\Collector\GroupCollectorInterface;
use FireflyIII\Models\Tag;
use FireflyIII\Repositories\Tag\TagRepositoryInterface;
use FireflyIII\Support\Http\Api\TransactionFilter;
use FireflyIII\Transformers\AttachmentTransformer;
use FireflyIII\Transformers\TagTransformer;
use FireflyIII\Transformers\TransactionGroupTransformer;
use FireflyIII\User;
@@ -117,7 +118,7 @@ class TagController extends Controller
{
$manager = $this->getManager();
// types to get, page size:
$pageSize = (int)app('preferences')->getForUser(auth()->user(), 'listPageSize', 50)->data;
$pageSize = (int) app('preferences')->getForUser(auth()->user(), 'listPageSize', 50)->data;
// get list of budgets. Count it and split it.
$collection = $this->repository->get();
@@ -138,6 +139,36 @@ class TagController extends Controller
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', 'application/vnd.api+json');
}
/**
* @param Tag $tag
*
* @return JsonResponse
* @codeCoverageIgnore
*/
public function attachments(Tag $tag): JsonResponse
{
$manager = $this->getManager();
$pageSize = (int) app('preferences')->getForUser(auth()->user(), 'listPageSize', 50)->data;
$collection = $this->repository->getAttachments($tag);
$count = $collection->count();
$attachments = $collection->slice(($this->parameters->get('page') - 1) * $pageSize, $pageSize);
// make paginator:
$paginator = new LengthAwarePaginator($attachments, $count, $pageSize, $this->parameters->get('page'));
$paginator->setPath(route('api.v1.tags.attachments', [$tag->id]) . $this->buildParams());
/** @var AttachmentTransformer $transformer */
$transformer = app(AttachmentTransformer::class);
$transformer->setParameters($this->parameters);
$resource = new FractalCollection($attachments, $transformer, 'attachments');
$resource->setPaginator(new IlluminatePaginatorAdapter($paginator));
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', 'application/vnd.api+json');
}
/**
* List single resource.
*
@@ -190,7 +221,7 @@ class TagController extends Controller
*/
public function transactions(Request $request, Tag $tag): JsonResponse
{
$pageSize = (int)app('preferences')->getForUser(auth()->user(), 'listPageSize', 50)->data;
$pageSize = (int) app('preferences')->getForUser(auth()->user(), 'listPageSize', 50)->data;
$type = $request->get('type') ?? 'default';
$this->parameters->set('type', $type);
@@ -236,7 +267,7 @@ class TagController extends Controller
* Update a rule.
*
* @param TagUpdateRequest $request
* @param Tag $tag
* @param Tag $tag
*
* @return JsonResponse
*/
@@ -288,8 +319,8 @@ class TagController extends Controller
];
/** @var Tag $tag */
foreach ($tags as $tag) {
$earned = (float)$this->repository->earnedInPeriod($tag, $start, $end);
$spent = (float)$this->repository->spentInPeriod($tag, $start, $end);
$earned = (float) $this->repository->earnedInPeriod($tag, $start, $end);
$spent = (float) $this->repository->spentInPeriod($tag, $start, $end);
$size = ($spent * -1) + $earned;
$min = $min ?? $size;
if ($size > 0) {

View File

@@ -29,6 +29,7 @@ use FireflyIII\Api\V1\Requests\TransactionUpdateRequest;
use FireflyIII\Events\StoredTransactionGroup;
use FireflyIII\Events\UpdatedTransactionGroup;
use FireflyIII\Exceptions\DuplicateTransactionException;
use FireflyIII\Exceptions\FireflyException;
use FireflyIII\Helpers\Collector\GroupCollectorInterface;
use FireflyIII\Models\TransactionGroup;
use FireflyIII\Models\TransactionJournal;
@@ -109,7 +110,6 @@ class TransactionController extends Controller
$resource = new FractalCollection($attachments, $transformer, 'attachments');
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', 'application/vnd.api+json');
}
/**
@@ -152,7 +152,7 @@ class TransactionController extends Controller
*/
public function index(Request $request): JsonResponse
{
$pageSize = (int)app('preferences')->getForUser(auth()->user(), 'listPageSize', 50)->data;
$pageSize = (int) app('preferences')->getForUser(auth()->user(), 'listPageSize', 50)->data;
$type = $request->get('type') ?? 'default';
$this->parameters->set('type', $type);
@@ -214,7 +214,6 @@ class TransactionController extends Controller
$resource = new FractalCollection($events, $transformer, 'piggy_bank_events');
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', 'application/vnd.api+json');
}
/**
@@ -274,6 +273,7 @@ class TransactionController extends Controller
*/
public function store(TransactionStoreRequest $request): JsonResponse
{
Log::debug('Now in API TransactionController::store()');
$data = $request->getAll();
$data['user'] = auth()->user()->id;
@@ -283,6 +283,7 @@ class TransactionController extends Controller
try {
$transactionGroup = $this->groupRepository->store($data);
} catch (DuplicateTransactionException $e) {
Log::warning('Caught a duplicate. Return error message.');
// return bad validation message.
// TODO use Laravel's internal validation thing to do this.
$response = [
@@ -293,9 +294,22 @@ class TransactionController extends Controller
];
return response()->json($response, 422);
}
} catch (FireflyException $e) {
Log::warning('Caught an exception. Return error message.');
Log::error($e->getMessage());
// return bad validation message.
// TODO use Laravel's internal validation thing to do this.
$response = [
'message' => 'The given data was invalid.',
'errors' => [
'transactions.0.description' => [sprintf('Internal exception: %s', $e->getMessage())],
],
];
event(new StoredTransactionGroup($transactionGroup));
return response()->json($response, 422);
}
app('preferences')->mark();
event(new StoredTransactionGroup($transactionGroup, $data['apply_rules'] ?? true));
$manager = $this->getManager();
/** @var User $admin */
@@ -338,7 +352,8 @@ class TransactionController extends Controller
$transactionGroup = $this->groupRepository->update($transactionGroup, $data);
$manager = $this->getManager();
event(new UpdatedTransactionGroup($transactionGroup));
app('preferences')->mark();
event(new UpdatedTransactionGroup($transactionGroup, $data['apply_rules'] ?? true));
/** @var User $admin */
$admin = auth()->user();
@@ -362,6 +377,5 @@ class TransactionController extends Controller
$resource = new Item($selectedGroup, $transformer, 'transactions');
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', 'application/vnd.api+json');
}
}

View File

@@ -105,7 +105,7 @@ class TransactionLinkController extends Controller
$name = $request->get('name');
// types to get, page size:
$pageSize = (int)app('preferences')->getForUser(auth()->user(), 'listPageSize', 50)->data;
$pageSize = (int) app('preferences')->getForUser(auth()->user(), 'listPageSize', 50)->data;
$linkType = $this->repository->findByName($name);
// get list of transaction links. Count it and split it.
@@ -155,8 +155,8 @@ class TransactionLinkController extends Controller
*
* @param TransactionLinkRequest $request
*
* @return JsonResponse
* @throws FireflyException
* @return JsonResponse
*/
public function store(TransactionLinkRequest $request): JsonResponse
{
@@ -186,8 +186,8 @@ class TransactionLinkController extends Controller
* @param TransactionLinkRequest $request
* @param TransactionJournalLink $journalLink
*
* @return JsonResponse
* @throws FireflyException
* @return JsonResponse
*/
public function update(TransactionLinkRequest $request, TransactionJournalLink $journalLink): JsonResponse
{

View File

@@ -70,9 +70,9 @@ class UserController extends Controller
*
* @param User $user
*
* @return JsonResponse
* @throws FireflyException
* @codeCoverageIgnore
* @return JsonResponse
*/
public function delete(User $user): JsonResponse
{
@@ -95,7 +95,7 @@ class UserController extends Controller
public function index(): JsonResponse
{
// user preferences
$pageSize = (int)app('preferences')->getForUser(auth()->user(), 'listPageSize', 50)->data;
$pageSize = (int) app('preferences')->getForUser(auth()->user(), 'listPageSize', 50)->data;
$manager = $this->getManager();
// build collection

View File

@@ -126,7 +126,7 @@ class AccountStoreRequest extends Request
'interest_period' => 'required_if:type,liability|in:daily,monthly,yearly',
'notes' => 'min:0|max:65536',
];
$rules = Location::requestRules($rules);
$rules = Location::requestRules($rules);
return $rules;
}

View File

@@ -105,7 +105,7 @@ class AccountUpdateRequest extends Request
$types = implode(',', array_keys(config('firefly.subTitlesByIdentifier')));
$ccPaymentTypes = implode(',', array_keys(config('firefly.ccTypes')));
$rules = [
$rules = [
'name' => sprintf('min:1|uniqueAccountForUser:%d', $account->id),
'type' => sprintf('in:%s', $types),
'iban' => 'iban|nullable',

View File

@@ -23,9 +23,6 @@ declare(strict_types=1);
namespace FireflyIII\Api\V1\Requests;
use FireflyIII\Models\Bill;
use FireflyIII\Models\ImportJob;
use FireflyIII\Models\TransactionJournal;
use FireflyIII\Rules\IsValidAttachmentModel;
/**
@@ -57,8 +54,8 @@ class AttachmentStoreRequest extends Request
'filename' => $this->string('filename'),
'title' => $this->string('title'),
'notes' => $this->nlString('notes'),
'model' => $this->string('model'),
'model_id' => $this->integer('model_id'),
'model' => $this->string('attachable_type'),
'model_id' => $this->integer('attachable_id'),
];
}
@@ -69,22 +66,22 @@ class AttachmentStoreRequest extends Request
*/
public function rules(): array
{
$models = implode(
',',
[
str_replace('FireflyIII\\Models\\', '', Bill::class),
str_replace('FireflyIII\\Models\\', '', ImportJob::class),
str_replace('FireflyIII\\Models\\', '', TransactionJournal::class),
]
$models = config('firefly.valid_attachment_models');
$models = array_map(
static function (string $className) {
return str_replace('FireflyIII\\Models\\', '', $className);
}, $models
);
$model = $this->string('model');
$models = implode(',', $models);
$model = $this->string('attachable_type');
return [
'filename' => 'required|between:1,255',
'title' => 'between:1,255',
'notes' => 'between:1,65000',
'model' => sprintf('required|in:%s', $models),
'model_id' => ['required', 'numeric', new IsValidAttachmentModel($model)],
'filename' => 'required|between:1,255',
'title' => 'between:1,255',
'notes' => 'between:1,65000',
'attachable_type' => sprintf('required|in:%s', $models),
'attachable_id' => ['required', 'numeric', new IsValidAttachmentModel($model)],
];
}
}

View File

@@ -52,8 +52,8 @@ class AttachmentUpdateRequest extends Request
'filename' => $this->string('filename'),
'title' => $this->string('title'),
'notes' => $this->nlString('notes'),
'model' => $this->string('model'),
'model_id' => $this->integer('model_id'),
'model' => $this->string('attachable_type'),
'model_id' => $this->integer('attachable_id'),
];
}

View File

@@ -64,15 +64,13 @@ class AvailableBudgetRequest extends Request
*/
public function rules(): array
{
$rules = [
return [
'currency_id' => 'numeric|exists:transaction_currencies,id',
'currency_code' => 'min:3|max:3|exists:transaction_currencies,code',
'amount' => 'required|numeric|more:0',
'start' => 'required|date|before:end',
'end' => 'required|date|after:start',
];
return $rules;
}

View File

@@ -60,7 +60,7 @@ class BillRequest extends Request
$active = $this->boolean('active');
}
$data = [
return [
'name' => $this->string('name'),
'amount_min' => $this->string('amount_min'),
'amount_max' => $this->string('amount_max'),
@@ -72,8 +72,6 @@ class BillRequest extends Request
'active' => $active,
'notes' => $this->nlString('notes'),
];
return $data;
}
/**
@@ -121,10 +119,10 @@ class BillRequest extends Request
$validator->after(
static function (Validator $validator) {
$data = $validator->getData();
$min = (float)($data['amount_min'] ?? 0);
$max = (float)($data['amount_max'] ?? 0);
$min = (float) ($data['amount_min'] ?? 0);
$max = (float) ($data['amount_max'] ?? 0);
if ($min > $max) {
$validator->errors()->add('amount_min', (string)trans('validation.amount_min_over_max'));
$validator->errors()->add('amount_min', (string) trans('validation.amount_min_over_max'));
}
}
);

View File

@@ -1,91 +0,0 @@
<?php
/**
* BudgetRequest.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\Models\Budget;
use FireflyIII\Rules\IsBoolean;
/**
* Class BudgetRequest
*
* @codeCoverageIgnore
* TODO AFTER 4.8,0: split this into two request classes.
*/
class BudgetRequest 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
{
$active = true;
if (null !== $this->get('active')) {
$active = $this->boolean('active');
}
return [
'name' => $this->string('name'),
'active' => $active,
'order' => 0,
];
}
/**
* The rules that the incoming request must be matched against.
*
* @return array
*/
public function rules(): array
{
$rules = [
'name' => 'required|between:1,100|uniqueObjectForUser:budgets,name',
'active' => [new IsBoolean],
];
switch ($this->method()) {
default:
break;
case 'PUT':
case 'PATCH':
/** @var Budget $budget */
$budget = $this->route()->parameter('budget');
$rules['name'] = sprintf('required|between:1,100|uniqueObjectForUser:budgets,name,%d', $budget->id);
break;
}
return $rules;
}
}

View File

@@ -0,0 +1,106 @@
<?php
/**
* BudgetStoreRequest.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\IsBoolean;
use Illuminate\Validation\Validator;
/**
* Class BudgetStoreRequest
*
* @codeCoverageIgnore
*/
class BudgetStoreRequest 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
{
$active = true;
if (null !== $this->get('active')) {
$active = $this->boolean('active');
}
return [
'name' => $this->string('name'),
'active' => $active,
'order' => 0,
'auto_budget_type' => $this->string('auto_budget_type'),
'transaction_currency_id' => $this->integer('auto_budget_currency_id'),
'transaction_currency_code' => $this->string('auto_budget_currency_code'),
'auto_budget_amount' => $this->string('auto_budget_amount'),
'auto_budget_period' => $this->string('auto_budget_period'),
];
}
/**
* The rules that the incoming request must be matched against.
*
* @return array
*/
public function rules(): array
{
return [
'name' => 'required|between:1,100|uniqueObjectForUser:budgets,name',
'active' => [new IsBoolean],
'auto_budget_type' => 'in:reset,rollover,none',
'auto_budget_currency_id' => 'exists:transaction_currencies,id',
'auto_budget_currency_code' => 'exists:transaction_currencies,code',
'auto_budget_amount' => 'min:0|max:1000000000',
'auto_budget_period' => 'in:daily,weekly,monthly,quarterly,half_year,yearly',
];
}
/**
* Configure the validator instance with special rules for after the basic validation rules.
*
* @param Validator $validator
*
* @return void
*/
public function withValidator(Validator $validator): void
{
$validator->after(
function (Validator $validator) {
// validate all account info
$this->validateAutoBudgetAmount($validator);
}
);
}
}

View File

@@ -0,0 +1,107 @@
<?php
/**
* BudgetUpdateRequest.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\IsBoolean;
use Illuminate\Validation\Validator;
/**
* Class BudgetUpdateRequest
*
* @codeCoverageIgnore
*/
class BudgetUpdateRequest 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
{
$active = true;
if (null !== $this->get('active')) {
$active = $this->boolean('active');
}
return [
'name' => $this->string('name'),
'active' => $active,
'order' => 0,
'auto_budget_type' => $this->string('auto_budget_type'),
'transaction_currency_id' => $this->integer('auto_budget_currency_id'),
'transaction_currency_code' => $this->string('auto_budget_currency_code'),
'auto_budget_amount' => $this->string('auto_budget_amount'),
'auto_budget_period' => $this->string('auto_budget_period'),
];
}
/**
* The rules that the incoming request must be matched against.
*
* @return array
*/
public function rules(): array
{
$budget = $this->route()->parameter('budget');
return [
'name' => sprintf('required|between:1,100|uniqueObjectForUser:budgets,name,%d', $budget->id),
'active' => [new IsBoolean],
'auto_budget_type' => 'in:reset,rollover,none',
'auto_budget_currency_id' => 'exists:transaction_currencies,id',
'auto_budget_currency_code' => 'exists:transaction_currencies,code',
'auto_budget_amount' => 'min:0|max:1000000000',
'auto_budget_period' => 'in:daily,weekly,monthly,quarterly,half_year,yearly',
];
}
/**
* Configure the validator instance with special rules for after the basic validation rules.
*
* @param Validator $validator
*
* @return void
*/
public function withValidator(Validator $validator): void
{
$validator->after(
function (Validator $validator) {
// validate all account info
$this->validateAutoBudgetAmount($validator);
}
);
}
}

View File

@@ -26,6 +26,7 @@ namespace FireflyIII\Api\V1\Requests;
use Carbon\Carbon;
use FireflyIII\Rules\BelongsUser;
use FireflyIII\Rules\IsBoolean;
use FireflyIII\Validation\CurrencyValidation;
use FireflyIII\Validation\RecurrenceValidation;
use FireflyIII\Validation\TransactionValidation;
use Illuminate\Validation\Validator;
@@ -35,7 +36,7 @@ use Illuminate\Validation\Validator;
*/
class RecurrenceStoreRequest extends Request
{
use RecurrenceValidation, TransactionValidation;
use RecurrenceValidation, TransactionValidation, CurrencyValidation;
/**
* Authorize logged in users.
@@ -63,7 +64,8 @@ class RecurrenceStoreRequest extends Request
if (null !== $this->get('apply_rules')) {
$applyRules = $this->boolean('apply_rules');
}
$return = [
return [
'recurrence' => [
'type' => $this->string('type'),
'title' => $this->string('title'),
@@ -77,8 +79,6 @@ class RecurrenceStoreRequest extends Request
'transactions' => $this->getTransactionData(),
'repetitions' => $this->getRepetitionData(),
];
return $return;
}
/**
@@ -168,8 +168,8 @@ class RecurrenceStoreRequest extends Request
$return[] = [
'type' => $repetition['type'],
'moment' => $repetition['moment'],
'skip' => (int)$repetition['skip'],
'weekend' => (int)$repetition['weekend'],
'skip' => (int) $repetition['skip'],
'weekend' => (int) $repetition['weekend'],
];
}
@@ -193,29 +193,7 @@ class RecurrenceStoreRequest extends Request
}
/** @var array $transaction */
foreach ($transactions as $transaction) {
$return[] = [
'amount' => $transaction['amount'],
'currency_id' => isset($transaction['currency_id']) ? (int)$transaction['currency_id'] : null,
'currency_code' => $transaction['currency_code'] ?? null,
'foreign_amount' => $transaction['foreign_amount'] ?? null,
'foreign_currency_id' => isset($transaction['foreign_currency_id']) ? (int)$transaction['foreign_currency_id'] : null,
'foreign_currency_code' => $transaction['foreign_currency_code'] ?? null,
'source_id' => isset($transaction['source_id']) ? (int)$transaction['source_id'] : null,
'source_name' => isset($transaction['source_name']) ? (string)$transaction['source_name'] : null,
'destination_id' => isset($transaction['destination_id']) ? (int)$transaction['destination_id'] : null,
'destination_name' => isset($transaction['destination_name']) ? (string)$transaction['destination_name'] : null,
'description' => $transaction['description'],
'type' => $this->string('type'),
// new and updated fields:
'piggy_bank_id' => isset($transaction['piggy_bank_id']) ? (int)$transaction['piggy_bank_id'] : null,
'piggy_bank_name' => $transaction['piggy_bank_name'] ?? null,
'tags' => $transaction['tags'] ?? [],
'budget_id' => isset($transaction['budget_id']) ? (int)$transaction['budget_id'] : null,
'budget_name' => $transaction['budget_name'] ?? null,
'category_id' => isset($transaction['category_id']) ? (int)$transaction['category_id'] : null,
'category_name' => $transaction['category_name'] ?? null,
];
$return[] = $this->getSingleRecurrenceData($transaction);
}
return $return;

View File

@@ -26,6 +26,7 @@ namespace FireflyIII\Api\V1\Requests;
use FireflyIII\Models\Recurrence;
use FireflyIII\Rules\BelongsUser;
use FireflyIII\Rules\IsBoolean;
use FireflyIII\Validation\CurrencyValidation;
use FireflyIII\Validation\RecurrenceValidation;
use FireflyIII\Validation\TransactionValidation;
use Illuminate\Validation\Validator;
@@ -35,7 +36,7 @@ use Illuminate\Validation\Validator;
*/
class RecurrenceUpdateRequest extends Request
{
use RecurrenceValidation, TransactionValidation;
use RecurrenceValidation, TransactionValidation, CurrencyValidation;
/**
* Authorize logged in users.
@@ -63,7 +64,8 @@ class RecurrenceUpdateRequest extends Request
if (null !== $this->get('apply_rules')) {
$applyRules = $this->boolean('apply_rules');
}
$return = [
return [
'recurrence' => [
'type' => $this->nullableString('type'),
'title' => $this->nullableString('title'),
@@ -78,8 +80,6 @@ class RecurrenceUpdateRequest extends Request
'transactions' => $this->getTransactionData(),
'repetitions' => $this->getRepetitionData(),
];
return $return;
}
/**
@@ -141,7 +141,7 @@ class RecurrenceUpdateRequest extends Request
{
$validator->after(
function (Validator $validator) {
$this->validateOneRecurrenceTransactionUpdate($validator);
$this->validateOneRecurrenceTransaction($validator);
$this->validateOneRepetitionUpdate($validator);
$this->validateRecurrenceRepetition($validator);
$this->validateRepetitionMoment($validator);
@@ -170,8 +170,8 @@ class RecurrenceUpdateRequest extends Request
$return[] = [
'type' => $repetition['type'],
'moment' => $repetition['moment'],
'skip' => (int)$repetition['skip'],
'weekend' => (int)$repetition['weekend'],
'skip' => (int) $repetition['skip'],
'weekend' => (int) $repetition['weekend'],
];
}
@@ -195,29 +195,7 @@ class RecurrenceUpdateRequest extends Request
}
/** @var array $transaction */
foreach ($transactions as $transaction) {
$return[] = [
'amount' => $transaction['amount'],
'currency_id' => isset($transaction['currency_id']) ? (int)$transaction['currency_id'] : null,
'currency_code' => $transaction['currency_code'] ?? null,
'foreign_amount' => $transaction['foreign_amount'] ?? null,
'foreign_currency_id' => isset($transaction['foreign_currency_id']) ? (int)$transaction['foreign_currency_id'] : null,
'foreign_currency_code' => $transaction['foreign_currency_code'] ?? null,
'source_id' => isset($transaction['source_id']) ? (int)$transaction['source_id'] : null,
'source_name' => isset($transaction['source_name']) ? (string)$transaction['source_name'] : null,
'destination_id' => isset($transaction['destination_id']) ? (int)$transaction['destination_id'] : null,
'destination_name' => isset($transaction['destination_name']) ? (string)$transaction['destination_name'] : null,
'description' => $transaction['description'],
'type' => $this->string('type'),
// new and updated fields:
'piggy_bank_id' => isset($transaction['piggy_bank_id']) ? (int)$transaction['piggy_bank_id'] : null,
'piggy_bank_name' => $transaction['piggy_bank_name'] ?? null,
'tags' => $transaction['tags'] ?? [],
'budget_id' => isset($transaction['budget_id']) ? (int)$transaction['budget_id'] : null,
'budget_name' => $transaction['budget_name'] ?? null,
'category_id' => isset($transaction['category_id']) ? (int)$transaction['category_id'] : null,
'category_name' => $transaction['category_name'] ?? null,
];
$return[] = $this->getSingleRecurrenceData($transaction);
}
return $return;

View File

@@ -34,4 +34,36 @@ use FireflyIII\Http\Requests\Request as FireflyIIIRequest;
*/
class Request extends FireflyIIIRequest
{
/**
* @param array $transaction
*
* @return array
*/
protected function getSingleRecurrenceData(array $transaction): array
{
return [
'amount' => $transaction['amount'],
'currency_id' => isset($transaction['currency_id']) ? (int) $transaction['currency_id'] : null,
'currency_code' => $transaction['currency_code'] ?? null,
'foreign_amount' => $transaction['foreign_amount'] ?? null,
'foreign_currency_id' => isset($transaction['foreign_currency_id']) ? (int) $transaction['foreign_currency_id'] : null,
'foreign_currency_code' => $transaction['foreign_currency_code'] ?? null,
'source_id' => isset($transaction['source_id']) ? (int) $transaction['source_id'] : null,
'source_name' => isset($transaction['source_name']) ? (string) $transaction['source_name'] : null,
'destination_id' => isset($transaction['destination_id']) ? (int) $transaction['destination_id'] : null,
'destination_name' => isset($transaction['destination_name']) ? (string) $transaction['destination_name'] : null,
'description' => $transaction['description'],
'type' => $this->string('type'),
// new and updated fields:
'piggy_bank_id' => isset($transaction['piggy_bank_id']) ? (int) $transaction['piggy_bank_id'] : null,
'piggy_bank_name' => $transaction['piggy_bank_name'] ?? null,
'tags' => $transaction['tags'] ?? [],
'budget_id' => isset($transaction['budget_id']) ? (int) $transaction['budget_id'] : null,
'budget_name' => $transaction['budget_name'] ?? null,
'category_id' => isset($transaction['category_id']) ? (int) $transaction['category_id'] : null,
'category_name' => $transaction['category_name'] ?? null,
];
}
}

View File

@@ -54,7 +54,7 @@ class RuleGroupTestRequest extends Request
*/
public function getTestParameters(): array
{
$return = [
return [
'page' => $this->getPage(),
'start_date' => $this->getDate('start_date'),
'end_date' => $this->getDate('end_date'),
@@ -62,9 +62,6 @@ class RuleGroupTestRequest extends Request
'trigger_limit' => $this->getTriggerLimit(),
'accounts' => $this->getAccounts(),
];
return $return;
}
/**
@@ -80,7 +77,7 @@ class RuleGroupTestRequest extends Request
*/
private function getAccounts(): Collection
{
$accountList = '' === (string)$this->query('accounts') ? [] : explode(',', $this->query('accounts'));
$accountList = '' === (string) $this->query('accounts') ? [] : explode(',', $this->query('accounts'));
$accounts = new Collection;
/** @var AccountRepositoryInterface $accountRepository */
@@ -88,7 +85,7 @@ class RuleGroupTestRequest extends Request
foreach ($accountList as $accountId) {
Log::debug(sprintf('Searching for asset account with id "%s"', $accountId));
$account = $accountRepository->findNull((int)$accountId);
$account = $accountRepository->findNull((int) $accountId);
if ($this->validAccount($account)) {
/** @noinspection NullPointerExceptionInspection */
Log::debug(sprintf('Found account #%d ("%s") and its an asset account', $account->id, $account->name));
@@ -117,7 +114,7 @@ class RuleGroupTestRequest extends Request
*/
private function getPage(): int
{
return 0 === (int)$this->query('page') ? 1 : (int)$this->query('page');
return 0 === (int) $this->query('page') ? 1 : (int) $this->query('page');
}
@@ -126,7 +123,7 @@ class RuleGroupTestRequest extends Request
*/
private function getSearchLimit(): int
{
return 0 === (int)$this->query('search_limit') ? (int)config('firefly.test-triggers.limit') : (int)$this->query('search_limit');
return 0 === (int) $this->query('search_limit') ? (int) config('firefly.test-triggers.limit') : (int) $this->query('search_limit');
}
/**
@@ -134,7 +131,7 @@ class RuleGroupTestRequest extends Request
*/
private function getTriggerLimit(): int
{
return 0 === (int)$this->query('triggered_limit') ? (int)config('firefly.test-triggers.range') : (int)$this->query('triggered_limit');
return 0 === (int) $this->query('triggered_limit') ? (int) config('firefly.test-triggers.range') : (int) $this->query('triggered_limit');
}
/**

View File

@@ -54,14 +54,11 @@ class RuleGroupTriggerRequest extends Request
*/
public function getTriggerParameters(): array
{
$return = [
return [
'start_date' => $this->getDate('start_date'),
'end_date' => $this->getDate('end_date'),
'accounts' => $this->getAccounts(),
];
return $return;
}
/**
@@ -80,7 +77,7 @@ class RuleGroupTriggerRequest extends Request
*/
private function getAccounts(): Collection
{
$accountList = '' === (string)$this->query('accounts') ? [] : explode(',', $this->query('accounts'));
$accountList = '' === (string) $this->query('accounts') ? [] : explode(',', $this->query('accounts'));
$accounts = new Collection;
/** @var AccountRepositoryInterface $accountRepository */
@@ -88,7 +85,7 @@ class RuleGroupTriggerRequest extends Request
foreach ($accountList as $accountId) {
Log::debug(sprintf('Searching for asset account with id "%s"', $accountId));
$account = $accountRepository->findNull((int)$accountId);
$account = $accountRepository->findNull((int) $accountId);
if ($this->validAccount($account)) {
/** @noinspection NullPointerExceptionInspection */
Log::debug(sprintf('Found account #%d ("%s") and its an asset account', $account->id, $account->name));

View File

@@ -65,7 +65,7 @@ class RuleStoreRequest extends Request
$stopProcessing = $this->boolean('stop_processing');
}
$data = [
return [
'title' => $this->string('title'),
'description' => $this->string('description'),
'rule_group_id' => $this->integer('rule_group_id'),
@@ -77,8 +77,6 @@ class RuleStoreRequest extends Request
'triggers' => $this->getRuleTriggers(),
'actions' => $this->getRuleActions(),
];
return $data;
}
/**
@@ -94,7 +92,8 @@ class RuleStoreRequest extends Request
// some triggers and actions require text:
$contextTriggers = implode(',', config('firefly.context-rule-triggers'));
$contextActions = implode(',', config('firefly.context-rule-actions'));
$rules = [
return [
'title' => 'required|between:1,100|uniqueObjectForUser:rules,title',
'description' => 'between:1,5000|nullable',
'rule_group_id' => 'required|belongsToUser:rule_groups|required_without:rule_group_title',
@@ -112,8 +111,6 @@ class RuleStoreRequest extends Request
'stop_processing' => [new IsBoolean],
'active' => [new IsBoolean],
];
return $rules;
}
/**
@@ -144,7 +141,7 @@ class RuleStoreRequest extends Request
$actions = $data['actions'] ?? [];
// need at least one trigger
if (0 === count($actions)) {
$validator->errors()->add('title', (string)trans('validation.at_least_one_action'));
$validator->errors()->add('title', (string) trans('validation.at_least_one_action'));
}
}
@@ -159,7 +156,7 @@ class RuleStoreRequest extends Request
$triggers = $data['triggers'] ?? [];
// need at least one trigger
if (0 === count($triggers)) {
$validator->errors()->add('title', (string)trans('validation.at_least_one_trigger'));
$validator->errors()->add('title', (string) trans('validation.at_least_one_trigger'));
}
}
@@ -175,8 +172,8 @@ class RuleStoreRequest extends Request
$return[] = [
'type' => $action['type'],
'value' => $action['value'],
'active' => $this->convertBoolean((string)($action['active'] ?? 'false')),
'stop_processing' => $this->convertBoolean((string)($action['stop_processing'] ?? 'false')),
'active' => $this->convertBoolean((string) ($action['active'] ?? 'false')),
'stop_processing' => $this->convertBoolean((string) ($action['stop_processing'] ?? 'false')),
];
}
}
@@ -196,8 +193,8 @@ class RuleStoreRequest extends Request
$return[] = [
'type' => $trigger['type'],
'value' => $trigger['value'],
'active' => $this->convertBoolean((string)($trigger['active'] ?? 'false')),
'stop_processing' => $this->convertBoolean((string)($trigger['stop_processing'] ?? 'false')),
'active' => $this->convertBoolean((string) ($trigger['active'] ?? 'false')),
'stop_processing' => $this->convertBoolean((string) ($trigger['stop_processing'] ?? 'false')),
];
}
}

View File

@@ -54,7 +54,7 @@ class RuleTestRequest extends Request
*/
public function getTestParameters(): array
{
$return = [
return [
'page' => $this->getPage(),
'start_date' => $this->getDate('start_date'),
'end_date' => $this->getDate('end_date'),
@@ -62,9 +62,6 @@ class RuleTestRequest extends Request
'trigger_limit' => $this->getTriggerLimit(),
'accounts' => $this->getAccounts(),
];
return $return;
}
/**
@@ -80,7 +77,7 @@ class RuleTestRequest extends Request
*/
private function getAccounts(): Collection
{
$accountList = '' === (string)$this->query('accounts') ? [] : explode(',', $this->query('accounts'));
$accountList = '' === (string) $this->query('accounts') ? [] : explode(',', $this->query('accounts'));
$accounts = new Collection;
/** @var AccountRepositoryInterface $accountRepository */
@@ -88,7 +85,7 @@ class RuleTestRequest extends Request
foreach ($accountList as $accountId) {
Log::debug(sprintf('Searching for asset account with id "%s"', $accountId));
$account = $accountRepository->findNull((int)$accountId);
$account = $accountRepository->findNull((int) $accountId);
if ($this->validAccount($account)) {
/** @noinspection NullPointerExceptionInspection */
Log::debug(sprintf('Found account #%d ("%s") and its an asset account', $account->id, $account->name));
@@ -117,7 +114,7 @@ class RuleTestRequest extends Request
*/
private function getPage(): int
{
return 0 === (int)$this->query('page') ? 1 : (int)$this->query('page');
return 0 === (int) $this->query('page') ? 1 : (int) $this->query('page');
}
@@ -126,7 +123,7 @@ class RuleTestRequest extends Request
*/
private function getSearchLimit(): int
{
return 0 === (int)$this->query('search_limit') ? (int)config('firefly.test-triggers.limit') : (int)$this->query('search_limit');
return 0 === (int) $this->query('search_limit') ? (int) config('firefly.test-triggers.limit') : (int) $this->query('search_limit');
}
/**
@@ -134,7 +131,7 @@ class RuleTestRequest extends Request
*/
private function getTriggerLimit(): int
{
return 0 === (int)$this->query('triggered_limit') ? (int)config('firefly.test-triggers.range') : (int)$this->query('triggered_limit');
return 0 === (int) $this->query('triggered_limit') ? (int) config('firefly.test-triggers.range') : (int) $this->query('triggered_limit');
}
/**

View File

@@ -53,14 +53,11 @@ class RuleTriggerRequest extends Request
*/
public function getTriggerParameters(): array
{
$return = [
return [
'start_date' => $this->getDate('start_date'),
'end_date' => $this->getDate('end_date'),
'accounts' => $this->getAccounts(),
];
return $return;
}
/**
@@ -79,7 +76,7 @@ class RuleTriggerRequest extends Request
*/
private function getAccounts(): Collection
{
$accountList = '' === (string)$this->query('accounts') ? [] : explode(',', $this->query('accounts'));
$accountList = '' === (string) $this->query('accounts') ? [] : explode(',', $this->query('accounts'));
$accounts = new Collection;
/** @var AccountRepositoryInterface $accountRepository */
@@ -87,7 +84,7 @@ class RuleTriggerRequest extends Request
foreach ($accountList as $accountId) {
Log::debug(sprintf('Searching for asset account with id "%s"', $accountId));
$account = $accountRepository->findNull((int)$accountId);
$account = $accountRepository->findNull((int) $accountId);
if ($this->validAccount($account)) {
/** @noinspection NullPointerExceptionInspection */
Log::debug(sprintf('Found account #%d ("%s") and its an asset account', $account->id, $account->name));

View File

@@ -65,7 +65,7 @@ class RuleUpdateRequest extends Request
$stopProcessing = $this->boolean('stop_processing');
}
$data = [
return [
'title' => $this->nullableString('title'),
'description' => $this->nullableString('description'),
'rule_group_id' => $this->nullableInteger('rule_group_id'),
@@ -77,8 +77,6 @@ class RuleUpdateRequest extends Request
'triggers' => $this->getRuleTriggers(),
'actions' => $this->getRuleActions(),
];
return $data;
}
/**
@@ -95,7 +93,8 @@ class RuleUpdateRequest extends Request
// some triggers and actions require text:
$contextTriggers = implode(',', config('firefly.context-rule-triggers'));
$contextActions = implode(',', config('firefly.context-rule-actions'));
$rules = [
return [
'title' => sprintf('between:1,100|uniqueObjectForUser:rules,title,%d', $rule->id),
'description' => 'between:1,5000|nullable',
'rule_group_id' => 'belongsToUser:rule_groups',
@@ -113,8 +112,6 @@ class RuleUpdateRequest extends Request
'stop_processing' => [new IsBoolean],
'active' => [new IsBoolean],
];
return $rules;
}
/**
@@ -145,7 +142,7 @@ class RuleUpdateRequest extends Request
$actions = $data['actions'] ?? null;
// need at least one action
if (is_array($actions) && 0 === count($actions)) {
$validator->errors()->add('title', (string)trans('validation.at_least_one_action'));
$validator->errors()->add('title', (string) trans('validation.at_least_one_action'));
}
}
@@ -160,7 +157,7 @@ class RuleUpdateRequest extends Request
$triggers = $data['triggers'] ?? null;
// need at least one trigger
if (is_array($triggers) && 0 === count($triggers)) {
$validator->errors()->add('title', (string)trans('validation.at_least_one_trigger'));
$validator->errors()->add('title', (string) trans('validation.at_least_one_trigger'));
}
}
@@ -179,8 +176,8 @@ class RuleUpdateRequest extends Request
$return[] = [
'type' => $action['type'],
'value' => $action['value'],
'active' => $this->convertBoolean((string)($action['active'] ?? 'false')),
'stop_processing' => $this->convertBoolean((string)($action['stop_processing'] ?? 'false')),
'active' => $this->convertBoolean((string) ($action['active'] ?? 'false')),
'stop_processing' => $this->convertBoolean((string) ($action['stop_processing'] ?? 'false')),
];
}
}
@@ -203,8 +200,8 @@ class RuleUpdateRequest extends Request
$return[] = [
'type' => $trigger['type'],
'value' => $trigger['value'],
'active' => $this->convertBoolean((string)($trigger['active'] ?? 'false')),
'stop_processing' => $this->convertBoolean((string)($trigger['stop_processing'] ?? 'false')),
'active' => $this->convertBoolean((string) ($trigger['active'] ?? 'false')),
'stop_processing' => $this->convertBoolean((string) ($trigger['stop_processing'] ?? 'false')),
];
}
}

View File

@@ -1,4 +1,5 @@
<?php
declare(strict_types=1);
/**
* TransferRequest.php
* Copyright (c) 2019 james@firefly-iii.org
@@ -21,7 +22,6 @@
namespace FireflyIII\Api\V1\Requests\Search;
use FireflyIII\Api\V1\Requests\Request;
use FireflyIII\Rules\IsTransferAccount;
@@ -54,5 +54,4 @@ class TransferRequest extends Request
'date' => 'required|date',
];
}
}
}

View File

@@ -110,8 +110,8 @@ class TransactionLinkRequest extends Request
$journalRepos->setUser($user);
$data = $validator->getData();
$inwardId = (int)($data['inward_id'] ?? 0);
$outwardId = (int)($data['outward_id'] ?? 0);
$inwardId = (int) ($data['inward_id'] ?? 0);
$outwardId = (int) ($data['outward_id'] ?? 0);
$inward = $journalRepos->findNull($inwardId);
$outward = $journalRepos->findNull($outwardId);

View File

@@ -28,16 +28,18 @@ use FireflyIII\Rules\BelongsUser;
use FireflyIII\Rules\IsBoolean;
use FireflyIII\Rules\IsDateOrTime;
use FireflyIII\Support\NullArrayObject;
use FireflyIII\Validation\CurrencyValidation;
use FireflyIII\Validation\GroupValidation;
use FireflyIII\Validation\TransactionValidation;
use Illuminate\Validation\Validator;
use Log;
/**
* Class TransactionStoreRequest
*/
class TransactionStoreRequest extends Request
{
use TransactionValidation;
use TransactionValidation, GroupValidation, CurrencyValidation;
/**
* Authorize logged in users.
@@ -46,6 +48,8 @@ class TransactionStoreRequest extends Request
*/
public function authorize(): bool
{
Log::debug('Authorize TransactionStoreRequest');
// Only allow authenticated users
return auth()->check();
}
@@ -57,13 +61,14 @@ class TransactionStoreRequest extends Request
*/
public function getAll(): array
{
$data = [
Log::debug('get all data in TransactionStoreRequest');
return [
'group_title' => $this->string('group_title'),
'error_if_duplicate_hash' => $this->boolean('error_if_duplicate_hash'),
'apply_rules' => $this->boolean('apply_rules', true),
'transactions' => $this->getTransactionData(),
];
return $data;
}
/**
@@ -73,10 +78,13 @@ class TransactionStoreRequest extends Request
*/
public function rules(): array
{
$rules = [
Log::debug('Collect rules of TransactionStoreRequest');
return [
// basic fields for group:
'group_title' => 'between:1,1000|nullable',
'error_if_duplicate_hash' => [new IsBoolean],
'apply_rules' => [new IsBoolean],
// transaction rules (in array for splits):
'transactions.*.type' => 'required|in:withdrawal,deposit,transfer,opening-balance,reconciliation',
@@ -150,8 +158,6 @@ class TransactionStoreRequest extends Request
'transactions.*.invoice_date' => 'date|nullable',
];
return $rules;
}
@@ -208,63 +214,63 @@ class TransactionStoreRequest extends Request
$return[] = [
'type' => $this->stringFromValue($object['type']),
'date' => $this->dateFromValue($object['date']),
'order' => $this->integerFromValue((string)$object['order']),
'order' => $this->integerFromValue((string) $object['order']),
'currency_id' => $this->integerFromValue((string)$object['currency_id']),
'currency_id' => $this->integerFromValue((string) $object['currency_id']),
'currency_code' => $this->stringFromValue($object['currency_code']),
// foreign currency info:
'foreign_currency_id' => $this->integerFromValue((string)$object['foreign_currency_id']),
'foreign_currency_id' => $this->integerFromValue((string) $object['foreign_currency_id']),
'foreign_currency_code' => $this->stringFromValue($object['foreign_currency_code']),
// amount and foreign amount. Cannot be 0.
'amount' => $this->stringFromValue((string)$object['amount']),
'foreign_amount' => $this->stringFromValue((string)$object['foreign_amount']),
'amount' => $this->stringFromValue((string) $object['amount']),
'foreign_amount' => $this->stringFromValue((string) $object['foreign_amount']),
// description.
'description' => $this->stringFromValue($object['description']),
// source of transaction. If everything is null, assume cash account.
'source_id' => $this->integerFromValue((string)$object['source_id']),
'source_id' => $this->integerFromValue((string) $object['source_id']),
'source_name' => $this->stringFromValue($object['source_name']),
'source_iban' => $this->stringFromValue($object['source_iban']),
'source_number' => $this->stringFromValue($object['source_number']),
'source_bic' => $this->stringFromValue($object['source_bic']),
// destination of transaction. If everything is null, assume cash account.
'destination_id' => $this->integerFromValue((string)$object['destination_id']),
'destination_id' => $this->integerFromValue((string) $object['destination_id']),
'destination_name' => $this->stringFromValue($object['destination_name']),
'destination_iban' => $this->stringFromValue($object['destination_iban']),
'destination_number' => $this->stringFromValue($object['destination_number']),
'destination_bic' => $this->stringFromValue($object['destination_bic']),
// budget info
'budget_id' => $this->integerFromValue((string)$object['budget_id']),
'budget_id' => $this->integerFromValue((string) $object['budget_id']),
'budget_name' => $this->stringFromValue($object['budget_name']),
// category info
'category_id' => $this->integerFromValue((string)$object['category_id']),
'category_id' => $this->integerFromValue((string) $object['category_id']),
'category_name' => $this->stringFromValue($object['category_name']),
// journal bill reference. Optional. Will only work for withdrawals
'bill_id' => $this->integerFromValue((string)$object['bill_id']),
'bill_id' => $this->integerFromValue((string) $object['bill_id']),
'bill_name' => $this->stringFromValue($object['bill_name']),
// piggy bank reference. Optional. Will only work for transfers
'piggy_bank_id' => $this->integerFromValue((string)$object['piggy_bank_id']),
'piggy_bank_id' => $this->integerFromValue((string) $object['piggy_bank_id']),
'piggy_bank_name' => $this->stringFromValue($object['piggy_bank_name']),
// some other interesting properties
'reconciled' => $this->convertBoolean((string)$object['reconciled']),
'reconciled' => $this->convertBoolean((string) $object['reconciled']),
'notes' => $this->nlStringFromValue($object['notes']),
'tags' => $this->arrayFromValue($object['tags']),
// all custom fields:
'internal_reference' => $this->stringFromValue($object['internal_reference']),
'external_id' => $this->stringFromValue($object['external_id']),
'internal_reference' => $this->stringFromValue((string) $object['internal_reference']),
'external_id' => $this->stringFromValue((string) $object['external_id']),
'original_source' => sprintf('ff3-v%s|api-v%s', config('firefly.version'), config('firefly.api_version')),
'recurrence_id' => $this->integerFromValue($object['recurrence_id']),
'bunq_payment_id' => $this->stringFromValue($object['bunq_payment_id']),
'bunq_payment_id' => $this->stringFromValue((string) $object['bunq_payment_id']),
'sepa_cc' => $this->stringFromValue($object['sepa_cc']),
'sepa_ct_op' => $this->stringFromValue($object['sepa_ct_op']),

View File

@@ -28,6 +28,7 @@ use FireflyIII\Models\TransactionGroup;
use FireflyIII\Rules\BelongsUser;
use FireflyIII\Rules\IsBoolean;
use FireflyIII\Rules\IsDateOrTime;
use FireflyIII\Validation\GroupValidation;
use FireflyIII\Validation\TransactionValidation;
use Illuminate\Validation\Validator;
use Log;
@@ -37,7 +38,7 @@ use Log;
*/
class TransactionUpdateRequest extends Request
{
use TransactionValidation;
use TransactionValidation, GroupValidation;
/** @var array Array values. */
private $arrayFields;
@@ -138,6 +139,7 @@ class TransactionUpdateRequest extends Request
$data = [
'transactions' => $this->getTransactionData(),
'apply_rules' => $this->boolean('apply_rules', true),
];
if ($this->has('group_title')) {
$data['group_title'] = $this->string('group_title');
@@ -153,9 +155,10 @@ class TransactionUpdateRequest extends Request
*/
public function rules(): array
{
$rules = [
return [
// basic fields for group:
'group_title' => 'between:1,1000',
'apply_rules' => [new IsBoolean],
// transaction rules (in array for splits):
'transactions.*.type' => 'in:withdrawal,deposit,transfer,opening-balance,reconciliation',
@@ -220,8 +223,6 @@ class TransactionUpdateRequest extends Request
'transactions.*.payment_date' => 'date|nullable',
'transactions.*.invoice_date' => 'date|nullable',
];
return $rules;
}
/**
@@ -277,6 +278,111 @@ class TransactionUpdateRequest extends Request
);
}
/**
* @param array $current
* @param array $transaction
*
* @return array
*/
private function getArrayData(array $current, array $transaction): array
{
foreach ($this->arrayFields as $fieldName) {
if (array_key_exists($fieldName, $transaction)) {
$current[$fieldName] = $this->arrayFromValue($transaction[$fieldName]);
}
}
return $current;
}
/**
* @param array $current
* @param array $transaction
*
* @return array
*/
private function getBooleanData(array $current, array $transaction): array
{
foreach ($this->booleanFields as $fieldName) {
if (array_key_exists($fieldName, $transaction)) {
$current[$fieldName] = $this->convertBoolean((string) $transaction[$fieldName]);
}
}
return $current;
}
/**
* @param array $current
* @param array $transaction
*
* @return array
*/
private function getDateData(array $current, array $transaction): array
{
foreach ($this->dateFields as $fieldName) {
Log::debug(sprintf('Now at date field %s', $fieldName));
if (array_key_exists($fieldName, $transaction)) {
$current[$fieldName] = $this->dateFromValue((string) $transaction[$fieldName]);
Log::debug(sprintf('New value: "%s"', (string) $transaction[$fieldName]));
}
}
return $current;
}
/**
* For each field, add it to the array if a reference is present in the request:
*
* @param array $current
*
* @return array
*/
private function getIntegerData(array $current, array $transaction): array
{
foreach ($this->integerFields as $fieldName) {
if (array_key_exists($fieldName, $transaction)) {
$current[$fieldName] = $this->integerFromValue((string) $transaction[$fieldName]);
}
}
return $current;
}
/**
* @param array $current
* @param array $transaction
*
* @return array
*/
private function getNlStringData(array $current, array $transaction): array
{
foreach ($this->textareaFields as $fieldName) {
if (array_key_exists($fieldName, $transaction)) {
$current[$fieldName] = $this->nlStringFromValue((string) $transaction[$fieldName]);
}
}
return $current;
}
/**
* @param array $current
* @param array $transaction
*
* @return array
*/
private function getStringData(array $current, array $transaction): array
{
foreach ($this->stringFields as $fieldName) {
if (array_key_exists($fieldName, $transaction)) {
$current[$fieldName] = $this->stringFromValue((string) $transaction[$fieldName]);
}
}
return $current;
}
/**
* Get transaction data.
*
@@ -290,48 +396,15 @@ class TransactionUpdateRequest extends Request
* @var int $index
* @var array $transaction
*/
foreach ($this->get('transactions') as $index => $transaction) {
foreach ($this->get('transactions') as $transaction) {
// default response is to update nothing in the transaction:
$current = [];
// for each field, add it to the array if a reference is present in the request:
foreach ($this->integerFields as $fieldName) {
if (array_key_exists($fieldName, $transaction)) {
$current[$fieldName] = $this->integerFromValue((string)$transaction[$fieldName]);
}
}
foreach ($this->stringFields as $fieldName) {
if (array_key_exists($fieldName, $transaction)) {
$current[$fieldName] = $this->stringFromValue((string)$transaction[$fieldName]);
}
}
foreach ($this->textareaFields as $fieldName) {
if (array_key_exists($fieldName, $transaction)) {
$current[$fieldName] = $this->nlStringFromValue((string)$transaction[$fieldName]);
}
}
foreach ($this->dateFields as $fieldName) {
Log::debug(sprintf('Now at date field %s', $fieldName));
if (array_key_exists($fieldName, $transaction)) {
$current[$fieldName] = $this->dateFromValue((string)$transaction[$fieldName]);
Log::debug(sprintf('New value: "%s"', (string)$transaction[$fieldName]));
}
}
foreach ($this->booleanFields as $fieldName) {
if (array_key_exists($fieldName, $transaction)) {
$current[$fieldName] = $this->convertBoolean((string)$transaction[$fieldName]);
}
}
foreach ($this->arrayFields as $fieldName) {
if (array_key_exists($fieldName, $transaction)) {
$current[$fieldName] = $this->arrayFromValue($transaction[$fieldName]);
}
}
$current = [];
$current = $this->getIntegerData($current, $transaction);
$current = $this->getStringData($current, $transaction);
$current = $this->getNlStringData($current, $transaction);
$current = $this->getDateData($current, $transaction);
$current = $this->getBooleanData($current, $transaction);
$current = $this->getArrayData($current, $transaction);
$return[] = $current;
}

View File

@@ -69,14 +69,13 @@ class UserStoreRequest extends Request
if (null !== $this->get('blocked')) {
$blocked = $this->boolean('blocked');
}
$data = [
return [
'email' => $this->string('email'),
'blocked' => $blocked,
'blocked_code' => $this->string('blocked_code'),
'role' => $this->string('role'),
];
return $data;
}
/**

View File

@@ -69,14 +69,13 @@ class UserUpdateRequest extends Request
if (null !== $this->get('blocked')) {
$blocked = $this->boolean('blocked');
}
$data = [
return [
'email' => $this->string('email'),
'blocked' => $blocked,
'blocked_code' => $this->string('blocked_code'),
'role' => $this->string('role'),
];
return $data;
}
/**
@@ -86,15 +85,14 @@ class UserUpdateRequest extends Request
*/
public function rules(): array
{
$user = $this->route()->parameter('user');
$rules = [
$user = $this->route()->parameter('user');
return [
'email' => sprintf('email|unique:users,email,%d', $user->id),
'blocked' => [new IsBoolean],
'blocked_code' => 'in:email_changed',
'role' => 'in:owner,demo,',
];
return $rules;
}
}

View File

@@ -30,6 +30,7 @@ use Schema;
/**
* Class CorrectDatabase
*
* @codeCoverageIgnore
*/
class CorrectDatabase extends Command
@@ -73,7 +74,7 @@ class CorrectDatabase extends Command
'firefly-iii:fix-ob-currencies',
'firefly-iii:fix-long-descriptions',
'firefly-iii:fix-recurring-transactions',
'firefly-iii:restore-oauth-keys'
'firefly-iii:restore-oauth-keys',
];
foreach ($commands as $command) {
$this->line(sprintf('Now executing %s', $command));
@@ -82,6 +83,8 @@ class CorrectDatabase extends Command
echo $result;
}
// app('telemetry')->feature('executed-command', $this->signature);
return 0;
}
}

View File

@@ -76,6 +76,8 @@ 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;
}
@@ -111,15 +113,12 @@ class CorrectOpeningBalanceCurrencies extends Command
*/
private function getAccount(TransactionJournal $journal): ?Account
{
$excluded = [];
$transactions = $journal->transactions()->with(['account', 'account.accountType'])->get();
/** @var Transaction $transaction */
foreach ($transactions as $transaction) {
$account = $transaction->account;
if (null !== $account) {
if (AccountType::INITIAL_BALANCE !== $account->accountType->type) {
return $account;
}
if ((null !== $account) && AccountType::INITIAL_BALANCE !== $account->accountType->type) {
return $account;
}
}

View File

@@ -50,8 +50,8 @@ class CreateAccessTokens extends Command
/**
* Execute the console command.
*
* @return int
* @throws Exception
* @return int
*/
public function handle(): int
{
@@ -78,6 +78,8 @@ 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,6 +79,8 @@ 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

@@ -25,7 +25,6 @@ namespace FireflyIII\Console\Commands\Correction;
use Exception;
use FireflyIII\Models\TransactionGroup;
use FireflyIII\Models\TransactionJournal;
use Illuminate\Console\Command;
use Log;
@@ -50,16 +49,17 @@ class DeleteEmptyGroups extends Command
/**
* Execute the console command.
*
* @return mixed
* @throws Exception;
*
* @return int
*/
public function handle(): int
{
Log::debug(sprintf('Now in %s', __METHOD__));
$start = microtime(true);
$groupIds =
TransactionGroup
::leftJoin('transaction_journals','transaction_groups.id','=','transaction_journals.transaction_group_id')
$start = microtime(true);
$groupIds
= TransactionGroup
::leftJoin('transaction_journals', 'transaction_groups.id', '=', 'transaction_journals.transaction_group_id')
->whereNull('transaction_journals.id')->get(['transaction_groups.id'])->pluck('id')->toArray();
$total = count($groupIds);
@@ -76,6 +76,8 @@ 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,6 +58,7 @@ class DeleteEmptyJournals extends Command
$this->deleteUnevenJournals();
$this->deleteEmptyJournals();
// app('telemetry')->feature('executed-command', $this->signature);
return 0;
}
@@ -101,18 +102,18 @@ class DeleteEmptyJournals extends Command
->get([DB::raw('COUNT(transactions.transaction_journal_id) as the_count'), 'transaction_journal_id']);
$total = 0;
foreach ($set as $row) {
$count = (int)$row->the_count;
$count = (int) $row->the_count;
if (1 === $count % 2) {
// uneven number, delete journal and transactions:
try {
TransactionJournal::find((int)$row->transaction_journal_id)->delete();
TransactionJournal::find((int) $row->transaction_journal_id)->delete();
// @codeCoverageIgnoreStart
} catch (Exception $e) {
Log::info(sprintf('Could not delete journal: %s', $e->getMessage()));
}
// @codeCoverageIgnoreEnd
Transaction::where('transaction_journal_id', (int)$row->transaction_journal_id)->delete();
Transaction::where('transaction_journal_id', (int) $row->transaction_journal_id)->delete();
$this->info(sprintf('Deleted transaction journal #%d because it had an uneven number of transactions.', $row->transaction_journal_id));
$total++;
}

View File

@@ -51,8 +51,8 @@ class DeleteOrphanedTransactions extends Command
/**
* Execute the console command.
*
* @return int
* @throws Exception
* @return int
*/
public function handle(): int
{
@@ -62,6 +62,7 @@ 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;
}
@@ -79,7 +80,7 @@ class DeleteOrphanedTransactions extends Command
/** @var Transaction $transaction */
foreach ($set as $transaction) {
// delete journals
$journal = TransactionJournal::find((int)$transaction->transaction_journal_id);
$journal = TransactionJournal::find((int) $transaction->transaction_journal_id);
if ($journal) {
try {
$journal->delete();
@@ -89,10 +90,13 @@ class DeleteOrphanedTransactions extends Command
}
// @codeCoverageIgnoreEnd
}
Transaction::where('transaction_journal_id', (int)$transaction->transaction_journal_id)->delete();
Transaction::where('transaction_journal_id', (int) $transaction->transaction_journal_id)->delete();
$this->line(
sprintf('Deleted transaction journal #%d because account #%d was already deleted.',
$transaction->transaction_journal_id, $transaction->account_id)
sprintf(
'Deleted transaction journal #%d because account #%d was already deleted.',
$transaction->transaction_journal_id,
$transaction->account_id
)
);
$count++;
}
@@ -120,7 +124,7 @@ class DeleteOrphanedTransactions extends Command
);
/** @var stdClass $entry */
foreach ($set as $entry) {
$transaction = Transaction::find((int)$entry->transaction_id);
$transaction = Transaction::find((int) $entry->transaction_id);
$transaction->delete();
$this->info(
sprintf(
@@ -134,6 +138,5 @@ class DeleteOrphanedTransactions extends Command
if (0 === $count) {
$this->info('No orphaned transactions.');
}
}
}

View File

@@ -49,6 +49,7 @@ class DeleteZeroAmount extends Command
/**
* Execute the console command.
*
* @return int
*/
public function handle(): int
@@ -77,6 +78,8 @@ 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
{
@@ -62,28 +62,28 @@ class EnableCurrencies extends Command
/** @var Collection $meta */
$meta = AccountMeta::where('name', 'currency_id')->groupBy('data')->get(['data']);
foreach ($meta as $entry) {
$found[] = (int)$entry->data;
$found[] = (int) $entry->data;
}
// get all from journals:
/** @var Collection $journals */
$journals = TransactionJournal::groupBy('transaction_currency_id')->get(['transaction_currency_id']);
foreach ($journals as $entry) {
$found[] = (int)$entry->transaction_currency_id;
$found[] = (int) $entry->transaction_currency_id;
}
// get all from transactions
/** @var Collection $transactions */
$transactions = Transaction::groupBy('transaction_currency_id')->get(['transaction_currency_id']);
foreach ($transactions as $entry) {
$found[] = (int)$entry->transaction_currency_id;
$found[] = (int) $entry->transaction_currency_id;
}
// get all from budget limits
/** @var Collection $limits */
$limits = BudgetLimit::groupBy('transaction_currency_id')->get(['transaction_currency_id']);
foreach ($limits as $entry) {
$found[] = (int)$entry->transaction_currency_id;
$found[] = (int) $entry->transaction_currency_id;
}
$found = array_unique($found);
@@ -101,6 +101,8 @@ 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

@@ -49,20 +49,20 @@ class FixAccountTypes extends Command
* @var string
*/
protected $signature = 'firefly-iii:fix-account-types';
/** @var int */
private $count;
/** @var array */
private $expected;
/** @var AccountFactory */
private $factory;
/** @var array */
private $fixable;
/** @var int */
private $count;
/**
* Execute the console command.
*
* @return int
* @throws FireflyException
* @return int
*/
public function handle(): int
{
@@ -106,26 +106,16 @@ 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;
}
/**
* 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->count = 0;
}
/**
* @param TransactionJournal $journal
* @param string $type
* @param Transaction $source
* @param Transaction $dest
* @param string $type
* @param Transaction $source
* @param Transaction $dest
*
* @throws FireflyException
*/
private function fixJournal(TransactionJournal $journal, string $type, Transaction $source, Transaction $dest): void
@@ -167,9 +157,12 @@ class FixAccountTypes extends Command
$dest->save();
$this->info(
sprintf(
'Transaction journal #%d, destination account changed from #%d ("%s") to #%d ("%s").', $journal->id,
$oldDest->id, $oldDest->name,
$result->id, $result->name
'Transaction journal #%d, destination account changed from #%d ("%s") to #%d ("%s").',
$journal->id,
$oldDest->id,
$oldDest->name,
$result->id,
$result->name
)
);
$this->inspectJournal($journal);
@@ -184,9 +177,12 @@ class FixAccountTypes extends Command
$source->save();
$this->info(
sprintf(
'Transaction journal #%d, source account changed from #%d ("%s") to #%d ("%s").', $journal->id,
$oldSource->id, $oldSource->name,
$result->id, $result->name
'Transaction journal #%d, source account changed from #%d ("%s") to #%d ("%s").',
$journal->id,
$oldSource->id,
$oldSource->name,
$result->id,
$result->name
)
);
$this->inspectJournal($journal);
@@ -198,7 +194,6 @@ class FixAccountTypes extends Command
break;
}
}
/**
@@ -274,4 +269,15 @@ class FixAccountTypes extends Command
}
}
/**
* 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->count = 0;
}
}

View File

@@ -51,7 +51,7 @@ class FixLongDescriptions extends Command
*/
public function handle(): int
{
$start = microtime(true);
$start = microtime(true);
$journals = TransactionJournal::get(['id', 'description']);
/** @var TransactionJournal $journal */
foreach ($journals as $journal) {
@@ -73,6 +73,8 @@ 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,6 +98,7 @@ 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

@@ -51,16 +51,6 @@ class FixRecurringTransactions extends Command
/** @var UserRepositoryInterface */
private $userRepos;
/**
* Create a new command instance.
*
* @return void
*/
public function __construct()
{
parent::__construct();
}
/**
* Execute the console command.
*
@@ -76,6 +66,7 @@ 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

@@ -63,8 +63,8 @@ class FixUnevenAmount extends Command
->get(['transaction_journal_id', DB::raw('SUM(amount) AS the_sum')]);
/** @var stdClass $entry */
foreach ($journals as $entry) {
if (0 !== bccomp((string)$entry->the_sum, '0')) {
$this->fixJournal((int)$entry->transaction_journal_id);
if (0 !== bccomp((string) $entry->the_sum, '0')) {
$this->fixJournal((int) $entry->transaction_journal_id);
$count++;
}
}
@@ -75,6 +75,7 @@ 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;
}
@@ -90,11 +91,42 @@ class FixUnevenAmount extends Command
}
/** @var Transaction $source */
$source = $journal->transactions()->where('amount', '<', 0)->first();
$amount = bcmul('-1', (string)$source->amount);
if (null === $source) {
$this->error(
sprintf(
'Journal #%d ("%s") has no source transaction. It will be deleted to maintain database consistency.',
$journal->id ?? 0,
$journal->description ?? ''
)
);
Transaction::where('transaction_journal_id', $journal->id ?? 0)->forceDelete();
TransactionJournal::where('id', $journal->description ?? 0)->forceDelete();
return;
}
$amount = bcmul('-1', (string) $source->amount);
// fix amount of destination:
/** @var Transaction $destination */
$destination = $journal->transactions()->where('amount', '>', 0)->first();
$destination = $journal->transactions()->where('amount', '>', 0)->first();
if (null === $destination) {
$this->error(
sprintf(
'Journal #%d ("%s") has no destination transaction. It will be deleted to maintain database consistency.',
$journal->id ?? 0,
$journal->description ?? ''
)
);
Transaction::where('transaction_journal_id', $journal->id ?? 0)->forceDelete();
TransactionJournal::where('id', $journal->description ?? 0)->forceDelete();
return;
}
$destination->amount = $amount;
$destination->save();

View File

@@ -48,7 +48,7 @@ class RemoveBills extends Command
/**
* Execute the console command.
*
* @return mixed
* @return int
*/
public function handle(): int
{
@@ -71,6 +71,7 @@ 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,6 +83,7 @@ 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,6 +74,7 @@ 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

@@ -55,10 +55,11 @@ class CreateDatabase extends Command
{
if ('mysql' !== env('DB_CONNECTION')) {
$this->info(sprintf('CreateDB does not apply to "%s", skipped.', env('DB_CONNECTION')));
return 0;
}
// try to set up a raw connection:
$dsn = sprintf('mysql:host=%s;charset=utf8mb4', env('DB_HOST'));
$dsn = sprintf('mysql:host=%s;port=%d;charset=utf8mb4', env('DB_HOST', 'localhost'), env('DB_PORT', '3306'));
$options = [
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,

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;
/**
@@ -54,8 +55,8 @@ class DecryptDatabase extends Command
/**
* Execute the console command.
*
* @return int
* @throws FireflyException
* @return int
*/
public function handle(): int
{
@@ -92,11 +93,15 @@ class DecryptDatabase extends Command
// A separate routine for preferences:
if ('preferences' === $table) {
// try to json_decrypt the value.
$value = json_decode($value, true) ?? $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 */
$object = Preference::find((int)$id);
$object = Preference::find((int) $id);
if (null !== $object) {
$object->data = $value;
$object->save();
@@ -118,6 +123,7 @@ class DecryptDatabase extends Command
}
$this->info('Done!');
// app('telemetry')->feature('executed-command', $this->signature);
return 0;
}
@@ -131,7 +137,7 @@ class DecryptDatabase extends Command
$configName = sprintf('is_decrypted_%s', $table);
$configVar = app('fireflyconfig')->get($configName, false);
if (null !== $configVar) {
return (bool)$configVar->data;
return (bool) $configVar->data;
}
return false;
@@ -142,8 +148,9 @@ class DecryptDatabase extends Command
* Tries to decrypt data. Will only throw an exception when the MAC is invalid.
*
* @param $value
* @return string
*
* @throws FireflyException
* @return string
*/
private function tryDecrypt($value)
{

View File

@@ -22,6 +22,7 @@
namespace FireflyIII\Console\Commands\Export;
use Carbon\Carbon;
use Exception;
use FireflyIII\Console\Commands\VerifiesAccessToken;
use FireflyIII\Exceptions\FireflyException;
use FireflyIII\Models\AccountType;
@@ -32,6 +33,7 @@ use FireflyIII\User;
use Illuminate\Console\Command;
use Illuminate\Support\Collection;
use InvalidArgumentException;
use League\Csv\CannotInsertRecord;
use Log;
/**
@@ -76,21 +78,12 @@ class ExportData extends Command
/** @var User */
private $user;
/**
* Create a new command instance.
*
* @return void
*/
public function __construct()
{
parent::__construct();
}
/**
* Execute the console command.
*
* @return int
* @throws FireflyException
* @throws CannotInsertRecord
* @return int
*/
public function handle(): int
{
@@ -142,8 +135,12 @@ class ExportData extends Command
$this->exportData($options, $data);
} catch (FireflyException $e) {
$this->error(sprintf('Could not store data: %s', $e->getMessage()));
// app('telemetry')->feature('executed-command-with-error', $this->signature);
return 1;
}
// app('telemetry')->feature('executed-command', $this->signature);
return 0;
}
@@ -171,8 +168,8 @@ class ExportData extends Command
}
/**
* @return Collection
* @throws FireflyException
* @return Collection
*/
private function getAccountsParameter(): Collection
{
@@ -180,7 +177,7 @@ class ExportData extends Command
$accounts = new Collection;
$accountList = $this->option('accounts');
$types = [AccountType::ASSET, AccountType::LOAN, AccountType::DEBT, AccountType::MORTGAGE];
if (null !== $accountList && '' !== (string)$accountList) {
if (null !== $accountList && '' !== (string) $accountList) {
$accountIds = explode(',', $accountList);
$accounts = $this->accountRepository->getAccountsById($accountIds);
}
@@ -204,8 +201,9 @@ class ExportData extends Command
/**
* @param string $field
*
* @return Carbon
* @throws FireflyException
* @throws Exception
* @return Carbon
*/
private function getDateParameter(string $field): Carbon
{
@@ -239,12 +237,13 @@ class ExportData extends Command
}
/**
* @return string
* @throws FireflyException
*
* @return string
*/
private function getExportDirectory(): string
{
$directory = $this->option('export_directory');
$directory = (string) $this->option('export_directory');
if (null === $directory) {
$directory = './';
}
@@ -256,8 +255,8 @@ class ExportData extends Command
}
/**
* @return array
* @throws FireflyException
* @return array
*/
private function parseOptions(): array
{

View File

@@ -39,6 +39,9 @@ use Log;
/**
* Class CreateCSVImport.
*
* @deprecated
* @codeCoverageIgnore
*/
class CreateCSVImport extends Command
{
@@ -60,12 +63,12 @@ class CreateCSVImport extends Command
{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 UserRepositoryInterface */
private $userRepository;
/** @var ImportJobRepositoryInterface */
private $importRepository;
/** @var ImportJob */
private $importJob;
/** @var ImportJobRepositoryInterface */
private $importRepository;
/** @var UserRepositoryInterface */
private $userRepository;
/**
* Run the command.
@@ -87,13 +90,13 @@ class CreateCSVImport extends Command
}
// @codeCoverageIgnoreEnd
/** @var User $user */
$user = $this->userRepository->findNull((int)$this->option('user'));
$file = (string)$this->argument('file');
$configuration = (string)$this->argument('configuration');
$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);
$configurationData = json_decode(file_get_contents($configuration), true, 512, JSON_THROW_ON_ERROR);
$this->importJob = $this->importRepository->create('file');
@@ -125,6 +128,7 @@ class CreateCSVImport extends Command
} catch (FireflyException $e) {
$this->errorLine($e->getMessage());
// app('telemetry')->feature('executed-command-with-error', $this->signature);
return 1;
}
@@ -134,6 +138,7 @@ class CreateCSVImport extends Command
} catch (FireflyException $e) {
$this->errorLine($e->getMessage());
// app('telemetry')->feature('executed-command-with-error', $this->signature);
return 1;
}
@@ -143,25 +148,14 @@ class CreateCSVImport extends Command
// clear cache for user:
app('preferences')->setForUser($user, 'lastActivity', microtime());
// app('telemetry')->feature('executed-command', $this->signature);
return 0;
}
/**
* 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);
}
/**
* @param string $message
* @param string $message
* @param array|null $data
*
* @codeCoverageIgnore
*/
private function errorLine(string $message, array $data = null): void
@@ -171,9 +165,34 @@ class CreateCSVImport extends Command
}
/**
*
*/
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
* @param array $data
*
* @codeCoverageIgnore
*/
private function infoLine(string $message, array $data = null): void
@@ -182,65 +201,6 @@ class CreateCSVImport extends Command
$this->line($message);
}
/**
* 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);
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;
}
/**
* 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());
}
}
}
/**
* Keep repeating import call until job lands on "provider_finished".
*
@@ -307,26 +267,75 @@ class CreateCSVImport extends Command
}
/**
* Store the supplied file as an attachment to this job.
*
* @param string $file
*
* @throws FireflyException
*/
private function giveFeedback(): void
private function storeFile(string $file): 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);
// 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,6 +64,7 @@ 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

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

View File

@@ -54,6 +54,7 @@ class ReportSum extends Command
{
$this->reportSum();
// app('telemetry')->feature('executed-command', $this->signature);
return 0;
}
@@ -69,7 +70,7 @@ class ReportSum extends Command
/** @var User $user */
foreach ($userRepository->all() as $user) {
$sum = (string)$user->transactions()->sum('amount');
$sum = (string) $user->transactions()->sum('amount');
if (0 !== bccomp($sum, '0')) {
$message = sprintf('Error: Transactions for user #%d (%s) are off by %s!', $user->id, $user->email, $sum);
$this->error($message);

View File

@@ -21,8 +21,6 @@
namespace FireflyIII\Console\Commands\Integrity;
use Artisan;
use Crypt;
use FireflyIII\Support\System\OAuthKeys;
use Illuminate\Console\Command;
@@ -53,6 +51,7 @@ class RestoreOAuthKeys extends Command
{
$this->restoreOAuthKeys();
// app('telemetry')->feature('executed-command', $this->signature);
return 0;
}
@@ -122,4 +121,4 @@ class RestoreOAuthKeys extends Command
{
OAuthKeys::storeKeysInDB();
}
}
}

View File

@@ -63,8 +63,7 @@ class ScanAttachments extends Command
$disk = Storage::disk('upload');
/** @var Attachment $attachment */
foreach ($attachments as $attachment) {
$fileName = $attachment->fileName();
$decryptedContent = '';
$fileName = $attachment->fileName();
try {
$encryptedContent = $disk->get($fileName);
} catch (FileNotFoundException $e) {
@@ -87,6 +86,7 @@ class ScanAttachments extends Command
$this->line(sprintf('Fixed attachment #%d', $attachment->id));
}
// app('telemetry')->feature('executed-command', $this->signature);
return 0;
}
}

View File

@@ -1,5 +1,5 @@
<?php
declare(strict_types=1);
/**
* SetLatestVersion.php
@@ -25,6 +25,9 @@ namespace FireflyIII\Console\Commands;
use Illuminate\Console\Command;
/**
* Class SetLatestVersion
*/
class SetLatestVersion extends Command
{
/**
@@ -32,7 +35,7 @@ class SetLatestVersion extends Command
*
* @var string
*/
protected $description = 'Command description';
protected $description = 'Set latest version in DB.';
/**
* The name and signature of the console command.
*
@@ -40,32 +43,24 @@ class SetLatestVersion extends Command
*/
protected $signature = 'firefly-iii:set-latest-version {--james-is-cool}';
/**
* Create a new command instance.
*
* @return void
*/
public function __construct()
{
parent::__construct();
}
/**
* Execute the console command.
*
* @return mixed
* @return int
*/
public function handle()
public function handle(): int
{
if (!$this->option('james-is-cool')) {
$this->error('Am too!');
return;
return 0;
}
app('fireflyconfig')->set('db_version', config('firefly.db_version'));
app('fireflyconfig')->set('ff3_version', config('firefly.version'));
$this->line('Updated version.');
// app('telemetry')->feature('executed-command', $this->signature);
return 0;
}
}

View File

@@ -68,35 +68,32 @@ class ApplyRules extends Command
{--all_rules : If set, will overrule both settings and simply apply ALL of your rules.}
{--start_date= : The date of the earliest transaction to be included (inclusive). If omitted, will be your very first transaction ever. Format: YYYY-MM-DD}
{--end_date= : The date of the latest transaction to be included (inclusive). If omitted, will be your latest transaction ever. Format: YYYY-MM-DD}';
/** @var Collection */
private $accounts;
/** @var array */
private $acceptedAccounts;
/** @var Collection */
private $accounts;
/** @var bool */
private $allRules;
/** @var Carbon */
private $endDate;
/** @var Collection */
private $groups;
/** @var RuleGroupRepositoryInterface */
private $ruleGroupRepository;
/** @var array */
private $ruleGroupSelection;
/** @var RuleRepositoryInterface */
private $ruleRepository;
/** @var array */
private $ruleSelection;
/** @var Carbon */
private $startDate;
/** @var Collection */
private $groups;
/** @var bool */
private $allRules;
/** @var RuleRepositoryInterface */
private $ruleRepository;
/** @var RuleGroupRepositoryInterface */
private $ruleGroupRepository;
/**
* Execute the console command.
*
* @return int
* @throws FireflyException
* @return int
*/
public function handle(): int
{
@@ -115,6 +112,7 @@ class ApplyRules extends Command
$result = $this->verifyInput();
if (false === $result) {
// app('telemetry')->feature('executed-command-with-error', $this->signature);
return 1;
}
@@ -132,6 +130,9 @@ class ApplyRules extends Command
$this->warn(' --rules=1,2,...');
$this->warn(' --rule_groups=1,2,...');
$this->warn(' --all_rules');
// app('telemetry')->feature('executed-command-with-error', $this->signature);
return 1;
}
/** @var GroupCollectorInterface $collector */
@@ -166,9 +167,53 @@ class ApplyRules extends Command
$this->line('');
$this->line('Done!');
// app('telemetry')->feature('executed-command', $this->signature);
return 0;
}
/**
* @return array
*/
private function getRulesToApply(): array
{
$rulesToApply = [];
/** @var RuleGroup $group */
foreach ($this->groups as $group) {
$rules = $this->ruleGroupRepository->getActiveStoreRules($group);
/** @var Rule $rule */
foreach ($rules as $rule) {
// if in rule selection, or group in selection or all rules, it's included.
$test = $this->includeRule($rule, $group);
if (true === $test) {
Log::debug(sprintf('Will include rule #%d "%s"', $rule->id, $rule->title));
$rulesToApply[] = $rule->id;
}
}
}
return $rulesToApply;
}
/**
*/
private function grabAllRules(): void
{
$this->groups = $this->ruleGroupRepository->getActiveGroups();
}
/**
* @param Rule $rule
* @param RuleGroup $group
*
* @return bool
*/
private function includeRule(Rule $rule, RuleGroup $group): bool
{
return in_array($group->id, $this->ruleGroupSelection, true)
|| in_array($rule->id, $this->ruleSelection, true)
|| $this->allRules;
}
/**
* 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
@@ -189,8 +234,8 @@ class ApplyRules extends Command
}
/**
* @return bool
* @throws FireflyException
* @return bool
*/
private function verifyInput(): bool
{
@@ -212,8 +257,8 @@ class ApplyRules extends Command
}
/**
* @return bool
* @throws FireflyException
* @return bool
*/
private function verifyInputAccounts(): bool
{
@@ -240,7 +285,7 @@ class ApplyRules extends Command
foreach ($accountList as $accountId) {
$accountId = (int)$accountId;
$accountId = (int) $accountId;
$account = $accountRepository->findNull($accountId);
if (null !== $account && in_array($account->accountType->type, $this->acceptedAccounts, true)) {
$finalList->push($account);
@@ -258,66 +303,6 @@ class ApplyRules extends Command
}
/**
* @return bool
*/
private function verifyInputRuleGroups(): bool
{
$ruleGroupString = $this->option('rule_groups');
if (null === $ruleGroupString || '' === $ruleGroupString) {
// can be empty.
return true;
}
$ruleGroupList = explode(',', $ruleGroupString);
// @codeCoverageIgnoreStart
if (0 === count($ruleGroupList)) {
// can be empty.
return true;
}
// @codeCoverageIgnoreEnd
foreach ($ruleGroupList as $ruleGroupId) {
$ruleGroup = $this->ruleGroupRepository->find((int)$ruleGroupId);
if ($ruleGroup->active) {
$this->ruleGroupSelection[] = $ruleGroup->id;
}
if (false === $ruleGroup->active) {
$this->warn(sprintf('Will ignore inactive rule group #%d ("%s")', $ruleGroup->id, $ruleGroup->title));
}
}
return true;
}
/**
* @return bool
*/
private function verifyInputRules(): bool
{
$ruleString = $this->option('rules');
if (null === $ruleString || '' === $ruleString) {
// can be empty.
return true;
}
$ruleList = explode(',', $ruleString);
// @codeCoverageIgnoreStart
if (0 === count($ruleList)) {
// can be empty.
return true;
}
// @codeCoverageIgnoreEnd
foreach ($ruleList as $ruleId) {
$rule = $this->ruleRepository->find((int)$ruleId);
if (null !== $rule && $rule->active) {
$this->ruleSelection[] = $rule->id;
}
}
return true;
}
/**
* @throws FireflyException
*/
@@ -355,44 +340,62 @@ class ApplyRules extends Command
}
/**
*/
private function grabAllRules(): void
{
$this->groups = $this->ruleGroupRepository->getActiveGroups();
}
/**
* @param Rule $rule
* @param RuleGroup $group
* @return bool
*/
private function includeRule(Rule $rule, RuleGroup $group): bool
private function verifyInputRuleGroups(): bool
{
return in_array($group->id, $this->ruleGroupSelection, true) ||
in_array($rule->id, $this->ruleSelection, true) ||
$this->allRules;
}
/**
* @return array
*/
private function getRulesToApply(): array
{
$rulesToApply = [];
/** @var RuleGroup $group */
foreach ($this->groups as $group) {
$rules = $this->ruleGroupRepository->getActiveStoreRules($group);
/** @var Rule $rule */
foreach ($rules as $rule) {
// if in rule selection, or group in selection or all rules, it's included.
$test = $this->includeRule($rule, $group);
if (true === $test) {
Log::debug(sprintf('Will include rule #%d "%s"', $rule->id, $rule->title));
$rulesToApply[] = $rule->id;
}
$ruleGroupString = $this->option('rule_groups');
if (null === $ruleGroupString || '' === $ruleGroupString) {
// can be empty.
return true;
}
$ruleGroupList = explode(',', $ruleGroupString);
// @codeCoverageIgnoreStart
if (0 === count($ruleGroupList)) {
// can be empty.
return true;
}
// @codeCoverageIgnoreEnd
foreach ($ruleGroupList as $ruleGroupId) {
$ruleGroup = $this->ruleGroupRepository->find((int) $ruleGroupId);
if ($ruleGroup->active) {
$this->ruleGroupSelection[] = $ruleGroup->id;
}
if (false === $ruleGroup->active) {
$this->warn(sprintf('Will ignore inactive rule group #%d ("%s")', $ruleGroup->id, $ruleGroup->title));
}
}
return $rulesToApply;
return true;
}
/**
* @return bool
*/
private function verifyInputRules(): bool
{
$ruleString = $this->option('rules');
if (null === $ruleString || '' === $ruleString) {
// can be empty.
return true;
}
$ruleList = explode(',', $ruleString);
// @codeCoverageIgnoreStart
if (0 === count($ruleList)) {
// can be empty.
return true;
}
// @codeCoverageIgnoreEnd
foreach ($ruleList as $ruleId) {
$rule = $this->ruleRepository->find((int) $ruleId);
if (null !== $rule && $rule->active) {
$this->ruleSelection[] = $rule->id;
}
}
return true;
}
}

View File

@@ -27,9 +27,12 @@ namespace FireflyIII\Console\Commands\Tools;
use Carbon\Carbon;
use Exception;
use FireflyIII\Exceptions\FireflyException;
use FireflyIII\Support\Cronjobs\AutoBudgetCronjob;
use FireflyIII\Support\Cronjobs\RecurringCronjob;
use FireflyIII\Support\Cronjobs\TelemetryCronjob;
use Illuminate\Console\Command;
use InvalidArgumentException;
use Log;
/**
* Class Cron
@@ -56,45 +59,137 @@ class Cron extends Command
/**
* @return int
* @throws Exception
*/
public function handle(): int
{
$date = null;
try {
$date = new Carbon($this->option('date'));
} catch (InvalidArgumentException $e) {
} catch (InvalidArgumentException|Exception $e) {
$this->error(sprintf('"%s" is not a valid date', $this->option('date')));
$e->getMessage();
}
$force = (bool) $this->option('force');
/*
* Fire recurring transaction cron job.
*/
try {
$this->recurringCronJob($force, $date);
} catch (FireflyException $e) {
Log::error($e->getMessage());
Log::error($e->getTraceAsString());
$this->error($e->getMessage());
}
/*
* Fire auto-budget cron job:
*/
try {
$this->autoBudgetCronJob($force, $date);
} catch (FireflyException $e) {
Log::error($e->getMessage());
Log::error($e->getTraceAsString());
$this->error($e->getMessage());
}
/*
* Fire telemetry cron job (disabled):
*/
try {
//$this->telemetryCronJob($force, $date);
} catch (FireflyException $e) {
Log::error($e->getMessage());
Log::error($e->getTraceAsString());
$this->error($e->getMessage());
}
$this->info('More feedback on the cron jobs can be found in the log files.');
// app('telemetry')->feature('executed-command', $this->signature);
return 0;
}
/**
* @param bool $force
* @param Carbon|null $date
*
* @throws FireflyException
* @throws Exception
*/
private function autoBudgetCronJob(bool $force, ?Carbon $date): void
{
$autoBudget = new AutoBudgetCronjob;
$autoBudget->setForce($force);
// set date in cron job:
if (null !== $date) {
$autoBudget->setDate($date);
}
$result = $autoBudget->fire();
if (false === $result) {
$this->line('The auto budget cron job did not fire.');
}
if (true === $result) {
$this->line('The auto budget cron job fired successfully.');
}
}
/**
* @param bool $force
* @param Carbon|null $date
*
* @throws FireflyException
*/
private function recurringCronJob(bool $force, ?Carbon $date): void
{
$recurring = new RecurringCronjob;
$recurring->setForce($this->option('force'));
$recurring->setForce($force);
// set date in cron job:
if (null !== $date) {
$recurring->setDate($date);
}
try {
$result = $recurring->fire();
} catch (FireflyException $e) {
$this->error($e->getMessage());
$result = $recurring->fire();
return 0;
}
if (false === $result) {
$this->line('The recurring transaction cron job did not fire.');
}
if (true === $result) {
$this->line('The recurring transaction cron job fired successfully.');
}
$this->info('More feedback on the cron jobs can be found in the log files.');
return 0;
}
/**
* @param bool $force
* @param Carbon|null $date
*/
private function telemetryCronJob(bool $force, ?Carbon $date): void
{
if (false === config('firefly.send_telemetry') || false === config('firefly.feature_flags.telemetry')) {
// if not configured to do anything with telemetry, do nothing.
return;
}
$telemetry = new TelemetryCronJob;
$telemetry->setForce($force);
// set date in cron job:
if (null !== $date) {
$telemetry->setDate($date);
}
$result = $telemetry->fire();
if (false === $result) {
$this->line('The telemetry cron job did not fire.');
}
if (true === $result) {
$this->line('The telemetry cron job fired successfully.');
}
}
}

View File

@@ -54,10 +54,10 @@ class AccountCurrencies extends Command
protected $signature = 'firefly-iii:account-currencies {--F|force : Force the execution of this command.}';
/** @var AccountRepositoryInterface */
private $accountRepos;
/** @var UserRepositoryInterface */
private $userRepos;
/** @var int */
private $count;
/** @var UserRepositoryInterface */
private $userRepos;
/**
* Each (asset) account must have a reference to a preferred currency. If the account does not have one, it's forced upon the account.
@@ -87,9 +87,32 @@ 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;
}
/**
* @return bool
*/
private function isExecuted(): bool
{
$configVar = app('fireflyconfig')->get(self::CONFIG_NAME, false);
if (null !== $configVar) {
return (bool) $configVar->data;
}
return false; // @codeCoverageIgnore
}
/**
*
*/
private function markAsExecuted(): void
{
app('fireflyconfig')->set(self::CONFIG_NAME, true);
}
/**
* 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
@@ -105,29 +128,7 @@ class AccountCurrencies extends Command
}
/**
* @return bool
*/
private function isExecuted(): bool
{
$configVar = app('fireflyconfig')->get(self::CONFIG_NAME, false);
if (null !== $configVar) {
return (bool)$configVar->data;
}
return false; // @codeCoverageIgnore
}
/**
*
*/
private function markAsExecuted(): void
{
app('fireflyconfig')->set(self::CONFIG_NAME, true);
}
/**
* @param Account $account
* @param Account $account
* @param TransactionCurrency $currency
*/
private function updateAccount(Account $account, TransactionCurrency $currency): void
@@ -135,13 +136,13 @@ class AccountCurrencies extends Command
Log::debug(sprintf('Now in updateAccount(%d, %s)', $account->id, $currency->code));
$this->accountRepos->setUser($account->user);
$accountCurrency = (int)$this->accountRepos->getMetaValue($account, 'currency_id');
$accountCurrency = (int) $this->accountRepos->getMetaValue($account, 'currency_id');
Log::debug(sprintf('Account currency is #%d', $accountCurrency));
$openingBalance = $this->accountRepos->getOpeningBalance($account);
$obCurrency = 0;
$openingBalance = $this->accountRepos->getOpeningBalance($account);
$obCurrency = 0;
if (null !== $openingBalance) {
$obCurrency = (int)$openingBalance->transaction_currency_id;
$obCurrency = (int) $openingBalance->transaction_currency_id;
Log::debug('Account has opening balance.');
}
Log::debug(sprintf('Account OB currency is #%d.', $obCurrency));
@@ -178,7 +179,8 @@ class AccountCurrencies extends Command
static function (Transaction $transaction) use ($accountCurrency) {
$transaction->transaction_currency_id = $accountCurrency;
$transaction->save();
});
}
);
$this->line(sprintf('Account #%d ("%s") now has a correct currency for opening balance.', $account->id, $account->name));
$this->count++;
@@ -194,7 +196,7 @@ class AccountCurrencies extends Command
{
Log::debug('Now in updateAccountCurrencies()');
$users = $this->userRepos->all();
$defaultCurrencyCode = (string)config('firefly.default_currency', 'EUR');
$defaultCurrencyCode = (string) config('firefly.default_currency', 'EUR');
Log::debug(sprintf('Default currency is %s', $defaultCurrencyCode));
foreach ($users as $user) {
$this->updateCurrenciesForUser($user, $defaultCurrencyCode);
@@ -202,7 +204,7 @@ class AccountCurrencies extends Command
}
/**
* @param User $user
* @param User $user
* @param string $systemCurrencyCode
*/
private function updateCurrenciesForUser(User $user, string $systemCurrencyCode): void

View File

@@ -78,6 +78,8 @@ 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;
}
@@ -111,9 +113,9 @@ class BackToJournals extends Command
$chunks = array_chunk($transactions, 500);
foreach ($chunks as $chunk) {
$set = DB::table('transactions')
->whereIn('transactions.id', $chunk)
->get(['transaction_journal_id'])->pluck('transaction_journal_id')->toArray();
$set = DB::table('transactions')
->whereIn('transactions.id', $chunk)
->get(['transaction_journal_id'])->pluck('transaction_journal_id')->toArray();
/** @noinspection SlowArrayOperationsInLoopInspection */
$array = array_merge($array, $set);
}
@@ -128,7 +130,7 @@ class BackToJournals extends Command
{
$configVar = app('fireflyconfig')->get(self::CONFIG_NAME, false);
if (null !== $configVar) {
return (bool)$configVar->data;
return (bool) $configVar->data;
}
return false; // @codeCoverageIgnore
@@ -141,7 +143,7 @@ class BackToJournals extends Command
{
$configVar = app('fireflyconfig')->get(MigrateToGroups::CONFIG_NAME, false);
if (null !== $configVar) {
return (bool)$configVar->data;
return (bool) $configVar->data;
}
return false; // @codeCoverageIgnore
@@ -212,7 +214,7 @@ class BackToJournals extends Command
// both have a budget, but they don't match.
if (null !== $budget && null !== $journalBudget && $budget->id !== $journalBudget->id) {
// sync to journal:
$journal->budgets()->sync([(int)$budget->id]);
$journal->budgets()->sync([(int) $budget->id]);
return;
}
@@ -220,7 +222,7 @@ class BackToJournals extends Command
// transaction has a budget, but the journal doesn't.
if (null !== $budget && null === $journalBudget) {
// sync to journal:
$journal->budgets()->sync([(int)$budget->id]);
$journal->budgets()->sync([(int) $budget->id]);
}
}
@@ -271,12 +273,12 @@ class BackToJournals extends Command
// both have a category, but they don't match.
if (null !== $category && null !== $journalCategory && $category->id !== $journalCategory->id) {
// sync to journal:
$journal->categories()->sync([(int)$category->id]);
$journal->categories()->sync([(int) $category->id]);
}
// transaction has a category, but the journal doesn't.
if (null !== $category && null === $journalCategory) {
$journal->categories()->sync([(int)$category->id]);
$journal->categories()->sync([(int) $category->id]);
}
}
}

View File

@@ -92,6 +92,8 @@ class BudgetLimitCurrency extends Command
$this->markAsExecuted();
// app('telemetry')->feature('executed-command', $this->signature);
return 0;
}
@@ -102,7 +104,7 @@ class BudgetLimitCurrency extends Command
{
$configVar = app('fireflyconfig')->get(self::CONFIG_NAME, false);
if (null !== $configVar) {
return (bool)$configVar->data;
return (bool) $configVar->data;
}
return false; // @codeCoverageIgnore

View File

@@ -91,6 +91,8 @@ 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;
}
@@ -101,7 +103,7 @@ class CCLiabilities extends Command
{
$configVar = app('fireflyconfig')->get(self::CONFIG_NAME, false);
if (null !== $configVar) {
return (bool)$configVar->data;
return (bool) $configVar->data;
}
return false; // @codeCoverageIgnore

View File

@@ -71,7 +71,7 @@ class MigrateAttachments extends Command
foreach ($attachments as $att) {
// move description:
$description = (string)$att->description;
$description = (string) $att->description;
if ('' !== $description) {
// find or create note:
@@ -101,6 +101,8 @@ 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;
}
@@ -111,7 +113,7 @@ class MigrateAttachments extends Command
{
$configVar = app('fireflyconfig')->get(self::CONFIG_NAME, false);
if (null !== $configVar) {
return (bool)$configVar->data;
return (bool) $configVar->data;
}
return false; // @codeCoverageIgnore

View File

@@ -100,6 +100,8 @@ class MigrateJournalNotes extends Command
$this->info(sprintf('Migrated notes in %s seconds.', $end));
$this->markAsExecuted();
// app('telemetry')->feature('executed-command', $this->signature);
return 0;
}
@@ -110,7 +112,7 @@ class MigrateJournalNotes extends Command
{
$configVar = app('fireflyconfig')->get(self::CONFIG_NAME, false);
if (null !== $configVar) {
return (bool)$configVar->data;
return (bool) $configVar->data;
}
return false; // @codeCoverageIgnore

View File

@@ -71,6 +71,8 @@ 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;
}
@@ -81,7 +83,7 @@ class MigrateRecurrenceMeta extends Command
{
$configVar = app('fireflyconfig')->get(self::CONFIG_NAME, false);
if (null !== $configVar) {
return (bool)$configVar->data;
return (bool) $configVar->data;
}
return false; // @codeCoverageIgnore
@@ -103,7 +105,7 @@ class MigrateRecurrenceMeta extends Command
*/
private function migrateEntry(RecurrenceMeta $meta): int
{
$recurrence = $meta->recurrence;
$recurrence = $meta->recurrence;
if (null === $recurrence) {
return 0;
}
@@ -115,7 +117,7 @@ class MigrateRecurrenceMeta extends Command
if ('tags' === $meta->name) {
$array = explode(',', $meta->value);
$value = json_encode($array);
$value = json_encode($array, JSON_THROW_ON_ERROR, 512);
}
RecurrenceTransactionMeta::create(

View File

@@ -64,6 +64,7 @@ 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;
}
@@ -84,7 +85,7 @@ class MigrateTagLocations extends Command
{
$configVar = app('fireflyconfig')->get(self::CONFIG_NAME, false);
if (null !== $configVar) {
return (bool)$configVar->data;
return (bool) $configVar->data;
}
return false; // @codeCoverageIgnore

View File

@@ -59,21 +59,21 @@ class MigrateToGroups extends Command
* @var string
*/
protected $signature = 'firefly-iii:migrate-to-groups {--F|force : Force the migration, even if it fired before.}';
/** @var JournalCLIRepositoryInterface */
private $cliRepository;
private $count;
/** @var TransactionGroupFactory */
private $groupFactory;
/** @var JournalRepositoryInterface */
private $journalRepository;
/** @var JournalCLIRepositoryInterface */
private $cliRepository;
/** @var JournalDestroyService */
private $service;
private $count;
/**
* Execute the console command.
*
* @return int
* @throws Exception
* @return int
*/
public function handle(): int
{
@@ -112,29 +112,14 @@ class MigrateToGroups extends Command
$this->markAsMigrated();
// app('telemetry')->feature('executed-command', $this->signature);
return 0;
}
/**
* 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->count = 0;
$this->journalRepository = app(JournalRepositoryInterface::class);
$this->service = app(JournalDestroyService::class);
$this->groupFactory = app(TransactionGroupFactory::class);
$this->cliRepository = app(JournalCLIRepositoryInterface::class);
}
/**
* @param TransactionJournal $journal
* @param Transaction $transaction
* @param Transaction $transaction
*
* @return Transaction|null
*/
@@ -142,7 +127,7 @@ class MigrateToGroups extends Command
{
$set = $journal->transactions->filter(
static function (Transaction $subject) use ($transaction) {
$amount = (float)$transaction->amount * -1 === (float)$subject->amount;
$amount = (float) $transaction->amount * -1 === (float) $subject->amount;
$identifier = $transaction->identifier === $subject->identifier;
Log::debug(sprintf('Amount the same? %s', var_export($amount, true)));
Log::debug(sprintf('ID the same? %s', var_export($identifier, true)));
@@ -168,6 +153,72 @@ class MigrateToGroups extends Command
);
}
/**
* @param Transaction $left
* @param Transaction $right
*
* @return int|null
*/
private function getTransactionBudget(Transaction $left, Transaction $right): ?int
{
Log::debug('Now in getTransactionBudget()');
// try to get a budget ID from the left transaction:
/** @var Budget $budget */
$budget = $left->budgets()->first();
if (null !== $budget) {
Log::debug(sprintf('Return budget #%d, from transaction #%d', $budget->id, $left->id));
return (int) $budget->id;
}
// try to get a budget ID from the right transaction:
/** @var Budget $budget */
$budget = $right->budgets()->first();
if (null !== $budget) {
Log::debug(sprintf('Return budget #%d, from transaction #%d', $budget->id, $right->id));
return (int) $budget->id;
}
Log::debug('Neither left or right have a budget, return NULL');
// if all fails, return NULL.
return null;
}
/**
* @param Transaction $left
* @param Transaction $right
*
* @return int|null
*/
private function getTransactionCategory(Transaction $left, Transaction $right): ?int
{
Log::debug('Now in getTransactionCategory()');
// try to get a category ID from the left transaction:
/** @var Category $category */
$category = $left->categories()->first();
if (null !== $category) {
Log::debug(sprintf('Return category #%d, from transaction #%d', $category->id, $left->id));
return (int) $category->id;
}
// try to get a category ID from the left transaction:
/** @var Category $category */
$category = $right->categories()->first();
if (null !== $category) {
Log::debug(sprintf('Return category #%d, from transaction #%d', $category->id, $category->id));
return (int) $category->id;
}
Log::debug('Neither left or right have a category, return NULL');
// if all fails, return NULL.
return null;
}
/**
* @param array $array
*/
@@ -192,7 +243,7 @@ class MigrateToGroups extends Command
{
$configVar = app('fireflyconfig')->get(self::CONFIG_NAME, false);
if (null !== $configVar) {
return (bool)$configVar->data;
return (bool) $configVar->data;
}
return false; // @codeCoverageIgnore
@@ -302,7 +353,8 @@ class MigrateToGroups extends Command
$this->error(
sprintf(
'Journal #%d has no opposing transaction for transaction #%d. Cannot upgrade this entry.',
$journal->id, $transaction->id
$journal->id,
$transaction->id
)
);
continue;
@@ -365,81 +417,23 @@ class MigrateToGroups extends Command
// report on result:
Log::debug(
sprintf('Migrated journal #%d into group #%d with these journals: #%s',
$journal->id, $group->id, implode(', #', $group->transactionJournals->pluck('id')->toArray()))
sprintf(
'Migrated journal #%d into group #%d with these journals: #%s',
$journal->id,
$group->id,
implode(', #', $group->transactionJournals->pluck('id')->toArray())
)
);
$this->line(
sprintf('Migrated journal #%d into group #%d with these journals: #%s',
$journal->id, $group->id, implode(', #', $group->transactionJournals->pluck('id')->toArray()))
sprintf(
'Migrated journal #%d into group #%d with these journals: #%s',
$journal->id,
$group->id,
implode(', #', $group->transactionJournals->pluck('id')->toArray())
)
);
}
/**
* @param Transaction $left
* @param Transaction $right
*
* @return int|null
*/
private function getTransactionBudget(Transaction $left, Transaction $right): ?int
{
Log::debug('Now in getTransactionBudget()');
// try to get a budget ID from the left transaction:
/** @var Budget $budget */
$budget = $left->budgets()->first();
if (null !== $budget) {
Log::debug(sprintf('Return budget #%d, from transaction #%d', $budget->id, $left->id));
return (int)$budget->id;
}
// try to get a budget ID from the right transaction:
/** @var Budget $budget */
$budget = $right->budgets()->first();
if (null !== $budget) {
Log::debug(sprintf('Return budget #%d, from transaction #%d', $budget->id, $right->id));
return (int)$budget->id;
}
Log::debug('Neither left or right have a budget, return NULL');
// if all fails, return NULL.
return null;
}
/**
* @param Transaction $left
* @param Transaction $right
*
* @return int|null
*/
private function getTransactionCategory(Transaction $left, Transaction $right): ?int
{
Log::debug('Now in getTransactionCategory()');
// try to get a category ID from the left transaction:
/** @var Category $category */
$category = $left->categories()->first();
if (null !== $category) {
Log::debug(sprintf('Return category #%d, from transaction #%d', $category->id, $left->id));
return (int)$category->id;
}
// try to get a category ID from the left transaction:
/** @var Category $category */
$category = $right->categories()->first();
if (null !== $category) {
Log::debug(sprintf('Return category #%d, from transaction #%d', $category->id, $category->id));
return (int)$category->id;
}
Log::debug('Neither left or right have a category, return NULL');
// if all fails, return NULL.
return null;
}
/**
*
*/
@@ -448,4 +442,19 @@ class MigrateToGroups extends Command
app('fireflyconfig')->set(self::CONFIG_NAME, true);
}
/**
* 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->count = 0;
$this->journalRepository = app(JournalRepositoryInterface::class);
$this->service = app(JournalDestroyService::class);
$this->groupFactory = app(TransactionGroupFactory::class);
$this->cliRepository = app(JournalCLIRepositoryInterface::class);
}
}

View File

@@ -53,22 +53,21 @@ class MigrateToRules extends Command
* @var string
*/
protected $signature = 'firefly-iii:bills-to-rules {--F|force : Force the execution of this command.}';
/** @var UserRepositoryInterface */
private $userRepository;
/** @var RuleGroupRepositoryInterface */
private $ruleGroupRepository;
/** @var BillRepositoryInterface */
private $billRepository;
private $count;
/** @var RuleGroupRepositoryInterface */
private $ruleGroupRepository;
/** @var RuleRepositoryInterface */
private $ruleRepository;
private $count;
/** @var UserRepositoryInterface */
private $userRepository;
/**
* Execute the console command.
*
* @return int
* @throws FireflyException
* @return int
*/
public function handle(): int
{
@@ -100,25 +99,10 @@ 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;
}
/**
* 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->count = 0;
$this->userRepository = app(UserRepositoryInterface::class);
$this->ruleGroupRepository = app(RuleGroupRepositoryInterface::class);
$this->billRepository = app(BillRepositoryInterface::class);
$this->ruleRepository = app(RuleRepositoryInterface::class);
}
/**
* @return bool
*/
@@ -126,7 +110,7 @@ class MigrateToRules extends Command
{
$configVar = app('fireflyconfig')->get(self::CONFIG_NAME, false);
if (null !== $configVar) {
return (bool)$configVar->data;
return (bool) $configVar->data;
}
return false; // @codeCoverageIgnore
@@ -141,45 +125,9 @@ class MigrateToRules extends Command
}
/**
* Migrate bills to new rule structure for a specific user.
*
* @param User $user
* @throws FireflyException
*/
private function migrateUser(User $user): void
{
$this->ruleGroupRepository->setUser($user);
$this->billRepository->setUser($user);
$this->ruleRepository->setUser($user);
/** @var Preference $lang */
$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(
[
'title' => (string)trans('firefly.rulegroup_for_bills_title', [], $lang->data),
'description' => (string)trans('firefly.rulegroup_for_bills_description', [], $lang->data),
'active' => true,
]
);
}
$bills = $this->billRepository->getBills();
/** @var Bill $bill */
foreach ($bills as $bill) {
$this->migrateBill($ruleGroup, $bill, $lang);
}
}
/**
* @param RuleGroup $ruleGroup
* @param Bill $bill
* @throws FireflyException
* @param RuleGroup $ruleGroup
* @param Bill $bill
* @param Preference $language
*/
private function migrateBill(RuleGroup $ruleGroup, Bill $bill, Preference $language): void
{
@@ -194,8 +142,8 @@ class MigrateToRules extends Command
'active' => true,
'strict' => false,
'stop_processing' => false, // field is no longer used.
'title' => (string)trans('firefly.rule_for_bill_title', ['name' => $bill->name], $language->data),
'description' => (string)trans('firefly.rule_for_bill_description', ['name' => $bill->name], $language->data),
'title' => (string) trans('firefly.rule_for_bill_title', ['name' => $bill->name], $language->data),
'description' => (string) trans('firefly.rule_for_bill_description', ['name' => $bill->name], $language->data),
'trigger' => 'store-journal',
'triggers' => [
[
@@ -246,4 +194,57 @@ class MigrateToRules extends Command
$this->billRepository->update($bill, $newBillData);
$this->count++;
}
/**
* Migrate bills to new rule structure for a specific user.
*
* @param User $user
*
* @throws FireflyException
*/
private function migrateUser(User $user): void
{
$this->ruleGroupRepository->setUser($user);
$this->billRepository->setUser($user);
$this->ruleRepository->setUser($user);
/** @var Preference $lang */
$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(
[
'title' => (string) trans('firefly.rulegroup_for_bills_title', [], $lang->data),
'description' => (string) trans('firefly.rulegroup_for_bills_description', [], $lang->data),
'active' => true,
]
);
}
$bills = $this->billRepository->getBills();
/** @var Bill $bill */
foreach ($bills as $bill) {
$this->migrateBill($ruleGroup, $bill, $lang);
}
}
/**
* 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->count = 0;
$this->userRepository = app(UserRepositoryInterface::class);
$this->ruleGroupRepository = app(RuleGroupRepositoryInterface::class);
$this->billRepository = app(BillRepositoryInterface::class);
$this->ruleRepository = app(RuleRepositoryInterface::class);
}
}

View File

@@ -40,7 +40,6 @@ use Illuminate\Console\Command;
*/
class OtherCurrenciesCorrections extends Command
{
public const CONFIG_NAME = '480_other_currencies';
/**
* The console command description.
@@ -58,14 +57,14 @@ class OtherCurrenciesCorrections extends Command
private $accountCurrencies;
/** @var AccountRepositoryInterface */
private $accountRepos;
/** @var CurrencyRepositoryInterface */
private $currencyRepos;
/** @var JournalRepositoryInterface */
private $journalRepos;
/** @var JournalCLIRepositoryInterface */
private $cliRepos;
/** @var int */
private $count;
/** @var CurrencyRepositoryInterface */
private $currencyRepos;
/** @var JournalRepositoryInterface */
private $journalRepos;
/**
* Execute the console command.
@@ -91,26 +90,10 @@ 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;
}
/**
* 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->count = 0;
$this->accountCurrencies = [];
$this->accountRepos = app(AccountRepositoryInterface::class);
$this->currencyRepos = app(CurrencyRepositoryInterface::class);
$this->journalRepos = app(JournalRepositoryInterface::class);
$this->cliRepos = app(JournalCLIRepositoryInterface::class);
}
/**
* @param Account $account
*
@@ -136,110 +119,6 @@ class OtherCurrenciesCorrections extends Command
$this->accountCurrencies[$accountId] = $currency;
return $currency;
}
/**
* @return bool
*/
private function isExecuted(): bool
{
$configVar = app('fireflyconfig')->get(self::CONFIG_NAME, false);
if (null !== $configVar) {
return (bool)$configVar->data;
}
return false; // @codeCoverageIgnore
}
/**
*
*/
private function markAsExecuted(): void
{
app('fireflyconfig')->set(self::CONFIG_NAME, true);
}
/**
* @param TransactionJournal $journal
*/
private function updateJournalCurrency(TransactionJournal $journal): void
{
$this->accountRepos->setUser($journal->user);
$this->journalRepos->setUser($journal->user);
$this->currencyRepos->setUser($journal->user);
$this->cliRepos->setUser($journal->user);
$leadTransaction = $this->getLeadTransaction($journal);
if (null === $leadTransaction) {
// @codeCoverageIgnoreStart
$this->error(sprintf('Could not reliably determine which transaction is in the lead for transaction journal #%d.', $journal->id));
return;
// @codeCoverageIgnoreEnd
}
/** @var Account $account */
$account = $leadTransaction->account;
$currency = $this->getCurrency($account);
if (null === $currency) {
// @codeCoverageIgnoreStart
$this->error(sprintf('Account #%d ("%s") has no currency preference, so transaction journal #%d can\'t be corrected',
$account->id, $account->name, $journal->id));
$this->count++;
return;
// @codeCoverageIgnoreEnd
}
// fix each transaction:
$journal->transactions->each(
static function (Transaction $transaction) use ($currency) {
if (null === $transaction->transaction_currency_id) {
$transaction->transaction_currency_id = $currency->id;
$transaction->save();
}
// when mismatch in transaction:
if (!((int)$transaction->transaction_currency_id === (int)$currency->id)) {
$transaction->foreign_currency_id = (int)$transaction->transaction_currency_id;
$transaction->foreign_amount = $transaction->amount;
$transaction->transaction_currency_id = $currency->id;
$transaction->save();
}
}
);
// also update the journal, of course:
$journal->transaction_currency_id = $currency->id;
$this->count++;
$journal->save();
}
/**
* This routine verifies that withdrawals, deposits and opening balances have the correct currency settings for
* the accounts they are linked to.
*
* Both source and destination must match the respective currency preference of the related asset account.
* So FF3 must verify all transactions.
*
*/
private function updateOtherJournalsCurrencies(): void
{
$set =
$this->cliRepos->getAllJournals(
[
TransactionType::WITHDRAWAL,
TransactionType::DEPOSIT,
TransactionType::OPENING_BALANCE,
TransactionType::RECONCILIATION,
]
);
/** @var TransactionJournal $journal */
foreach ($set as $journal) {
$this->updateJournalCurrency($journal);
}
}
/**
@@ -281,4 +160,129 @@ class OtherCurrenciesCorrections extends Command
return $lead;
}
/**
* @return bool
*/
private function isExecuted(): bool
{
$configVar = app('fireflyconfig')->get(self::CONFIG_NAME, false);
if (null !== $configVar) {
return (bool) $configVar->data;
}
return false; // @codeCoverageIgnore
}
/**
*
*/
private function markAsExecuted(): void
{
app('fireflyconfig')->set(self::CONFIG_NAME, true);
}
/**
* 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->count = 0;
$this->accountCurrencies = [];
$this->accountRepos = app(AccountRepositoryInterface::class);
$this->currencyRepos = app(CurrencyRepositoryInterface::class);
$this->journalRepos = app(JournalRepositoryInterface::class);
$this->cliRepos = app(JournalCLIRepositoryInterface::class);
}
/**
* @param TransactionJournal $journal
*/
private function updateJournalCurrency(TransactionJournal $journal): void
{
$this->accountRepos->setUser($journal->user);
$this->journalRepos->setUser($journal->user);
$this->currencyRepos->setUser($journal->user);
$this->cliRepos->setUser($journal->user);
$leadTransaction = $this->getLeadTransaction($journal);
if (null === $leadTransaction) {
// @codeCoverageIgnoreStart
$this->error(sprintf('Could not reliably determine which transaction is in the lead for transaction journal #%d.', $journal->id));
return;
// @codeCoverageIgnoreEnd
}
/** @var Account $account */
$account = $leadTransaction->account;
$currency = $this->getCurrency($account);
if (null === $currency) {
// @codeCoverageIgnoreStart
$this->error(
sprintf(
'Account #%d ("%s") has no currency preference, so transaction journal #%d can\'t be corrected',
$account->id,
$account->name,
$journal->id
)
);
$this->count++;
return;
// @codeCoverageIgnoreEnd
}
// fix each transaction:
$journal->transactions->each(
static function (Transaction $transaction) use ($currency) {
if (null === $transaction->transaction_currency_id) {
$transaction->transaction_currency_id = $currency->id;
$transaction->save();
}
// when mismatch in transaction:
if (!((int) $transaction->transaction_currency_id === (int) $currency->id)) {
$transaction->foreign_currency_id = (int) $transaction->transaction_currency_id;
$transaction->foreign_amount = $transaction->amount;
$transaction->transaction_currency_id = $currency->id;
$transaction->save();
}
}
);
// also update the journal, of course:
$journal->transaction_currency_id = $currency->id;
$this->count++;
$journal->save();
}
/**
* This routine verifies that withdrawals, deposits and opening balances have the correct currency settings for
* the accounts they are linked to.
*
* Both source and destination must match the respective currency preference of the related asset account.
* So FF3 must verify all transactions.
*
*/
private function updateOtherJournalsCurrencies(): void
{
$set
= $this->cliRepos->getAllJournals(
[
TransactionType::WITHDRAWAL,
TransactionType::DEPOSIT,
TransactionType::OPENING_BALANCE,
TransactionType::RECONCILIATION,
]
);
/** @var TransactionJournal $journal */
foreach ($set as $journal) {
$this->updateJournalCurrency($journal);
}
}
}

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