Compare commits

...

1048 Commits

Author SHA1 Message Date
James Cole
ecdf59ee3e Merge branch 'release/4.7.7' 2018-09-29 12:27:03 +02:00
James Cole
cc1f3bba7e Updated language strings 2018-09-29 11:45:28 +02:00
James Cole
b501c47187 Move tags lower [skip ci] 2018-09-28 18:39:26 +02:00
James Cole
791b028dc4 Fix issue where an array is passed instead of a string. 2018-09-28 07:46:23 +02:00
James Cole
ab5b7f7893 Reinstate notes for bills. 2018-09-27 17:46:28 +02:00
James Cole
4b1aa29269 Fix Sandstorm. 2018-09-27 17:28:23 +02:00
James Cole
de34538d96 Update docker file for php 7.2 2018-09-27 16:35:24 +02:00
James Cole
53eb93fc4d New meta files for the upcoming release. 2018-09-27 16:33:08 +02:00
James Cole
a3841855e4 Fix for #1737 2018-09-27 13:54:59 +02:00
James Cole
b1e742c26c Fix tests. 2018-09-27 13:11:31 +02:00
James Cole
2c2814c998 Align notes with object, not separate. 2018-09-27 07:43:30 +02:00
James Cole
214c7a6f3e Improve test results. 2018-09-27 06:26:03 +02:00
James Cole
6c4f967c39 Fix for #1728 2018-09-27 05:57:06 +02:00
James Cole
e0152d3df4 Fix #1716 2018-09-26 20:47:57 +02:00
James Cole
989ffc2f07 Fix #1729 2018-09-26 20:44:43 +02:00
James Cole
f87a4c1e7c Fix for #1731 2018-09-26 20:42:07 +02:00
James Cole
fea5510700 Add some test code. 2018-09-26 20:35:27 +02:00
James Cole
aa1ae18dbb Fix validation #1720 2018-09-26 20:35:01 +02:00
James Cole
b5efd38ded New OFX parser reference. 2018-09-26 20:34:45 +02:00
James Cole
2a457c40db Fix for #1723 2018-09-26 20:34:24 +02:00
James Cole
e38b64547f Merge branch 'develop' of github.com:firefly-iii/firefly-iii into develop 2018-09-26 20:32:38 +02:00
James Cole
bafa96b9c0 Fix for #1719 2018-09-26 20:21:25 +02:00
James Cole
d49a13b091 Merge branch 'develop' of https://github.com/firefly-iii/firefly-iii into develop
* 'develop' of https://github.com/firefly-iii/firefly-iii:
  remove first slash in mass transaction changes
- Fix user event handler test
- Fix 404 view
2018-09-23 07:39:31 +02:00
James Cole
0bd818956f Fix auto complete for tags and others. Adds search. 2018-09-23 07:39:04 +02:00
James Cole
c119b9cc7b Merge pull request #1712 from hamuz/patch-4
remove first slash in mass transaction changes
2018-09-23 07:17:38 +02:00
HamuZ HamuZ
958c7e7939 remove first slash in mass transaction changes
maybe bug when Firefly installed in directory
2018-09-23 08:01:55 +03:00
James Cole
254a46b54c Move new currency so it doesn't break previous ID's. 2018-09-23 06:57:50 +02:00
James Cole
6ed31dc4c9 PHP 7.2 specific code. 2018-09-23 06:57:37 +02:00
James Cole
fe8f5573d2 Clean up request class. 2018-09-23 06:57:27 +02:00
James Cole
51dfb8ebf1 Auto complete now supports search. 2018-09-23 06:57:00 +02:00
James Cole
8fd64791d6 Strip newlines and tabs from description. 2018-09-23 06:53:15 +02:00
James Cole
82e7202ad2 Merge pull request #1710 from hamuz/patch-3
Add ILS currency
2018-09-23 06:46:59 +02:00
HamuZ HamuZ
1f70782f7e Add ILS 2018-09-22 22:46:28 +03:00
James Cole
eefb1c4a47 Fix for #1709 2018-09-22 20:01:38 +02:00
James Cole
069015c9b1 Merge pull request #1708 from mathieupost/patch-1
Fix bunq import "Undefined index: apply_rules"
2018-09-22 14:01:10 +02:00
James Cole
c1583d19fb Push Travis to 7.2 2018-09-22 13:58:58 +02:00
Mathieu Post
0556433ce4 Fix bunq import "Undefined index: apply_rules"
When using the bunq import and unchecking "apply rules" gave an error. Same as https://github.com/firefly-iii/firefly-iii/issues/1538
2018-09-22 13:57:36 +02:00
James Cole
ec072cee23 Add debug info to currency screen. 2018-09-22 07:09:41 +02:00
James Cole
e29e6c147c Upgrade Firefly III to PHP 7.2 and Laravel 5.7 2018-09-19 16:50:16 +02:00
James Cole
972721b183 Fix tests. 2018-09-18 18:47:42 +02:00
James Cole
9bf43ce80d Merge pull request #1701 from hertzg/fix-composer-php-path-issue
Make sure PHP executable is being resolved by composer
2018-09-18 18:36:31 +02:00
George Hertz
5941b5c07e composer: Make sure PHP executable is being resolved by composer 2018-09-18 18:18:09 +02:00
James Cole
3d91a186d5 Remove credit card liability type from system. 2018-09-18 18:17:55 +02:00
James Cole
744d45fb04 Modernise the typeahead stuff to squash some bugs. 2018-09-17 17:41:34 +02:00
James Cole
f76fdedd25 Set time out to zero. #1607 2018-09-17 16:50:46 +02:00
James Cole
93ca07d812 Fix auto complete (#1519) for editing reconciliations. 2018-09-17 09:36:31 +02:00
James Cole
d69042daee Code for #1519 2018-09-17 09:22:47 +02:00
James Cole
d9f515900c Expand code coverage. 2018-09-15 13:44:36 +02:00
James Cole
57b4a5be08 Code and tests for #1450 2018-09-15 13:43:57 +02:00
James Cole
fa347f5f75 Typo fix for #1695 2018-09-14 17:44:29 +02:00
James Cole
35e3404ced Merge pull request #1694 from hamuz/patch-2
Add expected behavior to bug report template
2018-09-14 17:36:35 +02:00
HamuZ HamuZ
f7344ec6c9 Add expected behavior to bug report template
Helps to understand how the bug violates what the user expect to happen in normal scenario.
2018-09-14 17:53:40 +03:00
James Cole
63a1e560ee Fix #1691 2018-09-14 11:39:40 +02:00
James Cole
98463f8258 Fix #1690 2018-09-14 11:14:20 +02:00
James Cole
2c95bfa701 Extra tools [skip ci] 2018-09-13 20:55:59 +02:00
James Cole
2de3a2c98e Fix alignment of auto-complete #1685 2018-09-13 20:48:02 +02:00
James Cole
314c0c9e3f Fix #1685 2018-09-13 20:45:16 +02:00
James Cole
4377627332 Some extra logging + a fix for #1683 2018-09-13 20:23:17 +02:00
James Cole
71d3f452ed Fix #1682 2018-09-13 20:12:19 +02:00
James Cole
e117222dc2 Fix for #1679 2018-09-13 20:01:41 +02:00
James Cole
6286daa881 Fix for #1675 2018-09-12 17:47:31 +02:00
James Cole
0b3b9af623 Fix test for fixed chart category controller 2018-09-12 12:57:14 +02:00
James Cole
1492f5611e Add forgotten entries to the change log. 2018-09-12 12:56:40 +02:00
James Cole
efeffaa49f Refactor period blocks. 2018-09-10 20:24:19 +02:00
James Cole
d77112955d Fix secure headers for new Google tag. 2018-09-10 20:23:43 +02:00
James Cole
9a34bb7e7a Small test fixes. 2018-09-10 20:22:02 +02:00
James Cole
b30445a5f3 Update Google Analytics tracking code. 2018-09-10 20:21:39 +02:00
James Cole
0bf5c6ee3d Fix for #1667 2018-09-10 17:57:20 +02:00
James Cole
155480b335 Code for #1671 2018-09-10 16:18:35 +02:00
James Cole
34202dea1d Some attempts to fix #1673 2018-09-09 21:23:04 +02:00
James Cole
38d58f0354 Fix #1670 2018-09-09 20:40:26 +02:00
James Cole
d4b82a33c5 After pulling the code from @hamuz I realised the test was disabled. So I enabled it again. I had to change two test results. One was a 0 value not being negative, the other was due to the 12 decimal cut off (Firefly III configuration). 2018-09-09 17:11:07 +02:00
James Cole
06f3463dbc Merge pull request #1672 from hamuz/develop
Implementation of negated amount column type
2018-09-09 17:02:57 +02:00
HamuZ HamuZ
9df2d86ac2 Add support for negated amount. Closes #1660 and #1650. 2018-09-09 13:35:21 +03:00
HamuZ HamuZ
c83d93971f Merge pull request #4 from firefly-iii/develop
Get last commits
2018-09-09 13:25:06 +03:00
James Cole
7e3ba3c27f Fix JSON encode #1668 2018-09-09 11:18:05 +02:00
James Cole
c7043dffc2 Extra code for #1668 2018-09-09 07:57:15 +02:00
James Cole
d2c1e30979 Fixes for #1670 2018-09-09 07:48:17 +02:00
James Cole
d5679c372f Temp fix for #1668. 2018-09-08 15:12:36 +02:00
James Cole
b33f8b70d4 Improve code coverage. 2018-09-07 20:12:22 +02:00
James Cole
d5773ab5d0 Make reports slightly more multi currency. 2018-09-06 19:47:29 +02:00
James Cole
1903292202 Fix reference in change log [skip ci] 2018-09-06 19:46:28 +02:00
James Cole
c3a9415208 Fine tune test content. 2018-09-06 13:56:18 +02:00
James Cole
9ece209c72 Add two new ranges #954 2018-09-06 13:05:15 +02:00
James Cole
03956af88a Warn when classes are used in testing environment; this means tests aren't efficient. 2018-09-06 12:29:32 +02:00
James Cole
013c8707ac Fix for #907 2018-09-06 12:28:15 +02:00
James Cole
32ed9c59ea Code for #896 2018-09-06 10:14:12 +02:00
James Cole
4ef663669c Unset transaction source so the duplicate detector keeps working. 2018-09-06 07:40:56 +02:00
James Cole
b855c54e81 Clean up some old code. 2018-09-06 07:38:51 +02:00
James Cole
8b65c8b909 Add Robot font because why not. 2018-09-06 07:38:41 +02:00
James Cole
28e7440726 Add budget limit currency ID. 2018-09-06 07:38:26 +02:00
James Cole
7bca2298a0 Fix tests for new transaction source routine. 2018-09-06 07:37:44 +02:00
James Cole
b1cc17d96e Make sure each source of transactions stores where it's from. 2018-09-05 19:45:59 +02:00
James Cole
2afbef63aa Rename font file and make font heavier for #1658 2018-09-05 07:54:53 +02:00
James Cole
f0d2caec67 Update file list for Sandstorm build [skip ci] 2018-09-04 20:09:51 +02:00
James Cole
ac2a317fd2 Merge tag '4.7.6.2' into develop
4.7.6.2
2018-09-04 19:49:46 +02:00
James Cole
bc4ac303e2 Merge branch 'release/4.7.6.2' 2018-09-04 19:49:45 +02:00
James Cole
0e9fbecbe4 Forgot the credit card type [skip ci] 2018-09-04 19:32:50 +02:00
James Cole
226b3cfdd8 Update meta files and language files for new release. 2018-09-04 19:07:02 +02:00
James Cole
d43fa3790d Update tests so repositories are not called. Saves on DB calls, speeds up tests. 2018-09-04 16:47:01 +02:00
James Cole
ca04113aa7 Less logging for tests means less strain on travis et al. 2018-09-04 09:52:51 +02:00
James Cole
817c157db4 Disable languages that drop under 75% coverage. 2018-09-04 09:52:35 +02:00
James Cole
07edbe758a Update tests so repositories are not called. Saves on DB calls, speeds up tests. 2018-09-04 09:52:19 +02:00
James Cole
46ba0a5a5a Mock more repositories in tests. 2018-09-03 18:52:46 +02:00
James Cole
480b636c7e Fix Docker build 2018-09-03 14:51:15 +02:00
James Cole
20340dff7b Fix CSS of OAuth authorise view. 2018-09-03 14:50:57 +02:00
James Cole
cfbabb500f Merge tag '4.7.6.1' into develop
4.7.6.1
2018-09-03 10:26:38 +02:00
James Cole
a4cb2c1cb1 Merge branch 'release/4.7.6.1' 2018-09-03 10:26:36 +02:00
James Cole
bd31b7e943 Update language files [skip ci] 2018-09-03 10:20:51 +02:00
James Cole
b2e7c767df Update meta files to 4.7.6.1 [skip ci] 2018-09-03 10:10:58 +02:00
James Cole
bb9f763729 Repositories will now warn if used in test environment. 2018-09-03 08:41:03 +02:00
James Cole
fb61229bf3 Update the .env files and the Dockerfile. 2018-09-03 08:40:22 +02:00
James Cole
fc30d41ee5 Refer to correct issue [skip ci] 2018-09-03 07:59:32 +02:00
James Cole
7666147f3c Merge pull request #1649 from hamuz/patch-1
2FA QR doesn't show up due to CSP error
2018-09-03 07:57:19 +02:00
HamuZ HamuZ
52f8b24041 2FA QR doesn't show up due to CSP error
Relevant stackoverflow fix:
https://stackoverflow.com/questions/18447970/content-security-policy-data-not-working-for-base64-images-in-chrome-28
2018-09-03 08:19:38 +03:00
James Cole
eaf2667abb Fix test method names. 2018-09-02 20:27:26 +02:00
James Cole
de754ca4e0 Improve test coverage. 2018-09-02 20:13:25 +02:00
James Cole
96dd89fbeb Merge tag '4.7.6' into develop
4.7.6
2018-09-01 21:30:46 +02:00
James Cole
bae40e2cbc Merge branch 'release/4.7.6' 2018-09-01 21:30:44 +02:00
James Cole
6a647dab8b Remove newline from changelog. 2018-09-01 20:57:03 +02:00
James Cole
ebcf5b71d2 Update meta files for new release. 2018-09-01 20:51:22 +02:00
James Cole
02370fb65d Fix final tests 2018-09-01 20:45:05 +02:00
James Cole
1e4f4907e3 Update translations. 2018-09-01 20:44:50 +02:00
James Cole
13f72c73fb Expand test coverage. 2018-08-31 21:12:53 +02:00
James Cole
69b4632ef6 Fix #1642 2018-08-31 21:11:47 +02:00
James Cole
ede8c293fc Fix for #1643 2018-08-31 19:51:18 +02:00
James Cole
0cfe991482 Fix issue where the tester would not respect the strict yes/no setting. 2018-08-31 17:48:54 +02:00
James Cole
6377459e2f Smaller batch for bunq import. #1607 2018-08-31 17:11:48 +02:00
James Cole
33fe6dbfa3 First step in improving test coverage. 2018-08-30 20:58:07 +02:00
James Cole
e158b9b64e Also improve the "forward" routine so it won't go back again #1607 2018-08-30 19:27:27 +02:00
James Cole
dfa9e537b3 Improve the bunq routine so it will keep looping when faced with default PHP time out settings (30 seconds). 2018-08-30 19:12:52 +02:00
James Cole
6d28ece616 Download more, sleep less. #1607 2018-08-29 17:33:36 +02:00
James Cole
59f4ecdaa6 The net worth chart will respect net worth preferences. 2018-08-29 10:57:42 +02:00
James Cole
10d953f336 Update change log. [skip ci] 2018-08-29 08:01:30 +02:00
James Cole
5b771f7def Code for #1607 2018-08-28 21:48:10 +02:00
James Cole
4a8e3ee845 Merge pull request #1639 from hamuz/hamuz-patch-1
Trust Heroku load balancer
2018-08-28 19:43:19 +02:00
HamuZ HamuZ
9a1f559dd2 Merge branch 'develop' into hamuz-patch-1 2018-08-28 20:34:01 +03:00
James Cole
62321a03ca Fix missing combi for transaction types. 2018-08-28 14:23:51 +02:00
James Cole
40ca72c656 Reference to unknown chart. 2018-08-28 14:20:04 +02:00
HamuZ HamuZ
34fcff7a9d Trust Heroku load balancer
Fix insecure warning in browser when deploying to Heroku
2018-08-28 08:18:43 +03:00
James Cole
e1c829f4fa Make some charts multi-currency. 2018-08-28 05:21:23 +02:00
James Cole
46136d94e9 A fix for apparently unknown category names [skip ci] 2018-08-28 04:29:16 +02:00
James Cole
0e2e8d1be5 Fix new category chart tests. 2018-08-27 21:06:46 +02:00
James Cole
1d1aa5dd3a Fix tests for multi currency account charts. 2018-08-27 20:33:52 +02:00
James Cole
0d82589916 Make some charts currency aware for #740 2018-08-27 18:59:30 +02:00
James Cole
4fc13037d2 This makes the expense chart on the frontpage multi-currency. 2018-08-27 08:08:51 +02:00
James Cole
3764499714 Expand API to accept liability accounts. 2018-08-26 21:29:46 +02:00
James Cole
c4bbbc49b4 Update CSS font references 2018-08-26 21:29:30 +02:00
James Cole
503158ab97 New translations [skip ci] 2018-08-26 18:44:22 +02:00
James Cole
8c1d1d1db0 Improved implementation of liability accounts and the option to add or remove accounts from the net-worth calculations. 2018-08-26 18:40:38 +02:00
James Cole
7dc72a2894 Add the ability to make transactions to and from liability accounts. 2018-08-25 22:10:10 +02:00
James Cole
07cfba1b3a Add the ability to make transfers to and from liability accounts. 2018-08-25 21:33:22 +02:00
James Cole
c55b80f467 Update test coverage. 2018-08-25 20:45:42 +02:00
James Cole
2099da7142 Moved word "success out of hyperlink [skip ci] 2018-08-25 17:09:25 +02:00
James Cole
ea125936e7 Fix CSS. [skip ci] 2018-08-25 17:08:29 +02:00
James Cole
5de01628a6 Expand secure headers. 2018-08-25 10:49:52 +02:00
James Cole
2834aca597 Update header readability, add Google as an optional allowed source. 2018-08-25 10:36:27 +02:00
James Cole
88bab888d8 Update CSS and JS libs. 2018-08-25 07:56:10 +02:00
James Cole
dfdbace298 Add secure headers middleware. 2018-08-25 07:55:47 +02:00
James Cole
a9590d2bb6 Add secure headers middleware. 2018-08-25 07:55:32 +02:00
James Cole
29a81eb05e Fix test coverage. 2018-08-24 21:14:17 +02:00
James Cole
20490fcd80 Update JS 2018-08-24 21:14:04 +02:00
James Cole
e775927f60 Add htaccess files to prevent directory indexing. [skip ci] 2018-08-24 21:10:04 +02:00
James Cole
835a421909 Refactor rule processor so it's testable. 2018-08-24 17:57:34 +02:00
James Cole
850a0ae17e Improved code coverage for events and reports. 2018-08-24 16:07:33 +02:00
James Cole
2b54363dd7 Improve test coverage. 2018-08-24 07:18:33 +02:00
James Cole
b174a06b86 Rewrite text in env files. 2018-08-24 07:17:50 +02:00
James Cole
d4096103cb Improve test coverage and fix test code. 2018-08-23 18:33:39 +02:00
James Cole
3f493aceb2 Mark code as untestable or deprecated (or both). 2018-08-23 18:33:07 +02:00
James Cole
05309da76d Small fix for test script. 2018-08-23 18:32:17 +02:00
James Cole
179f720806 Some updated translations [skip ci] 2018-08-23 06:17:26 +02:00
James Cole
7c34144ccd Some basic code for liability accounts. 2018-08-22 21:18:15 +02:00
James Cole
cc234b594d Fix call to cron job, clear cache after running. 2018-08-21 18:20:01 +02:00
James Cole
024cf610a8 Merge pull request #1624 from david-me/clickable-transaction-notifier
Can have link in success message to the transaction it refers to
2018-08-21 15:52:52 +02:00
David Meiseles
a1896a6336 DRYed out 2018-08-20 13:45:30 -04:00
David Meiseles
d30da7bf5d Can have link in success message to the transaction it refers to 2018-08-20 11:36:13 -04:00
James Cole
f8e914416d Give file a newline [skip ci] 2018-08-20 17:31:39 +02:00
James Cole
433da921bb Simplify cronjob call. 2018-08-20 17:29:39 +02:00
James Cole
4876053018 Test a fix for #1620 2018-08-19 19:31:21 +02:00
James Cole
0c3a580b33 Fix issues with italian translation, add new translations [skip ci] 2018-08-18 22:11:31 +02:00
James Cole
7689b7b4b0 Forgot to push this part of the fix for #1615 2018-08-18 20:13:52 +02:00
James Cole
21bff39e31 Fix #1620 2018-08-18 20:13:26 +02:00
James Cole
ba09901228 fix #1615 2018-08-18 20:11:12 +02:00
James Cole
90bf2e58b2 Fixes #1620 2018-08-18 14:12:39 +02:00
James Cole
004807aa32 Update cron file, use supervisor. 2018-08-18 14:08:28 +02:00
James Cole
35bacf2ad0 Update docker file to match postgres. 2018-08-18 05:21:47 +02:00
James Cole
81d17409d4 Fix some things with the update checker. 2018-08-17 21:51:15 +02:00
James Cole
a8080f55f0 Fix docker and entry point. 2018-08-17 21:12:26 +02:00
James Cole
379c540bd8 Update config for logging in Docker. 2018-08-17 20:01:46 +02:00
James Cole
f319005357 Fix tests. 2018-08-17 06:45:57 +02:00
James Cole
df0e2dd2a2 Bump version and warn about PHP 7.2 2018-08-17 06:39:48 +02:00
James Cole
219a0cd612 Fix for #1617 2018-08-17 05:54:29 +02:00
James Cole
3ca3ce0726 Fix #1616 2018-08-16 20:43:11 +02:00
James Cole
566be8dc63 Fix #1564 2018-08-16 16:42:58 +02:00
James Cole
6bd4fa1c0a Remove bad slash from path. 2018-08-15 19:10:00 +02:00
James Cole
c767ee04f4 Merge pull request #1613 from ErikFontanel/develop
fixed missing ENV variables
2018-08-15 17:15:33 +02:00
Erik Gelderblom
a5f89e0967 fixed missing ENV variables 2018-08-15 14:43:49 +02:00
James Cole
7355d14159 Merge pull request #1610 from ErikFontanel/develop
Multi architecture Dockerfile
2018-08-15 06:18:54 +02:00
Erik Gelderblom
efd5ceb405 fixed installation for cURL and cron 2018-08-14 21:21:03 +02:00
James Cole
035dc8ceb4 Fix #1609 2018-08-14 20:08:07 +02:00
James Cole
11be33e942 Fix #1605 2018-08-14 06:40:21 +02:00
James Cole
e125254687 Fix bad method name. 2018-08-14 06:40:04 +02:00
James Cole
a2b997ba20 Fix #1608 2018-08-13 19:09:43 +02:00
James Cole
7327941c77 Alert if cron job isn't running. 2018-08-13 19:07:46 +02:00
James Cole
6c9eb1b699 Update composer lock file. 2018-08-13 19:07:22 +02:00
James Cole
60e262dece Fix bug in Spectre import. 2018-08-13 18:30:47 +02:00
James Cole
9c5463e515 Update to user and cron job. 2018-08-13 18:10:02 +02:00
James Cole
6941176519 Make chart red/green 2018-08-13 18:09:47 +02:00
James Cole
cb2c52cddb New cronjob code. 2018-08-12 14:26:11 +02:00
James Cole
dd95776144 Code for #833 2018-08-12 10:06:20 +02:00
James Cole
b95ca98be9 Add cron job to docker file. 2018-08-12 09:34:03 +02:00
James Cole
67b090b4d8 New translations. 2018-08-12 09:33:56 +02:00
James Cole
54b76a03ce Update views and translations. 2018-08-11 19:22:28 +02:00
James Cole
cd6c727730 Flags for help pages. 2018-08-11 19:22:10 +02:00
James Cole
a35c6e29b6 Rename various methods. 2018-08-11 19:21:58 +02:00
James Cole
95ce72fce7 Expand API options for available budgets and journal links 2018-08-11 18:27:45 +02:00
James Cole
a803dfc7fa Undo recurring job thing. 2018-08-11 18:20:29 +02:00
James Cole
c465d1c059 Example run of recurring thing outside of cron job. 2018-08-11 18:20:10 +02:00
James Cole
9914c0791e Rename journal collector to more fitting transaction collector. 2018-08-11 14:33:47 +02:00
James Cole
96baf5d3c7 Add new transaction collector (as opposed to journal collector). 2018-08-11 14:15:22 +02:00
James Cole
a205367b62 Various refactoring. 2018-08-11 14:15:07 +02:00
James Cole
6218fa90de Move get income / get expense methods to trait. 2018-08-11 14:06:49 +02:00
James Cole
51a770cfdc New experimental Dockerfile #1464 2018-08-11 07:22:17 +02:00
James Cole
16fba15b5c Refactor various methods away from controllers 2018-08-11 06:39:29 +02:00
James Cole
ec2463a3ba Remove view generation and put in trait. 2018-08-10 18:19:51 +02:00
James Cole
b605ede74e Move methods to traits. 2018-08-10 17:05:37 +02:00
James Cole
b1b13d3696 Can no longer set a budget to an expense. 2018-08-09 20:49:30 +02:00
James Cole
51b11e5188 Can no longer set a budget to an expense. 2018-08-09 20:46:47 +02:00
James Cole
eefa84a77b Remove method pointers from tests. 2018-08-09 20:17:15 +02:00
James Cole
5908b4b000 Route fixes and fix tests. 2018-08-09 19:44:36 +02:00
James Cole
2ed433c96d Refactor configuration methods into trait 2018-08-09 17:50:30 +02:00
James Cole
9865800e39 Refactor many request related methods into (complex) trait. 2018-08-09 17:46:14 +02:00
James Cole
4f697e77d5 Redirect user to original account refactor. 2018-08-09 17:34:11 +02:00
James Cole
c957aded98 Redirect user to original account refactor. 2018-08-09 17:32:28 +02:00
James Cole
aa0758cd2b Refactor basic methods to trait 2018-08-09 16:16:27 +02:00
James Cole
0c2093753d Refactor isSplitJournal() 2018-08-09 16:14:47 +02:00
James Cole
136f983353 Move isOpeningBalance() to trait 2018-08-09 16:13:13 +02:00
James Cole
7943164375 Change scope of methods, add some notes. Prep for refactoring. 2018-08-09 16:07:33 +02:00
James Cole
32e58d0a60 Replace "moment" with more accurate start/end dates. 2018-08-08 17:53:40 +02:00
James Cole
bc807965ab Improve navigation for tags and rename route. 2018-08-07 21:00:25 +02:00
James Cole
477788658b Recurring transactions support pagination. 2018-08-07 20:47:05 +02:00
James Cole
723abf44bd Shorten breadcrumbs [skip ci] 2018-08-07 20:38:19 +02:00
James Cole
fd1298d4d2 Refactor method that only counts. 2018-08-07 19:29:53 +02:00
James Cole
42f39536a1 Catch "throwable" 2018-08-07 19:29:40 +02:00
James Cole
6f0ac91bd2 Add missing string. 2018-08-07 19:29:25 +02:00
James Cole
6dea9156ab Fix edit for liabilities. 2018-08-07 19:29:19 +02:00
James Cole
c5051b3e46 Make method nullable. 2018-08-07 19:29:10 +02:00
James Cole
229d033e1a Fix category bread crumb 2018-08-07 19:28:54 +02:00
James Cole
f494ba7065 Rename field to "notes" 2018-08-07 19:28:46 +02:00
James Cole
201bc7db53 Update requests. 2018-08-07 19:24:07 +02:00
James Cole
cd2a251f22 Reinstate description for rule group. 2018-08-07 17:54:37 +02:00
James Cole
ff44ad4994 Fix #1597 2018-08-07 17:50:14 +02:00
James Cole
b496ca6a2c Some fixing up for #1598 2018-08-07 17:34:43 +02:00
James Cole
5908c0ce8c Code cleanup and realign. 2018-08-06 19:14:30 +02:00
James Cole
f7eef25fed New translations. 2018-08-05 20:44:05 +02:00
James Cole
049c93465a Update tests 2018-08-05 20:42:45 +02:00
James Cole
33294dd9f0 Allow editing of liabilities. 2018-08-05 18:59:15 +02:00
James Cole
0a89f4000d Synchronise API and app rule management. 2018-08-05 15:41:13 +02:00
James Cole
422e80530b Refactor rule creation. 2018-08-05 15:34:20 +02:00
James Cole
07a8c69ba8 New translations [skip ci] 2018-08-05 15:33:49 +02:00
James Cole
5449879a7d Fix for #1594 2018-08-05 07:36:33 +02:00
James Cole
8dbc846314 Basic code for tracking liabilities. 2018-08-04 17:30:47 +02:00
James Cole
f0d3ca5d53 Various code cleanup. 2018-08-04 17:30:06 +02:00
James Cole
5af026674f Updated translations. 2018-08-04 14:17:03 +02:00
James Cole
2ebb4778cd Merge pull request #1593 from lucavallerini/transactions-links-translatable
Transactions links are now translatable on admin views
2018-08-04 14:14:33 +02:00
James Cole
bf3c57d26b Remove translations. 2018-08-04 14:14:08 +02:00
Luca Vallerini
cb9c87102f Transactions links are now translatable on admin views 2018-08-04 13:03:54 +02:00
James Cole
c73b003de4 Merge pull request #1591 from claystation/master
BUGFIX: Initial user not set as owner
2018-08-04 12:08:00 +02:00
Clemens Wijnekus
771d448a7b Revert "Added .idea folder to Gitignore for IntelliJ based projects."
This reverts commit dd49926
2018-08-04 10:17:18 +02:00
Clemens Wijnekus
de12db5f05 Fix for setting initial user as Owner 2018-08-04 00:27:28 +02:00
Clemens Wijnekus
dd49926cc2 Added .idea folder to Gitignore for IntelliJ based projects. 2018-08-04 00:08:21 +02:00
James Cole
7a9ab190eb Fixes #1586 2018-08-03 16:55:10 +02:00
James Cole
2290fcde22 First code for liabilities and some tests. 2018-08-03 16:35:55 +02:00
James Cole
ae85876965 Make sure null value is turned into an empty string [skip ci] 2018-08-02 07:17:18 +02:00
James Cole
f07d8e958f Experimental sort routine for list of accounts [skip ci] 2018-08-02 07:14:00 +02:00
James Cole
610af45dee Experimental sort routine for list of accounts [skip ci] 2018-08-02 07:12:06 +02:00
James Cole
138a5bc3fe Add autocomplete field as suggested by Chrome. 2018-08-01 07:35:31 +02:00
James Cole
427e9c5637 Fix #1216 2018-08-01 07:32:53 +02:00
James Cole
e3e8336602 Update some code for Heroku. 2018-08-01 07:24:19 +02:00
James Cole
194073e49a Fix tests. 2018-07-31 20:39:36 +02:00
James Cole
1af45aff73 Fix missing link to admin. 2018-07-31 19:28:56 +02:00
James Cole
56518ea028 First working version of YNAB import #145 2018-07-31 18:19:48 +02:00
James Cole
c1ac2bb156 Expand text and routine for YNAB 2018-07-31 05:49:03 +02:00
James Cole
a004f27361 Updated strings 2018-07-31 05:35:25 +02:00
James Cole
7843c55409 Expand helptext for #1581 2018-07-31 05:30:27 +02:00
James Cole
41da7d9f9a Fix #1580 2018-07-31 05:27:33 +02:00
James Cole
2add644706 First basic import #145 2018-07-30 20:39:19 +02:00
James Cole
dfd9cf0874 New code for YNAB import. 2018-07-29 21:02:03 +02:00
James Cole
7ad09da4e9 Fix #1576 2018-07-29 16:04:22 +02:00
James Cole
8efbeb14d2 First code for YNAB import #145 2018-07-29 07:30:06 +02:00
James Cole
a1005d91df Expand views with CSRF token, to prevent error in console. #1575 2018-07-29 06:53:08 +02:00
James Cole
a681f1ce3c Empty URL warning 2018-07-28 21:03:08 +02:00
James Cole
5a0714ca1a Merge tag '4.7.5.3' into develop
4.7.5.3
2018-07-28 15:39:36 +02:00
James Cole
bd5c790043 Merge branch 'release/4.7.5.3' 2018-07-28 15:39:35 +02:00
James Cole
2ae3cf79e4 Update config files and change logs for hotfix. 2018-07-28 15:20:28 +02:00
James Cole
fb122ba097 Fix for #1572 2018-07-28 15:10:20 +02:00
James Cole
0c104cd86c New file list for Sandstorm. 2018-07-28 14:54:10 +02:00
James Cole
a687f4ad68 Merge tag '4.7.5.2' into develop
4.7.5.2
2018-07-28 13:38:09 +02:00
James Cole
228f42cf04 Merge branch 'release/4.7.5.2' 2018-07-28 13:38:06 +02:00
James Cole
6d4956b574 Updated files for 4.7.5.2 2018-07-28 12:10:25 +02:00
James Cole
0c7b652a70 Last code optimization before release. 2018-07-28 10:45:16 +02:00
James Cole
d35470a79e Found and fixed #1571 2018-07-28 10:03:47 +02:00
James Cole
719d610be3 Fix issue with new crud() method. 2018-07-28 07:26:33 +02:00
James Cole
07ae64693e new language strings and updated code 2018-07-28 06:27:30 +02:00
James Cole
0ccc1271a6 Update tests. 2018-07-27 06:06:29 +02:00
James Cole
26fa2b0b74 Speed up category test. 2018-07-27 06:02:34 +02:00
James Cole
6f64c19c32 Update changelog for next release. 2018-07-27 05:03:50 +02:00
James Cole
e3e0e12fef Various code cleanup. 2018-07-27 05:03:37 +02:00
James Cole
0312ba8ad7 Various bugfixes and code clean up. 2018-07-27 04:46:21 +02:00
James Cole
2ad8e7f343 Fix some errors found in debug logs. 2018-07-27 03:09:35 +02:00
James Cole
d6298d9f05 Add extra logging for common error on demo site [skip ci] 2018-07-26 06:28:49 +02:00
James Cole
89be30c4b9 Catch various errors. 2018-07-26 06:27:52 +02:00
James Cole
6bcfea1de4 Various code cleanup. 2018-07-26 06:10:17 +02:00
James Cole
e8c9554dd6 Remove TODO's, add some suppressors for code quality. 2018-07-25 19:43:02 +02:00
James Cole
02272f7db0 New strings [skip ci] 2018-07-25 16:44:06 +02:00
James Cole
5a73e79475 Update explanation about sha1 [skip ci] 2018-07-25 16:14:24 +02:00
James Cole
7f4ecd40ce Fix issues where data-variable was not initialized properly. 2018-07-25 07:11:04 +02:00
James Cole
7c950c3022 Remove a lot of deprecated code. 2018-07-25 06:45:25 +02:00
James Cole
dbf019135a Simplified tag cloud. 2018-07-25 06:18:20 +02:00
James Cole
e504ee82e5 Submitted debug code. 2018-07-24 21:13:12 +02:00
James Cole
780a15fe4f Remove array calls and fix various bugs. 2018-07-24 21:12:48 +02:00
James Cole
abb249643f Fix bad class reference. 2018-07-24 20:49:25 +02:00
James Cole
086eccaf4a Updates for new Sandstorm package. 2018-07-24 20:30:52 +02:00
James Cole
871033501a Update file list for Sandstorm. 2018-07-24 20:29:39 +02:00
James Cole
ccd727488f Update file list for Sandstorm. 2018-07-24 20:19:41 +02:00
James Cole
aa59d0f082 Merge pull request #1569 from ocdtrekkie/update-sandstorm-build
Update Sandstorm build instructions
2018-07-24 20:16:42 +02:00
Jacob Weisz
5d12f53283 Update Sandstorm build instructions
I've moved this to official Jessie 64-bit. vagrant-spk currently uses Stretch, but that'd likely require more changes and testing on your other build files.
2018-07-24 12:14:35 -05:00
James Cole
59c005875a Fix for #1568 2018-07-24 17:46:34 +02:00
James Cole
06d22e843a Code optimizations. 2018-07-23 21:49:15 +02:00
James Cole
4fa5f4e5a3 Fix some issues that triggered in scrutinizer. 2018-07-22 21:32:58 +02:00
James Cole
67ea825d4a Remove unused methods. 2018-07-22 21:09:57 +02:00
James Cole
a616e06f9d Add newlines to tests. [skip ci] 2018-07-22 20:33:17 +02:00
James Cole
b7752928a4 Give all of these files a newline at the end. 2018-07-22 20:32:02 +02:00
James Cole
ca096852a5 Code optimisations. 2018-07-22 18:50:27 +02:00
James Cole
ea2c48bca5 Fix tests. 2018-07-22 17:06:10 +02:00
James Cole
a722dc4235 Clean up code, remove unused methods. 2018-07-22 16:35:46 +02:00
James Cole
dbbf0ff5e4 Improve code in Jobs. 2018-07-22 15:20:45 +02:00
James Cole
a941519db5 Improve code quality. 2018-07-22 15:08:56 +02:00
James Cole
d4ba014a8a Clean up various code. 2018-07-22 12:52:07 +02:00
James Cole
d193a6aec4 Give commands proper exit codes. 2018-07-22 10:05:06 +02:00
James Cole
1f0fdf3da7 Fix #1563 2018-07-22 09:03:53 +02:00
James Cole
b705240faa Fix #1530 2018-07-22 08:58:58 +02:00
James Cole
662b832274 Fix max amount. 2018-07-22 08:36:30 +02:00
James Cole
aed7e6d289 Fix #1549 2018-07-22 08:27:18 +02:00
James Cole
f7a1201d02 Expand route link for transactions without a budget. 2018-07-22 08:14:42 +02:00
James Cole
4d5bdd25a8 Add phpdocs everywhere. 2018-07-22 08:10:16 +02:00
James Cole
4a90ce35f2 Add php doc [skip ci] 2018-07-21 08:55:32 +02:00
James Cole
02f5eddd14 Update PHP doc everywhere. 2018-07-21 08:06:24 +02:00
James Cole
5ca4f1b181 Remove null pointer. 2018-07-21 06:41:42 +02:00
James Cole
ec7ef3a813 Various fixes for tests and code quality. 2018-07-20 20:53:48 +02:00
James Cole
49ff6febe5 Fix tests. 2018-07-20 16:28:54 +02:00
James Cole
2d66a9212f Various code cleanup 2018-07-20 14:35:09 +02:00
James Cole
44fb307da4 Code cleanup. 2018-07-20 14:34:56 +02:00
James Cole
cfc2181a48 Show note of piggy bank [skip ci] 2018-07-20 12:17:43 +02:00
James Cole
cf4a846312 Show note of piggy bank [skip ci] 2018-07-20 12:16:01 +02:00
James Cole
633b357d7b Clean up two big methods. 2018-07-19 16:57:38 +02:00
James Cole
b96d67a54e Referenced the wrong array. 2018-07-18 07:29:58 +02:00
James Cole
5b83931b01 Clean up recurrence transformer. 2018-07-18 07:28:35 +02:00
James Cole
f22b54de30 Clean up sandstorm tests. 2018-07-18 07:16:46 +02:00
James Cole
a3306bb26f Leaving only the specials. 2018-07-18 07:16:32 +02:00
James Cole
0adacac269 Remove switches, add if-statement. 2018-07-18 06:58:51 +02:00
James Cole
7359ed2ba2 Updated file list for Sandstorm. 2018-07-18 06:35:27 +02:00
James Cole
5a5f4e8161 Small update for Sandstorm release. 2018-07-18 06:30:56 +02:00
James Cole
b886cc1333 Optimize some code. 2018-07-17 22:21:03 +02:00
James Cole
9299efd086 Fix #1553 2018-07-17 16:36:36 +02:00
James Cole
1502aa3b20 Small code cleanup [skip ci] 2018-07-15 19:17:26 +02:00
James Cole
73e32ecdcb Refer to correct repositories. 2018-07-15 15:45:45 +02:00
James Cole
ac8776aea4 Add annotated methods. 2018-07-15 10:00:08 +02:00
James Cole
7b41c5b301 Cast all translations to strings. 2018-07-15 09:38:49 +02:00
James Cole
369839e012 Clean up references to static Facade. 2018-07-15 09:27:38 +02:00
James Cole
8fde16422e See if this is the solution in Scrutinizer as well. 2018-07-14 23:32:03 +02:00
James Cole
f1462dbd3d Small code quality improvements. 2018-07-14 23:22:08 +02:00
James Cole
5dad569d62 Add some method annotators, see if this helps with Scrutinizer issues. 2018-07-14 23:04:05 +02:00
James Cole
c424bb097d Improve category code quality. 2018-07-14 22:48:22 +02:00
James Cole
e4b1760b20 Remove exit clause from test. 2018-07-14 17:33:10 +02:00
James Cole
780e365a78 Possible fix for #1527 2018-07-14 17:23:44 +02:00
James Cole
3d1523a060 Improve randomness in test data to prevent key collisions. 2018-07-14 16:41:07 +02:00
James Cole
ff403dfa2e Improve code quality in budget methods. 2018-07-14 16:40:46 +02:00
James Cole
89834baf01 Refactor references to static facades. Improve budget controller code. 2018-07-14 16:08:34 +02:00
James Cole
b8699422c8 Refactor budget controller. 2018-07-14 15:22:21 +02:00
James Cole
6bc772d640 Add Facade methods for scrutinizer. 2018-07-14 15:21:05 +02:00
James Cole
0712f30a51 Fix bug in API: missing destroy budget limit method. 2018-07-14 15:16:32 +02:00
James Cole
9116796d90 Refactor account code and tests. 2018-07-14 11:45:05 +02:00
James Cole
a95fdb903b Refactor account controller and some associated tests. 2018-07-14 11:16:12 +02:00
James Cole
2ca6421206 Remove Rabobank description fix from available fixes. 2018-07-14 08:34:27 +02:00
James Cole
cd076cc069 Fix a bug where transfers would be stored reversed (ie. source and destination switched). 2018-07-14 08:33:13 +02:00
James Cole
46482bdae1 Merge tag '4.7.5.1' into develop
4.7.5.1
2018-07-14 07:05:34 +02:00
James Cole
5189c897be Merge branch 'release/4.7.5.1' 2018-07-14 07:05:31 +02:00
James Cole
2c7d25d472 Final changelog. 2018-07-14 06:37:55 +02:00
James Cole
0da370c42d Not really a solution for the test, but might work. 2018-07-13 18:45:11 +02:00
James Cole
6f036d9120 Fix test. 2018-07-13 17:02:23 +02:00
James Cole
260bbd79fd Update composer file. 2018-07-13 16:40:00 +02:00
James Cole
37ad6a3a62 Updated translation. 2018-07-13 16:29:10 +02:00
James Cole
aa25007431 Fixes tests 2018-07-13 16:07:30 +02:00
James Cole
8b33ec1339 Fix a transaction currency bug. 2018-07-13 15:56:06 +02:00
James Cole
cede11ecea Delete old code. 2018-07-13 15:52:27 +02:00
James Cole
2b4088c5f7 Some code cleanup. 2018-07-13 15:50:42 +02:00
James Cole
d872484607 Speed up category tests. 2018-07-13 06:52:53 +02:00
James Cole
f3f2160d96 Update files and languages. 2018-07-13 06:39:50 +02:00
James Cole
bcdb849b46 Update for bug fix release. 2018-07-13 06:12:39 +02:00
James Cole
5846431b34 Various code coverage changes and code updates. 2018-07-12 21:32:58 +02:00
James Cole
0217d9396a Bill must be active when stored. 2018-07-10 20:21:34 +02:00
James Cole
c99e233026 Add some debug entries. 2018-07-09 20:42:16 +02:00
James Cole
f670d930f3 Clean up docker file. 2018-07-09 19:43:08 +02:00
James Cole
0237d78f61 Fix some tests. 2018-07-09 19:42:53 +02:00
James Cole
5665f127aa Improve code quality. 2018-07-09 19:24:08 +02:00
James Cole
76386dad7d Fix #1541 2018-07-09 19:23:19 +02:00
James Cole
42072fdda4 Fix #1452 2018-07-09 05:37:30 +02:00
James Cole
fc80f828be Fix #1538 2018-07-08 15:22:52 +02:00
James Cole
d05a1e0260 Specify return types. 2018-07-08 12:28:42 +02:00
James Cole
b315882f58 Various code cleanup. 2018-07-08 12:08:53 +02:00
James Cole
2f2f907ffe Various code optimalisations. 2018-07-08 07:59:58 +02:00
James Cole
10492e3b2f Expand documentation for Helper directory. 2018-07-07 23:14:16 +02:00
James Cole
8e08ff2d39 Fix the transaction factory and associated tests. 2018-07-07 22:28:08 +02:00
James Cole
e78a59a8a8 Code quality update. 2018-07-07 21:17:46 +02:00
James Cole
cbe47a9dcc Code clean up in Handlers. 2018-07-07 07:48:10 +02:00
James Cole
a1056147d8 Improve code quality and add documentation in folder "Generator" 2018-07-07 07:18:49 +02:00
James Cole
8692590600 Improve code quality for Export directory. 2018-07-06 19:06:08 +02:00
James Cole
57345113b5 Improve code quality for Export directory. 2018-07-06 19:05:27 +02:00
James Cole
52f02cb9eb Fix #1533 2018-07-06 18:43:46 +02:00
James Cole
5d4dcd7e4b Small code optimizations in Exceptions. 2018-07-06 07:37:14 +02:00
James Cole
7d1f4d8907 Improve Events code quality. 2018-07-06 07:19:19 +02:00
James Cole
a76241c7ba Code cleanup and documentation improvements. 2018-07-06 07:15:42 +02:00
James Cole
bdc6678341 Fix unit tests. 2018-07-05 21:44:13 +02:00
James Cole
c99b7e927d Code optimalisations. 2018-07-05 21:18:53 +02:00
James Cole
1675a0d442 Fix unit tests. 2018-07-05 20:15:20 +02:00
James Cole
c0d2cd8962 Fix unit tests. 2018-07-05 19:39:17 +02:00
James Cole
146c9fd947 Fix unit tests. 2018-07-05 19:02:22 +02:00
James Cole
666e9897ea Fix unit test. 2018-07-05 18:42:51 +02:00
James Cole
81d70bd811 Clean up API code. 2018-07-05 18:02:02 +02:00
James Cole
f6f8bb7fd1 Clean up API code. 2018-07-05 06:10:35 +02:00
James Cole
7c3aaf7b7c Fix #1531 2018-07-05 05:53:21 +02:00
James Cole
32ea28f783 Fix #1532 2018-07-05 05:44:49 +02:00
James Cole
17f365941b Merge tag '4.7.5' into develop
4.7.5
2018-07-03 20:33:36 +02:00
James Cole
c2216843d8 Merge branch 'release/4.7.5' 2018-07-03 20:33:34 +02:00
James Cole
339fb5099f Fix test. 2018-07-03 20:33:12 +02:00
James Cole
cf56707b02 Add more fake entropy. 2018-07-03 20:10:14 +02:00
James Cole
19f38aa6ed Updated everything for version 4.7.5 2018-07-03 19:57:38 +02:00
James Cole
9f69e112d0 Last minute fixes. 2018-07-03 19:34:13 +02:00
James Cole
8eb4259be0 Last minute test fixes. 2018-07-03 19:04:46 +02:00
James Cole
d3a1f43cbb Some last-minute fixes. 2018-07-03 18:24:43 +02:00
James Cole
18b06ff283 Some last-minute fixes. 2018-07-03 17:48:26 +02:00
James Cole
53addcf99a Add cron job to docker file. 2018-07-03 06:03:38 +02:00
James Cole
0fa4d75a47 Enable profile for Sandstorm users. 2018-07-03 05:56:46 +02:00
James Cole
2ef86c3339 Add description. 2018-07-03 05:52:35 +02:00
James Cole
d48c3a6d2f Fix tests 2018-07-03 05:52:27 +02:00
James Cole
2260ede559 Add transaction list to recurring transaction 2018-07-03 05:32:35 +02:00
James Cole
5690a44c38 Remove a filter. 2018-07-02 20:41:28 +02:00
James Cole
e36a9fda1b Get a list of transactions belonging to the recurrence. 2018-07-02 20:39:45 +02:00
James Cole
10f195d334 Update versions. 2018-07-02 20:18:00 +02:00
James Cole
54afc6ca8c Some last minute updates. 2018-07-02 20:17:50 +02:00
James Cole
2e67bd3b78 New test code. 2018-07-02 20:02:20 +02:00
James Cole
f27eb084c7 Test the currency exchange controller. 2018-07-02 16:06:49 +02:00
James Cole
7629dfd54a Fix issues with #1521 2018-07-02 15:37:56 +02:00
James Cole
f62fd18b72 Update some translations [skip ci] 2018-07-01 21:40:45 +02:00
James Cole
c6b60ff6b4 Different order for recurrences [skip ci] 2018-07-01 21:32:48 +02:00
James Cole
e9655e6d86 Different order for recurrences [skip ci] 2018-07-01 21:31:27 +02:00
James Cole
3bca9b06f8 Implement category and configuration tests. 2018-07-01 21:27:25 +02:00
James Cole
d97fdc3393 Implement budget limit API tests 2018-07-01 21:02:39 +02:00
James Cole
7dc72f98bf Include tests for budget API 2018-07-01 20:19:34 +02:00
James Cole
da00179066 Test available budget API. 2018-07-01 18:58:41 +02:00
James Cole
89910031cd Test the attachment controller. 2018-07-01 18:31:02 +02:00
James Cole
5676aeac80 Improve test filter. 2018-07-01 16:13:22 +02:00
James Cole
b0b9055e2e Remove extra semi-colon. 2018-07-01 15:48:02 +02:00
James Cole
c0aefed764 Fix extra semicolon in test description 2018-07-01 14:55:06 +02:00
James Cole
e2ec9ca5fb Improve amount conversion code. 2018-07-01 13:34:57 +02:00
James Cole
8e38f5c2c0 Disable amount debit and credit tests. 2018-07-01 12:34:58 +02:00
James Cole
99b2858863 Go for php 7.1.8 to mimic dev machine. 2018-07-01 10:47:54 +02:00
James Cole
b43669e731 Update amount test codes. 2018-07-01 10:32:27 +02:00
James Cole
3bc9905715 Remove php7.2 tests. 2018-07-01 10:19:00 +02:00
James Cole
c55aebd005 Fix credit test. 2018-07-01 10:11:41 +02:00
James Cole
55c331f536 Update read me file. 2018-07-01 09:53:03 +02:00
James Cole
ce236284f4 Update test code. 2018-07-01 09:52:56 +02:00
James Cole
c24cac68f6 Fix for #1518 2018-07-01 09:43:44 +02:00
James Cole
db149ca6e1 Fix tests. 2018-07-01 09:27:22 +02:00
James Cole
0502f2a4a5 Implement rule group API. 2018-06-30 18:10:54 +02:00
James Cole
f13df7e605 Implement rules in API. 2018-06-30 17:49:14 +02:00
James Cole
36a6981329 Halfway rule API. 2018-06-30 16:46:51 +02:00
James Cole
7abcdea816 New translations [skip ci] 2018-06-30 06:16:09 +02:00
James Cole
0509e54a95 Complete API for recurring transactions. 2018-06-30 06:14:39 +02:00
James Cole
b8893bcad7 Fix bulk editor. 2018-06-30 05:54:23 +02:00
James Cole
c9356c1237 Restructure code to rename a variable. 2018-06-30 05:21:21 +02:00
James Cole
2d7b7c2f3f Expand recurring transactions API 2018-06-29 19:27:07 +02:00
James Cole
d0db1117f7 Recurrence first start and API routes. 2018-06-29 14:07:33 +02:00
James Cole
e287e76db5 Complete preferences. 2018-06-29 12:28:29 +02:00
James Cole
8c28c4b5ac New translations and routes. 2018-06-29 12:11:44 +02:00
James Cole
f048e943f8 Implement piggy bank API. 2018-06-29 08:06:17 +02:00
James Cole
12a84572e2 First code for the piggy bank API. 2018-06-29 06:43:44 +02:00
James Cole
c8de1d3372 New (empty) API controllers. 2018-06-28 22:15:22 +02:00
James Cole
234e3f4ca5 Implement link type controller. 2018-06-28 22:14:50 +02:00
James Cole
7749fb1a0b Expand API for journal links. 2018-06-28 17:02:13 +02:00
James Cole
f55d4e32c0 Implement currency exchange rate API. 2018-06-28 07:32:58 +02:00
James Cole
cfd98a33fe Fix #1463 2018-06-28 06:43:59 +02:00
James Cole
7bdf20fee5 Fix #1446 2018-06-28 06:40:04 +02:00
James Cole
e906fa3653 Bot cannot close bug tickets [skip ci] 2018-06-28 06:34:36 +02:00
James Cole
57cf7f6f0d Update some things for recurring transactions. 2018-06-28 06:31:31 +02:00
James Cole
d378e7e897 New translations [skip ci] 2018-06-27 21:37:16 +02:00
James Cole
a8e666db34 Expand view to include weekend responses. 2018-06-27 18:30:53 +02:00
James Cole
7b46339a5d Add some logging to weekly recurring. 2018-06-27 05:40:14 +02:00
James Cole
20aa6e429b Expand support for weekend and add some logging. 2018-06-27 05:37:56 +02:00
James Cole
7ba11a57a8 make sure recurrence can skip weekends. 2018-06-26 21:17:50 +02:00
James Cole
49de4f2200 Expand report email. 2018-06-26 19:26:10 +02:00
James Cole
5d01955133 Various extensions to recurring transactions. 2018-06-26 18:49:33 +02:00
James Cole
7591f3fa29 Send mail message when cron has hit. 2018-06-25 16:01:45 +02:00
James Cole
89f8f9b45b Fix view of bills. 2018-06-24 16:17:42 +02:00
James Cole
59f5b38dca Fix for #1509 2018-06-24 15:43:05 +02:00
James Cole
5b0e61033c Add configuration to Api. 2018-06-24 15:33:36 +02:00
James Cole
096af00a72 Add Category to API 2018-06-24 15:05:59 +02:00
James Cole
dca2dc4600 Add budgets to API. 2018-06-24 14:54:06 +02:00
James Cole
96b482dac5 Fix #1510 2018-06-24 13:59:20 +02:00
James Cole
e05664f34f Fix #1509 2018-06-24 13:46:34 +02:00
James Cole
72cca5ccbf Expand schedule. 2018-06-24 13:23:08 +02:00
James Cole
0b9be029ac Expand API with budget limits 2018-06-24 13:20:29 +02:00
James Cole
91701473af Expand API with available budgets. 2018-06-24 08:33:06 +02:00
James Cole
ad6a9a7df7 Expand API for attachments. 2018-06-24 06:51:22 +02:00
James Cole
32b6ded008 Fix #1505 2018-06-23 19:56:04 +02:00
James Cole
4f2d0a0322 Sentence patch [skip ci] 2018-06-23 17:59:57 +02:00
James Cole
793cfcb2c5 Code for #1503 2018-06-23 17:59:37 +02:00
James Cole
3a71bd01fb Remove dead code. 2018-06-23 17:40:41 +02:00
James Cole
a1d99c1954 Bunq and Spectre will ask to apply rules. 2018-06-23 10:55:26 +02:00
James Cole
19a874b274 Ability to delete recurring transactions. 2018-06-23 08:19:29 +02:00
James Cole
b95dd5c238 Updated language strings [skip ci] 2018-06-23 06:29:14 +02:00
James Cole
7c84af2370 Schedule recurring transactions daily. 2018-06-23 05:41:14 +02:00
James Cole
db1c27d833 First attempt at job to create transactions for recurring transactions. 2018-06-22 18:42:23 +02:00
James Cole
636cd84f4f Merge branch 'develop' of https://github.com/firefly-iii/firefly-iii into develop
* 'develop' of https://github.com/firefly-iii/firefly-iii:
  Change in YunoHost links
2018-06-22 18:40:37 +02:00
James Cole
f2d4fae813 Make sure directories exist #1500 2018-06-22 18:40:06 +02:00
James Cole
986c9ab20a Merge pull request #1499 from anmol26s/patch-2
Change in YunoHost links
2018-06-22 07:44:07 +02:00
anmol26s
cd7e222b72 Change in YunoHost links
As the link was changed, the current link was broken. So fixed it.
2018-06-22 03:05:02 +05:30
James Cole
50b599b1a9 Some refactoring. 2018-06-21 18:58:27 +02:00
James Cole
1d162edb59 Improve code for recurring transactions. 2018-06-21 18:57:51 +02:00
James Cole
7bdd4ddeab Small refactoring. 2018-06-21 18:56:44 +02:00
James Cole
ae6e5a5599 Clean up API references. 2018-06-20 21:17:16 +02:00
James Cole
1222184b68 Include softdelete 2018-06-20 21:16:42 +02:00
James Cole
18f779c6de Various fixes. 2018-06-20 16:27:57 +02:00
James Cole
138f67581c Fix #1483 2018-06-20 16:09:15 +02:00
James Cole
597d6ac513 Fix #1492 2018-06-20 16:06:47 +02:00
James Cole
3ab25c2e8c Merge pull request #1493 from invidian/typo
Fix typo in en_US translations
2018-06-20 15:14:45 +02:00
James Cole
b11d97ba4e Merge pull request #1491 from anmol26s/patch-1
Added support for YunoHost
2018-06-20 15:14:23 +02:00
Mateusz Gozdek
080c810131 Fix typo in en_US translations 2018-06-19 22:20:27 +02:00
James Cole
56bc79d64e Various code to fix checkboxes. 2018-06-18 21:07:09 +02:00
anmol26s
72d2c9d600 Added support for YunoHost
Hi 
I have packaged a Firefly  III app for YunoHost. It has install,remove,update,backup,restore script along with multi-instance(can be installed multiple times on different domains on a single server). The app is tested and works well. 
The CL passing will take a day to show up on the app page.
Thanks for coding this app.
2018-06-18 01:05:02 +05:30
James Cole
0374c32236 Improve code for edit routine #1469 2018-06-17 17:45:47 +02:00
James Cole
d73cd4b515 Can now create recurring transactions. #1469 2018-06-17 15:14:34 +02:00
James Cole
54e3e3f051 Play around with boxes layout. 2018-06-17 07:45:21 +02:00
James Cole
abf218fc21 Prevent empty box. 2018-06-17 07:45:10 +02:00
James Cole
dcf90b6159 Cannot create transfer 2018-06-17 07:44:59 +02:00
James Cole
1cf91c78f8 Lots of new code for recurring transactions. #1469 2018-06-16 21:47:51 +02:00
James Cole
968abd26e8 Extend mail config and help. #1487 2018-06-16 07:23:54 +02:00
James Cole
aa05f7a2d2 Merge branch 'develop' of https://github.com/firefly-iii/firefly-iii into develop
* 'develop' of https://github.com/firefly-iii/firefly-iii:
  Various updated code for recurring transactions.
  Don't report authentication exceptions.
  Fix various bugs in the import routine, discovered by Doug.
  Prevent index error
  Spelcheck plz [skip ci]
  Set demo user back to English at login.
  Add calendar view.
  Demo text for recurring.
  Capital sensitive [skip ci]
  Various code related to the recurring transactions.
  Fix missing variable
  Some code optimalisations.
  First batch of code for recurring transactions #1469
  Fix #1434
  Invalidate cache right after storing data #1478
  Fix #1475
  Remove the option to check for updates from Sandstorm installations.
  Fix #1474
2018-06-15 22:18:53 +02:00
James Cole
181c23b07c Various updated code for recurring transactions. 2018-06-15 22:06:33 +02:00
James Cole
955cde3ed9 Don't report authentication exceptions. 2018-06-14 19:52:20 +02:00
James Cole
477a3c7eb2 Fix various bugs in the import routine, discovered by Doug. 2018-06-13 19:03:18 +02:00
James Cole
f4b66b980b Prevent index error 2018-06-13 08:22:10 +02:00
James Cole
281de63e0d Spelcheck plz [skip ci] 2018-06-12 21:44:03 +02:00
James Cole
c19a700662 Set demo user back to English at login. 2018-06-12 21:41:58 +02:00
James Cole
fc011ba1d9 Add calendar view. 2018-06-12 21:38:05 +02:00
James Cole
b941f590e0 Demo text for recurring. 2018-06-12 19:44:17 +02:00
James Cole
8f4db78ff2 Capital sensitive [skip ci] 2018-06-12 19:03:01 +02:00
James Cole
4b4dc2e298 Various code related to the recurring transactions. 2018-06-12 18:48:15 +02:00
James Cole
2de19547ca Fix missing variable 2018-06-11 11:41:38 +02:00
James Cole
5a058491b0 Some code optimalisations. 2018-06-10 16:59:41 +02:00
James Cole
6743d99d9b First batch of code for recurring transactions #1469 2018-06-10 16:59:03 +02:00
James Cole
35a5ec78c3 Fix #1434 2018-06-10 10:41:45 +02:00
James Cole
3440c3e77a Invalidate cache right after storing data #1478 2018-06-10 07:10:44 +02:00
James Cole
dd17f06362 Fix #1475 2018-06-09 07:09:43 +02:00
James Cole
8a15cb3a34 Remove the option to check for updates from Sandstorm installations. 2018-06-09 06:07:40 +02:00
James Cole
4a548ac282 Fix #1474 2018-06-09 05:50:31 +02:00
James Cole
d22353b13d Update screenshots and Sandstorm files. 2018-06-08 19:35:51 +02:00
James Cole
c18046c25d Update composer libs. 2018-06-06 21:23:17 +02:00
James Cole
4a12d4d156 Code cleanup [skip ci] 2018-06-06 21:23:00 +02:00
James Cole
20044427b4 Use Guzzle, not Requests library. 2018-06-06 21:20:21 +02:00
James Cole
073dedd483 Add debug info 2018-06-06 05:54:24 +02:00
James Cole
06c25c913c Merge branch 'develop' of https://github.com/firefly-iii/firefly-iii into develop
* 'develop' of https://github.com/firefly-iii/firefly-iii:
  Still not sure what's causing the empty strings to appear.
2018-06-05 14:56:10 +02:00
James Cole
08d06cf465 Small updates to meta files [skip ci] 2018-06-05 07:57:18 +02:00
James Cole
1e9eb843c0 Still not sure what's causing the empty strings to appear. 2018-06-03 19:14:03 +02:00
James Cole
78a5dae2a0 Merge branch 'release/4.7.4' 2018-06-03 09:16:56 +02:00
James Cole
19443a5b34 Update readme [skip ci] 2018-06-03 09:11:18 +02:00
James Cole
74acc90702 Update readme [skip ci] 2018-06-03 09:08:24 +02:00
James Cole
349f580371 Update readme [skip ci] 2018-06-03 09:07:41 +02:00
James Cole
f019d33a03 New screenshots [skip ci] 2018-06-03 09:04:57 +02:00
James Cole
c7af25ac38 Fix last minute issues. 2018-06-03 08:23:49 +02:00
James Cole
b52bd59cea Upgrade various files for 4.7.4 [skip ci] 2018-06-02 20:05:39 +02:00
James Cole
332d32c319 Fix tests 2018-06-02 20:02:42 +02:00
James Cole
2f824ba1a8 Some more last-minute fixes. 2018-06-02 19:23:46 +02:00
James Cole
a6b09acd5e Some last minute fixes. 2018-06-02 18:19:35 +02:00
James Cole
d4779c8c8f Some last minute translations [skip ci] 2018-06-02 07:15:21 +02:00
James Cole
ba01c4bbe8 Ignore basic methods, improving code coverage. 2018-06-02 06:18:07 +02:00
James Cole
ddc1d81665 Fix tests, improve coverage. 2018-06-02 06:11:13 +02:00
James Cole
790aeb3c46 Fix #1458 2018-06-02 05:46:37 +02:00
James Cole
6ed5be10b1 Expand test coverage. 2018-06-01 22:20:08 +02:00
James Cole
a7b8470d9e Expand test coverage. 2018-06-01 22:04:52 +02:00
James Cole
2a05cc382f Update Turkish language files [skip ci] 2018-06-01 14:22:53 +02:00
James Cole
1e10a6ce1b Update Russian language files [skip ci] 2018-06-01 14:22:37 +02:00
James Cole
7645ef55c2 Update PT_BR language files [skip ci] 2018-06-01 14:22:19 +02:00
James Cole
6ce200b60d Update Polish language files [skip ci] 2018-06-01 14:22:08 +02:00
James Cole
d782e28906 Update Dutch language files [skip ci] 2018-06-01 14:21:54 +02:00
James Cole
da3bd31fb8 Update Italian language files [skip ci] 2018-06-01 14:21:27 +02:00
James Cole
aa3ed40430 Update Indonesian language files [skip ci] 2018-06-01 14:21:14 +02:00
James Cole
ad7e564f14 Update French language files [skip ci] 2018-06-01 14:20:52 +02:00
James Cole
f23ee2dac5 Update Spanish language files [skip ci] 2018-06-01 14:20:39 +02:00
James Cole
1962f74439 Update German language files [skip ci] 2018-06-01 14:20:17 +02:00
James Cole
0064d060ea Show bunq payment ID. #1443 2018-06-01 13:14:51 +02:00
James Cole
e47e6b1958 Fix null pointer. #1443 2018-06-01 13:11:23 +02:00
James Cole
4c04415e80 Fix #1452. 2018-06-01 13:11:10 +02:00
James Cole
3654e75b8c Improve test coverage. 2018-06-01 06:40:24 +02:00
James Cole
66fa73aea4 Fix tests. 2018-06-01 05:49:41 +02:00
James Cole
df87d03f32 FF3 will apply rules when importing from bunq #1443 2018-06-01 05:49:33 +02:00
James Cole
3fbe851a0b Include external ID with import. 2018-06-01 05:23:57 +02:00
James Cole
d1b2e63950 Small fixes for import routine. 2018-05-31 22:33:42 +02:00
James Cole
34fd8cf751 Fix #1442 2018-05-31 21:48:09 +02:00
James Cole
f1fe90fce0 Fix #1455 2018-05-31 21:30:25 +02:00
James Cole
2ba6fa0dda Add description to debug logging. #1443 2018-05-31 21:13:07 +02:00
James Cole
f2928e3d7d Possible fix for #1453 2018-05-31 20:34:49 +02:00
James Cole
895ab9c5d8 Updated lock file. 2018-05-31 20:34:32 +02:00
James Cole
fb07c68132 Updated tests 2018-05-31 20:04:19 +02:00
James Cole
68e7d45f63 Fix #1451 2018-05-30 18:38:39 +02:00
James Cole
49e302e1bc Reinstate ability to download config. 2018-05-30 18:36:21 +02:00
James Cole
b33ca786ae use cases for rules tested. 2018-05-30 18:05:06 +02:00
James Cole
dc77d8edda Extra upgrade instructions. 2018-05-30 18:04:53 +02:00
James Cole
c339a183b9 Fix code coverage and a test #1443 2018-05-30 18:04:43 +02:00
James Cole
f263795a99 Add config entries for tests 2018-05-30 18:04:23 +02:00
James Cole
e9e771e57b List 100 entries for bunq. #1443 2018-05-30 18:04:00 +02:00
James Cole
fbb9d7c6b4 It's about expecting JSON, not accepting it. 2018-05-29 18:33:43 +02:00
James Cole
10abd7b0ae Delete account meta data when field is made empty. 2018-05-29 18:31:48 +02:00
James Cole
3de36901b8 Fix #1425 2018-05-29 07:25:04 +02:00
James Cole
5b4967acb9 Changes in error handler 2018-05-29 07:09:11 +02:00
James Cole
0a007b1e6e Fix menu view. 2018-05-29 06:30:25 +02:00
James Cole
4ad68b7dfa Fix #1449 2018-05-28 19:07:06 +02:00
James Cole
73aef1b9a4 Code for #1415 2018-05-26 13:55:11 +02:00
James Cole
dcfea20973 Expand error logs. 2018-05-26 13:14:51 +02:00
James Cole
9b6766d3b2 Fix #1416 2018-05-26 08:04:50 +02:00
James Cole
b8bc8e2c47 Fix #1413 2018-05-26 07:58:36 +02:00
James Cole
039e3aa34c Fix for #1406 2018-05-26 07:55:31 +02:00
James Cole
551ff109c9 Fixed #1403 2018-05-26 07:53:32 +02:00
James Cole
664451d0c6 Fixed #1405 2018-05-26 07:48:49 +02:00
James Cole
4031057bc0 Fix #1386 2018-05-26 07:25:22 +02:00
James Cole
fcf9b782c1 Improve code coverage. #1443 2018-05-25 23:13:08 +02:00
James Cole
d693d382b9 Handle different account types #1443 2018-05-25 17:31:41 +02:00
James Cole
0a1b6c7793 Catch nullpointer #1443 2018-05-25 13:15:36 +02:00
James Cole
5acba2bddf Merge branch 'develop' of https://github.com/firefly-iii/firefly-iii into develop
* 'develop' of https://github.com/firefly-iii/firefly-iii:
  Revert "Updated git ignore. (firefly-iii/firefly-iii#1443)"
  Update curl to latest version. (firefly-iii/firefly-iii#1443)
  Install composer before updating curl. (firefly-iii/firefly-iii#1443)
  Added missing new line at EOF. (firefly-iii/firefly-iii#1443)
  Updated libpng and added wget. (firefly-iii/firefly-iii#1443)
  Updated git ignore. (firefly-iii/firefly-iii#1443)
2018-05-25 12:08:43 +02:00
James Cole
883b16fad1 Fix IBAN selection. 2018-05-25 12:08:15 +02:00
James Cole
ef48b3e751 Merge pull request #1445 from OGKevin/update-curl-in-docker-firefly-iii/firefly-iii#1443
Update curl in docker firefly-iii/firefly-iii#1443
2018-05-25 11:48:00 +02:00
Kevin Hellemun
3c956e7e98 Revert "Updated git ignore. (firefly-iii/firefly-iii#1443)"
This reverts commit 656bb5043d.
2018-05-25 11:22:06 +02:00
Kevin Hellemun
519ea271a9 Update curl to latest version. (firefly-iii/firefly-iii#1443) 2018-05-25 10:10:08 +02:00
Kevin Hellemun
09d5160404 Install composer before updating curl. (firefly-iii/firefly-iii#1443) 2018-05-25 10:09:54 +02:00
Kevin Hellemun
97dcf03334 Added missing new line at EOF. (firefly-iii/firefly-iii#1443) 2018-05-25 10:07:09 +02:00
Kevin Hellemun
896a804a72 Updated libpng and added wget. (firefly-iii/firefly-iii#1443) 2018-05-25 10:06:45 +02:00
Kevin Hellemun
656bb5043d Updated git ignore. (firefly-iii/firefly-iii#1443) 2018-05-25 10:05:57 +02:00
James Cole
e953becbae Expand test coverage for bunq. 2018-05-25 08:38:15 +02:00
James Cole
6c9901b919 Redirect correctly. 2018-05-25 08:33:59 +02:00
James Cole
ff45c94106 Test coverage for routine and prerequisites. 2018-05-25 06:29:51 +02:00
James Cole
a8a3fbeef4 Write bunq lowercase. 2018-05-25 06:27:40 +02:00
James Cole
dae8092ecd Add return call so the error is not called. 2018-05-25 06:27:32 +02:00
James Cole
70110208fc Use non-static class for ApiContext to improve testability. 2018-05-25 06:26:37 +02:00
James Cole
217ca98933 Update composer lock + json 2018-05-25 06:26:10 +02:00
James Cole
c2945c532e Testing environment always uses the sandbox. 2018-05-25 06:25:59 +02:00
James Cole
ea750576b3 Move to bitly shortlinks. 2018-05-23 14:31:12 +02:00
James Cole
82538ba4fc Catch OpenSSL error. 2018-05-23 14:08:37 +02:00
James Cole
2b2f37a8c9 All code for bunq. 2018-05-23 12:36:12 +02:00
James Cole
4db2ec60e0 Update composer files. 2018-05-23 08:41:15 +02:00
James Cole
7d88d35556 Fix test for coverage. 2018-05-23 08:38:05 +02:00
James Cole
3c3e91ff48 Deprecate and ignore bunq code. 2018-05-23 07:38:27 +02:00
James Cole
039e8d6e17 Add debug info and update routine for multiple accounts. 2018-05-23 07:38:03 +02:00
James Cole
50bf79ab18 Ignore bunq objects. 2018-05-22 18:55:30 +02:00
James Cole
467c6762fa Catch all edge cases. 2018-05-22 18:42:34 +02:00
James Cole
740f4e403f Improve coverage for Spectre 2018-05-22 18:05:35 +02:00
James Cole
5664d51695 Fix #1439 2018-05-21 20:04:30 +02:00
James Cole
b195a61498 Improve coverage for Spectre. 2018-05-21 19:17:33 +02:00
James Cole
94e6816bf6 Improve test coverage. 2018-05-21 17:28:09 +02:00
James Cole
ebf97f710f Refactor code and fix tests. 2018-05-21 09:40:19 +02:00
James Cole
714b54ed06 Refactor and rename test code. 2018-05-21 07:22:38 +02:00
James Cole
620c5f515e Improve test coverage, remove dead code. 2018-05-20 16:26:27 +02:00
James Cole
c06fd12b07 Fix test coverage. 2018-05-19 22:23:08 +02:00
James Cole
2c206bba64 First working version of a working Spectre import. 2018-05-19 21:13:00 +02:00
James Cole
04953b5645 Lots of new code for the Spectre routine. 2018-05-19 10:44:33 +02:00
James Cole
1732ce63f3 Merge branch 'hotfix/4.7.3.2' into develop 2018-05-16 21:55:42 +02:00
James Cole
1e212c6da2 Merge branch 'hotfix/4.7.3.2' 2018-05-16 21:55:41 +02:00
James Cole
7d8fc54351 Fix version number. 2018-05-16 21:55:24 +02:00
James Cole
dd44a1e517 Code for Spectre. 2018-05-16 21:31:45 +02:00
James Cole
9f26757e8a First code for Spectre login and import routine. 2018-05-14 20:21:00 +02:00
James Cole
a9c8c8384d Merge branch 'hotfix/4.7.3.1' into develop 2018-05-14 19:24:54 +02:00
James Cole
a826b0e0fb Merge branch 'hotfix/4.7.3.1' 2018-05-14 19:24:53 +02:00
James Cole
4aaec0e379 Fix an issue where new users would be given a rule that always triggers. 2018-05-14 19:24:35 +02:00
James Cole
69019d5215 First code for Spectre import. 2018-05-14 17:59:43 +02:00
James Cole
96411b17e9 Fix tests, improve demo text. 2018-05-13 16:04:53 +02:00
James Cole
5a093b58d8 Prep for bunq and spectre import. 2018-05-13 15:00:30 +02:00
James Cole
470b3e0973 Remove middleware [skip ci] 2018-05-13 09:58:21 +02:00
James Cole
dc251c216c Add debug log [skip ci] 2018-05-13 09:51:05 +02:00
James Cole
ae9ef61f80 Add debug log [skip ci] 2018-05-13 09:47:51 +02:00
James Cole
d9ca7b7277 Better error messages [skip ci] 2018-05-13 09:39:06 +02:00
James Cole
0c99248deb Fix rules surrounding creation of jobs [skip ci] 2018-05-13 09:34:27 +02:00
James Cole
1aae84a4d0 Optimise tests and coverage. 2018-05-13 09:01:10 +02:00
James Cole
528da3f08e Allow the mapping of asset accounts for opposing value 2018-05-12 20:56:34 +02:00
James Cole
9c507f7f62 Refactor some code to handle command line imports. 2018-05-12 19:09:34 +02:00
James Cole
07da2fdda3 Remove unused imports. 2018-05-12 17:27:19 +02:00
James Cole
ca3366544e Add file used to test UTF8 check. 2018-05-12 16:54:07 +02:00
James Cole
ccee7b483c Fix tests 2018-05-12 16:04:46 +02:00
James Cole
5903133e3b Remove return type. 2018-05-12 15:54:20 +02:00
James Cole
5bf520b6ed Code consistency and new tests. 2018-05-12 15:50:01 +02:00
James Cole
a47da92d81 Test coverage for opposing account mapper. 2018-05-12 13:27:02 +02:00
James Cole
63f84ae7b1 Lots of refactoring and new tests. 2018-05-12 10:46:18 +02:00
James Cole
4d6bc55723 Update test code. 2018-05-11 19:58:10 +02:00
James Cole
9bb4df4cc3 Split and cleanup file import routine. 2018-05-11 19:56:52 +02:00
James Cole
c47a5379ae Improve code test coverage. 2018-05-11 10:37:13 +02:00
James Cole
cde9c4a2bc Update copyright statements. 2018-05-11 10:08:34 +02:00
James Cole
5a560b42ef Improve test coverage. 2018-05-11 09:51:47 +02:00
James Cole
50874c9cf7 Rename some variables. 2018-05-10 23:11:11 +02:00
James Cole
6f984aa591 Improve test coverage. 2018-05-10 23:01:21 +02:00
James Cole
274162afcd Fix test that could come up with journals with 0 transactions, and improve test coverage for file routine. 2018-05-10 20:05:02 +02:00
James Cole
6bd23d897f Try to get details about OAuth exceptions. 2018-05-10 09:48:13 +02:00
James Cole
73f29ebf69 make sure class is compatible with interface. 2018-05-10 09:18:40 +02:00
James Cole
cabcb9c6d0 Basic storage routine works, basic file handling. 2018-05-10 09:10:16 +02:00
James Cole
116f7ed613 First attempt to run file import. 2018-05-10 06:26:57 +02:00
James Cole
6ef0eb73d0 Improve importer. 2018-05-09 20:53:39 +02:00
James Cole
7f4feb0cfc More code for import routine. 2018-05-07 20:35:14 +02:00
James Cole
626f7357bb Improve CSV import routine. 2018-05-07 19:21:12 +02:00
James Cole
690c9203c8 Start processing files. 2018-05-06 21:06:23 +02:00
James Cole
1209f3b39a First start for CSV file import. 2018-05-06 20:42:30 +02:00
James Cole
a4524b3c2c Throw exception with empty amount. 2018-05-06 20:42:07 +02:00
James Cole
a3cbdadb39 Towards managing mapping for file imports. 2018-05-06 16:19:29 +02:00
James Cole
9e3c5fd984 Remove references to non-existing files. 2018-05-06 07:40:50 +02:00
James Cole
7d80ac37a6 Can configure file upload in file imports. 2018-05-06 07:09:08 +02:00
James Cole
f74b9ba7ab Add strict types and newlines. 2018-05-05 16:51:32 +02:00
James Cole
3ac240dc1c Add some randomness to test data. 2018-05-05 15:18:41 +02:00
James Cole
d233b3f24f Improve test (coverage). 2018-05-05 14:40:12 +02:00
James Cole
19fff681d2 Improve test coverage, mark as deprecated. 2018-05-05 13:53:12 +02:00
James Cole
bc7c3bb9b3 Improve test coverage and remove deprecated code. 2018-05-05 11:03:10 +02:00
James Cole
57be7f2905 Fix test coverage, ignore all other routines. 2018-05-05 06:47:35 +02:00
James Cole
1c0da454db Improved code for new import + some tests. 2018-05-04 20:21:27 +02:00
James Cole
b541f7b944 Improve fake import. 2018-05-04 06:59:14 +02:00
James Cole
6e84326583 Fix #1418 2018-05-04 06:00:16 +02:00
James Cole
ca14496e4e First code for file import. 2018-05-03 22:20:06 +02:00
James Cole
480d65fc1f Fake import works, won't fire rules yet. also needs a state. 2018-05-03 18:17:59 +02:00
James Cole
6bddb63b45 New code for updated import routine. 2018-05-03 17:23:16 +02:00
James Cole
c5142aeba5 Merge branch 'develop' of github.com:firefly-iii/firefly-iii into develop 2018-05-03 17:22:34 +02:00
James Cole
38d9f10672 New issue templates. 2018-05-03 16:53:52 +02:00
James Cole
937394af7a Merge pull request #1409 from shashankmc/develop
Adding Indian rupee
2018-05-03 07:27:51 +02:00
Shashank M Chakravarthy
fe10955eb9 Adding Indian rupee
Adding Indian rupee under asian currencies.
2018-05-03 10:56:09 +05:30
James Cole
ccda71ff8e New code for updated import routine. 2018-05-01 20:47:38 +02:00
James Cole
cd75224cdd Create a fake routine, check for its progress. 2018-04-30 06:37:29 +02:00
James Cole
1c2089b8a3 Fixes #1400 2018-04-30 06:17:27 +02:00
James Cole
3ead4d4587 List rules as inactive if relevant #1392 2018-04-30 06:12:55 +02:00
James Cole
f2b71bc280 Fake jobs can be started and will crash. 2018-04-29 21:20:06 +02:00
James Cole
f027d71136 Fake jobs can be configured and can reach the landing stage. 2018-04-29 20:01:03 +02:00
James Cole
fa41d6df04 Clean up translations and strings in import routine. 2018-04-29 19:28:07 +02:00
James Cole
d2bb65bf04 Can now create jobs, and set prerequisites for the fake provider, which will be skipped when they're not necessary. 2018-04-29 19:07:54 +02:00
James Cole
b5be1b11d1 Update index and routes. 2018-04-29 18:07:58 +02:00
James Cole
9fb049991f Migration for 4.7.4 2018-04-29 18:07:47 +02:00
James Cole
fba847dd28 New bindable for import provider 2018-04-29 18:07:38 +02:00
James Cole
b33883b334 Small code improvements. 2018-04-29 18:07:23 +02:00
James Cole
f74a6dffca Update providers and repositories for new import job fields 2018-04-29 18:07:14 +02:00
James Cole
7390e20218 Add method to indicate completeness. 2018-04-29 18:06:47 +02:00
James Cole
9646dc439e Big fat reset in import controller to accomodate new routine. 2018-04-29 18:06:31 +02:00
James Cole
554c63b9c7 Expand config to handle new providers 2018-04-29 18:03:55 +02:00
James Cole
24d8640e9b Add logos for new providers. 2018-04-29 18:03:35 +02:00
James Cole
ea151d069c Merge pull request #1401 from paul999/select_bunq_option
Select the matching bunq account from the import. Fixes #1398
2018-04-29 17:32:07 +02:00
Paul Sohier
f140d2f37a Select the matching bunq account from the import. Fixes #1398 2018-04-29 16:26:19 +02:00
James Cole
4e163c4bda Merge pull request #1395 from nicoschreiner/patch-1
Fix alignment of sidebar-icons
2018-04-29 14:08:24 +02:00
Nico Schreiner
ddcf8b892b Fix alignment of sidebar-icons
I noticed a minor thing which was bothering me. The Icons in the sidebar weren't align correctly (the fa-repeat icon). This change should fix this.
2018-04-29 13:28:49 +02:00
James Cole
49138eb03a Can now import and handle external ID field. 2018-04-29 10:13:33 +02:00
James Cole
71b63bd33b Remove references to ExpandedForm. 2018-04-29 09:48:53 +02:00
James Cole
88348f59c2 Could repair #1389 2018-04-29 09:00:49 +02:00
James Cole
7eb5643204 Use new select options. 2018-04-29 07:46:30 +02:00
James Cole
565cb6d79e New select options 2018-04-29 07:46:14 +02:00
James Cole
c0d715c78a Add method to collect note text. 2018-04-29 07:46:03 +02:00
James Cole
a3d0355ddd Use new expanded for method. 2018-04-29 07:45:54 +02:00
James Cole
bc4e06568d Move references to repository 2018-04-29 07:45:38 +02:00
James Cole
8acb9f4056 Fix error when un-decryptable files would break the export. 2018-04-29 07:42:17 +02:00
James Cole
9cbbd581ee Rename template file. 2018-04-29 07:42:01 +02:00
James Cole
fdc9467218 Fix #1369 2018-04-28 21:54:48 +02:00
James Cole
84ac3df580 Merge branch 'release/4.7.3' 2018-04-28 16:27:55 +02:00
James Cole
7f459df9e9 Last minute sanity check. 2018-04-28 16:24:24 +02:00
James Cole
3625f3293a Code for 4.7.3 release. 2018-04-28 15:35:43 +02:00
James Cole
0a2308592f New language strings. 2018-04-28 15:26:45 +02:00
James Cole
8ef3f18da7 Update language strings for English. 2018-04-28 10:29:31 +02:00
James Cole
e126427809 Improve code quality and fix test coverage. 2018-04-28 10:27:33 +02:00
James Cole
7b39828980 Improve attachment list. 2018-04-28 06:53:37 +02:00
James Cole
d03de52735 New buttons and links [skip ci] 2018-04-28 06:44:37 +02:00
James Cole
cabe90b2dd Attachment controller basic index. 2018-04-28 06:34:01 +02:00
James Cole
13b78bdc20 Code cleanup 2018-04-28 06:23:13 +02:00
James Cole
6f0e1c79ac Fix #1353 2018-04-28 05:42:47 +02:00
James Cole
b66daad3d3 Fix coverage. 2018-04-28 05:40:23 +02:00
James Cole
9c5523252d Clean up old JS. 2018-04-28 05:40:08 +02:00
James Cole
bc8bcf7a1a Upgrade spectre to v4 2018-04-28 05:25:29 +02:00
James Cole
85d655d3e2 Upgrade Spectre to v4 2018-04-27 13:07:46 +02:00
James Cole
ac419e01d3 Catch open basedir errors. 2018-04-27 12:58:43 +02:00
James Cole
5d4467a6c0 Improve test speed. 2018-04-27 12:39:25 +02:00
James Cole
81da7f3667 Move to correct directory [skip ci] 2018-04-27 11:53:22 +02:00
James Cole
9734196eb9 Updated translations. 2018-04-27 11:48:52 +02:00
James Cole
7e0f9b9b8e Update packages. 2018-04-27 11:29:19 +02:00
James Cole
bb25132865 Fix tests 2018-04-27 11:29:09 +02:00
James Cole
28bcff99f6 Add config for stale bot. 2018-04-27 08:50:49 +02:00
James Cole
246cb36836 Expand support for trusted proxies configuration. 2018-04-27 07:01:03 +02:00
James Cole
9a0c0f6d21 Fix #1383 2018-04-27 06:50:41 +02:00
James Cole
a9dd8eb9e7 Fix #1382 2018-04-27 06:26:37 +02:00
James Cole
9026c9d6f1 Update docker file. 2018-04-26 21:16:45 +02:00
James Cole
d5f7430723 Move and update security txt [skip ci] 2018-04-26 21:00:29 +02:00
James Cole
5a53249fbb Merge pull request #1380 from paul999/fix_1378
iban returned from bunq might be empty.
2018-04-25 19:16:12 +02:00
Paul Sohier
d2848cf569 getIban might return null from the bunq API. Fixes #1378 as it gets imported now :) 2018-04-25 19:11:32 +02:00
James Cole
71f39f55f2 Push some more fixes for #1378 2018-04-25 17:02:43 +02:00
James Cole
490c817fc1 Some fixes for #1378 2018-04-25 16:01:51 +02:00
James Cole
2e1a777811 Fix small deprecated function call. [skip ci] 2018-04-24 19:49:54 +02:00
James Cole
48357d1cc9 Fix #1273 and #1272 2018-04-24 19:48:42 +02:00
James Cole
846df21764 Fix #1372 2018-04-24 19:26:31 +02:00
James Cole
f78b8f9267 Some code for #1272 2018-04-24 19:26:16 +02:00
James Cole
798d9ee876 Mail to logbooks. 2018-04-24 19:23:32 +02:00
James Cole
1eea81e9dd Update readme [skip ci] 2018-04-22 19:18:57 +02:00
James Cole
4fcdfd41fa Update readme [skip ci] 2018-04-22 19:17:43 +02:00
James Cole
36a5f17af2 Code cleanup as described in #1272 2018-04-22 17:12:22 +02:00
James Cole
8032684ad0 Some code cleanup for #1272 2018-04-22 17:10:11 +02:00
James Cole
f7d3d4a010 Updated language strings [skip ci] 2018-04-22 13:14:36 +02:00
James Cole
9975e0b3f3 And now without var_dump. 2018-04-22 12:01:34 +02:00
James Cole
ea484a7787 Small bill related fixes. 2018-04-22 12:01:18 +02:00
James Cole
c2e8a67330 Code for #1367 2018-04-22 11:29:20 +02:00
James Cole
8f3e4a2dee Code for #1356 2018-04-22 11:17:30 +02:00
James Cole
07768a43c8 Code for #1321 2018-04-22 09:40:03 +02:00
James Cole
01c10e320c Fix for #1364 2018-04-22 09:16:51 +02:00
James Cole
f16b2257c6 Custom input for amount. 2018-04-22 08:08:09 +02:00
James Cole
e005fe7ce1 Also show foreign amount. 2018-04-22 08:07:57 +02:00
James Cole
c682e69ee7 Keep order 2018-04-22 08:07:46 +02:00
James Cole
49421f50ac Will not store fields with empty strings or weird value 2018-04-22 08:07:33 +02:00
James Cole
529dd490b7 Fix #1336 2018-04-22 07:16:09 +02:00
James Cole
36329e596e Fix #1334 2018-04-21 23:48:54 +02:00
James Cole
fb75e2ef02 Move to MariaDB. [skip ci] #1366 2018-04-21 21:09:56 +02:00
James Cole
352171e339 New language strings [skip ci] 2018-04-21 20:48:18 +02:00
James Cole
592901b143 Code for @1346 2018-04-21 20:36:42 +02:00
James Cole
769b4819b2 Add timezone to Docker file. 2018-04-21 20:30:36 +02:00
James Cole
77fa2bcc39 Call test at wrong position [skip ci] 2018-04-21 20:30:07 +02:00
James Cole
1129001bc6 Possible solution for #1353 2018-04-21 20:29:44 +02:00
James Cole
8dd765ee89 Remove deprecated method. 2018-04-21 20:28:41 +02:00
James Cole
479648e7c1 Fix #1352 2018-04-21 20:28:30 +02:00
James Cole
45cd19d1e3 Fix #1363 2018-04-21 20:27:35 +02:00
James Cole
f8718e0b7b Fix some issues with verify database code. 2018-04-21 20:26:41 +02:00
James Cole
dcc45631da New language strings [skip ci] 2018-04-19 20:04:04 +02:00
James Cole
c6d3a5bedc Code for #1351 2018-04-19 20:03:02 +02:00
James Cole
7cc8539298 Fix for #1349, thanks to @NyKoF 2018-04-19 18:27:39 +02:00
James Cole
900e8202e6 Remove some deprecated functions. 2018-04-16 20:21:28 +02:00
James Cole
eb6ac7d1d1 Remove unused methods. 2018-04-16 20:12:30 +02:00
James Cole
178f917a49 Fix #1348 2018-04-16 19:29:26 +02:00
James Cole
1a8293d9ef Fix view for transaction controller. 2018-04-16 19:25:33 +02:00
James Cole
ecdc00dcb7 Debug code for transaction view. [skip ci] 2018-04-16 19:24:46 +02:00
James Cole
147e04ecd2 Debug code for transaction view. [skip ci] 2018-04-16 18:06:53 +02:00
James Cole
49e48725a5 Debug code for transaction view. [skip ci] 2018-04-16 18:03:56 +02:00
James Cole
b3af744041 Debug code for transaction view. [skip ci] 2018-04-16 18:02:35 +02:00
James Cole
58a6a95d90 Debug code for transaction view. [skip ci] 2018-04-16 17:59:35 +02:00
James Cole
1aa9461370 Fix reference to unknown method. 2018-04-16 17:51:37 +02:00
James Cole
1f78b9d4bc Add today as well. #1328 2018-04-15 19:24:20 +02:00
James Cole
6f974fe285 Improve API and test coverage. 2018-04-15 19:20:24 +02:00
James Cole
f4f3c8798e Fix for #1328 2018-04-15 19:20:04 +02:00
James Cole
ce1614f4e7 Fix chart range. 2018-04-15 19:11:10 +02:00
James Cole
91494584c2 Fix #1327 2018-04-15 17:58:39 +02:00
James Cole
a85ebb49b2 Improve test coverage. 2018-04-15 14:03:23 +02:00
James Cole
ae273f8320 Also test PHP 7.2 2018-04-15 10:44:47 +02:00
James Cole
ef62e31b61 Fix #1246 2018-04-15 10:12:04 +02:00
James Cole
0c2c5d5344 Code for #1326 2018-04-15 08:52:58 +02:00
James Cole
11e93eac3d Merge pull request #1341 from bconte/develop
Remove the 'php artisan optimize' line from .deploy/docker/entroypoin…
2018-04-15 08:52:04 +02:00
Brenden Conte
dbe17debb4 Remove the 'php artisan optimize' line from .deploy/docker/entroypoint.sh because the command was removed in artisan 5.6 2018-04-15 02:35:47 -04:00
James Cole
6c12337317 Improve transaction linking [skip ci] 2018-04-14 23:25:28 +02:00
James Cole
b2aa73b31e Improve transaction linking [skip ci] 2018-04-14 23:23:47 +02:00
James Cole
38b1fc7aa6 Improve logging [skip ci] 2018-04-14 23:12:54 +02:00
James Cole
f4afcb4d50 Add debug logging [skip ci] 2018-04-14 23:09:24 +02:00
James Cole
4b019fe38b Limit scope in transaction matcher. 2018-04-14 23:06:27 +02:00
James Cole
191401f32b Fix division by zero. 2018-04-14 22:37:20 +02:00
James Cole
62b68c6a21 Fix tests. 2018-04-14 21:21:20 +02:00
James Cole
15a22f0bfc Expand rules and bills. 2018-04-14 20:31:31 +02:00
James Cole
926c03986c Remove references to bill scanning. 2018-04-14 13:00:24 +02:00
James Cole
d8a00f4314 Various code for bills and rules. 2018-04-14 09:59:04 +02:00
James Cole
5862b832d9 Fix issue with API 2018-04-14 09:38:58 +02:00
James Cole
67fa4a0fc7 Add currency controls to API 2018-04-13 17:28:11 +02:00
James Cole
90cf7a3bf5 Fix several issues with bunq import #1330 2018-04-10 21:18:38 +02:00
James Cole
0847040017 Correct access rights #1320 2018-04-09 18:59:06 +02:00
James Cole
69b577048e New string [skip ci] 2018-04-08 18:35:13 +02:00
James Cole
3fbd2f93c8 Code for #1324 2018-04-08 17:36:37 +02:00
James Cole
8f0e36a8e4 Code for #1324 2018-04-08 16:27:52 +02:00
James Cole
7583698ee5 Remove hard exit from upgrade routine. 2018-04-08 16:26:26 +02:00
James Cole
b561e79a6c Catch null in currency pref. [skip ci] 2018-04-08 16:21:17 +02:00
James Cole
5850ad06b1 More debug [skip ci] 2018-04-08 16:18:35 +02:00
James Cole
e597f04b0d Add debug logging. 2018-04-08 16:17:29 +02:00
James Cole
7b715925cf Code for #1324 2018-04-07 22:23:16 +02:00
James Cole
d3701837e3 Possible fix for #1325 2018-04-07 18:00:09 +02:00
James Cole
7af10aca9e Add new action to link a transaction to a bill. 2018-04-07 06:20:45 +02:00
James Cole
b54e99642b Refactor some auto complete routes. 2018-04-07 06:19:40 +02:00
James Cole
b1ad0668cc Clean overview for bills. 2018-04-07 05:58:59 +02:00
James Cole
6583d0f69b Fix JS in installer. 2018-04-07 05:30:29 +02:00
James Cole
cee6bbf134 Update files for Sandstorm. 2018-04-06 22:24:57 +02:00
James Cole
43e49bf14a Fire middleware on index. 2018-04-06 21:38:43 +02:00
James Cole
371b58a807 Make upgrade routine not trigger everywhere. 2018-04-06 21:38:17 +02:00
James Cole
7812a1bb51 Fix for #1320 2018-04-06 18:14:48 +02:00
James Cole
538e045e4c Give error for proc_close. 2018-04-06 13:36:36 +02:00
James Cole
91fe1493a7 Improve edit routine for split transactions. 2018-04-06 12:44:43 +02:00
James Cole
4650a2ea52 Merge branch 'release/4.7.2.2' 2018-04-04 19:26:51 +02:00
James Cole
7cd51a7747 Update version. 2018-04-04 19:18:59 +02:00
James Cole
b55545b959 Fix #1317 2018-04-04 19:18:01 +02:00
James Cole
2685256c93 Fix split edit. 2018-04-04 19:15:05 +02:00
James Cole
3819de4e74 Fix security issue with markdown, thanks to @simhnna 2018-04-04 19:14:47 +02:00
James Cole
73fee4eb6b Fix #1313 2018-04-03 19:15:06 +02:00
James Cole
609c193b88 Fix #1312 2018-04-03 19:12:59 +02:00
James Cole
03a42976b1 Configure logging for Slack. [skip ci] 2018-04-02 20:05:18 +02:00
James Cole
6db0efdfbc Fix extremely specific piggy bank percentage. 2018-04-02 17:30:30 +02:00
James Cole
ebbbe1a620 Merge branch 'release/4.7.2.1' 2018-04-02 16:52:23 +02:00
James Cole
5d1c77cb16 New version: 4.7.2.1 2018-04-02 15:40:43 +02:00
James Cole
d48fb3ba55 Create keys by hand if not existing. 2018-04-02 15:26:33 +02:00
James Cole
8c024a1ae9 Create default token if none exist. 2018-04-02 15:17:03 +02:00
James Cole
a3c34e6b3c Code cleanup 2018-04-02 15:10:40 +02:00
James Cole
fa7ab45a40 Code cleanup 2018-04-02 14:50:17 +02:00
James Cole
379b104778 Refer to classes directly. 2018-04-02 14:43:06 +02:00
James Cole
d956c795a4 Vue components will now work in subdirs too. 2018-04-02 14:42:30 +02:00
James Cole
7d02d0f762 Code cleanup. 2018-04-02 14:42:07 +02:00
James Cole
f96f38b172 Code cleanup. 2018-04-02 14:17:11 +02:00
James Cole
4cea5d65a6 Expand language list #1310 2018-04-02 06:56:19 +02:00
James Cole
40d94e7a62 Avoid using serialised preferences for security purposes. This might break existing preferences. 2018-04-01 19:22:30 +02:00
James Cole
66019fdbbf Code for #1309 2018-04-01 16:00:15 +02:00
James Cole
37b02e3d5b Merge branch 'release/4.7.2' 2018-04-01 11:46:41 +02:00
James Cole
093bdd6090 Fix some last minute issues. 2018-04-01 08:50:23 +02:00
James Cole
52656b25da Let's cancel these tests for now. 2018-04-01 08:04:19 +02:00
James Cole
1386c9d915 Disable some tests. 2018-04-01 07:40:30 +02:00
James Cole
02c9441727 Last minute language updates. 2018-04-01 07:24:18 +02:00
James Cole
b1e926f2cb Use php unit 7, not 6. 2018-04-01 07:13:29 +02:00
James Cole
df9dcb395b Change composer build instructions 2018-04-01 07:02:46 +02:00
James Cole
ad59dad921 Remove deprecated features. 2018-03-31 21:42:08 +02:00
James Cole
46e75968f5 Update composer 2018-03-31 21:05:53 +02:00
James Cole
0df5c5121d Update language strings 2018-03-31 21:05:43 +02:00
James Cole
16f04b45ac Update composer file. 2018-03-31 21:05:17 +02:00
James Cole
5ce35a50c2 Make sure tests work. 2018-03-31 21:05:06 +02:00
James Cole
7110c1178a Fix bad parse error. 2018-03-30 22:49:46 +02:00
James Cole
220f5e2913 Add support for Italian. 2018-03-30 22:48:00 +02:00
James Cole
9f8c75efc6 Fix null pointer in account format. 2018-03-30 22:44:37 +02:00
James Cole
8f3e84df4d Fix possible null pointer. 2018-03-30 22:40:20 +02:00
James Cole
08ff3d8ad0 Implement test of import command. 2018-03-30 19:41:16 +02:00
James Cole
5c4d7734ac Expand test code for create export routine. 2018-03-30 16:44:33 +02:00
James Cole
15f8cd49d3 Log file security. 2018-03-30 14:50:44 +02:00
James Cole
62b3986fcd Update env files for #1280 2018-03-30 07:00:20 +02:00
James Cole
55b6d711f3 Currency exchange rate will not be saved when rate is 0. 2018-03-30 06:33:04 +02:00
James Cole
7e51d57d21 Update composer file. 2018-03-29 19:01:59 +02:00
James Cole
170d23d768 Code cleanup before release. 2018-03-29 19:01:47 +02:00
James Cole
40266c6821 Add support for Italian and update language files. 2018-03-29 19:00:21 +02:00
James Cole
0a71077513 Push updated tests. 2018-03-28 19:38:20 +02:00
James Cole
be5c44af61 Update some code, add security txt file. 2018-03-28 19:37:59 +02:00
James Cole
720dcb0fe5 Fix #1300 2018-03-27 19:29:58 +02:00
James Cole
c86b207b1c Fix #1297 2018-03-26 20:48:47 +02:00
James Cole
413c1bc2fe Fix #1294 2018-03-26 19:19:11 +02:00
James Cole
5ca31ea3dd Fix #1296 2018-03-26 19:09:58 +02:00
James Cole
dd5d2d1616 Consistent overview for #1292 2018-03-25 21:16:46 +02:00
James Cole
5f08790f12 Restore chart #1292 2018-03-25 20:52:21 +02:00
James Cole
d5ef5ee5a7 Fix #1293 2018-03-25 20:42:56 +02:00
James Cole
f641c70172 Fix #1292 2018-03-25 18:26:35 +02:00
James Cole
992657b942 Code for #1257 2018-03-25 13:30:55 +02:00
James Cole
41e468b507 Fix #1247 2018-03-25 10:17:07 +02:00
James Cole
6660306ac4 Various code cleanup. 2018-03-25 09:01:43 +02:00
James Cole
dd9694890a Code for #1291 2018-03-25 09:00:45 +02:00
James Cole
0b8654d865 Fix #1252 2018-03-25 07:59:06 +02:00
James Cole
f07dc7bd81 Finalize bunq import #1248 2018-03-25 07:55:31 +02:00
James Cole
6a6482dc7f Finish up bunq import routine. 2018-03-24 18:55:02 +01:00
James Cole
3c9b7c07af Move import to factory #1222 2018-03-24 14:05:29 +01:00
James Cole
796ab4bf2c Fixed some small issues in import routine. 2018-03-24 11:49:26 +01:00
James Cole
55602d632d Clean up code for import routine. 2018-03-24 10:35:42 +01:00
James Cole
310ed9f504 Add budget warnings #1202 2018-03-24 06:46:37 +01:00
James Cole
dafddfa39a Fix all tests. 2018-03-24 06:08:50 +01:00
James Cole
3e22c9860e Fix some tests. 2018-03-23 05:31:45 +01:00
James Cole
fb0a0c3fb5 Fix a few tests. 2018-03-23 05:31:30 +01:00
James Cole
3b735c7533 Expand views and files to use new methods. 2018-03-19 19:39:26 +01:00
James Cole
1645490f5c Avoid using model methods and use repository instead 2018-03-19 19:39:02 +01:00
James Cole
aecffe10d9 Import routine can handle new SEPA fields and many new date fields. See #1248 2018-03-19 19:38:17 +01:00
James Cole
4e69bc0e32 Add reference to FAQ [skip ci] 2018-03-19 15:44:08 +01:00
James Cole
909f72e6be Move notes for attachments to different object. This sacrifices the original notes. 2018-03-19 15:28:35 +01:00
James Cole
6a1d39d5f8 Add newlines and strict type declarations. 2018-03-19 13:23:26 +01:00
James Cole
c5d4ec17c3 Move strict type declaration. 2018-03-19 13:22:08 +01:00
James Cole
ed33a72945 Make sure that strict_types declaration is always at the very top of the file. 2018-03-19 12:09:12 +01:00
James Cole
d8c0091680 Make sure that strict_types declaration is always at the very top of the file. 2018-03-19 12:08:50 +01:00
James Cole
6419d68626 Add newlines to end of file. 2018-03-19 12:08:22 +01:00
James Cole
e2ecaf5bcf Include BIC in import routine 2018-03-19 10:03:08 +01:00
James Cole
31146954d1 Fix #1258 2018-03-19 09:33:48 +01:00
James Cole
601ca9ec80 Update German translations [skip ci] 2018-03-19 09:09:47 +01:00
James Cole
082b5ba895 Fix #1262 2018-03-19 09:09:02 +01:00
James Cole
e06361d5d7 Push strict declaration to top. 2018-03-19 08:17:42 +01:00
James Cole
552a8e130c Add support methods. 2018-03-19 08:17:31 +01:00
James Cole
40787bc29a Improve bunq import. 2018-03-19 08:17:15 +01:00
James Cole
6ab03bb228 Improve IBAN uniqueness. 2018-03-19 08:16:54 +01:00
James Cole
3fdb782321 Fix various tests. 2018-03-11 21:19:35 +01:00
James Cole
c8f52a1c40 Code cleanup [skip ci] 2018-03-11 20:41:03 +01:00
James Cole
eb63090387 Fix custom range thing for accounts #1240 [skip ci] 2018-03-11 19:01:19 +01:00
James Cole
5bc8f31c31 Add verify routine to installer. 2018-03-11 18:47:26 +01:00
James Cole
5776de7745 Update various tests. 2018-03-11 18:46:41 +01:00
James Cole
f45d0bb317 Expand install routine. 2018-03-11 18:46:18 +01:00
James Cole
93aa5b7753 Fix null pointer in chart JS [skip ci] 2018-03-11 18:40:08 +01:00
James Cole
dd6a6a565f Fix null pointer in budget report [skip ci] 2018-03-11 18:38:35 +01:00
James Cole
aba8025645 Move docker files, include kubernetes files. 2018-03-11 18:27:30 +01:00
James Cole
b12872e5de Various code cleanup. 2018-03-11 16:24:07 +01:00
James Cole
5a7b1ba292 Remove unused methods. 2018-03-11 15:55:36 +01:00
James Cole
24715c72a2 Remove unused functions. 2018-03-11 15:54:33 +01:00
James Cole
ed3a4e4663 View extension for amounts [skip ci] 2018-03-11 14:19:28 +01:00
James Cole
e97283b34b Make sure transfers can't get a budget. 2018-03-11 14:13:23 +01:00
James Cole
c2dfbcba10 Improve view for transactions. 2018-03-11 14:09:44 +01:00
James Cole
a9870b35be Remove some stuff, mark as deprecated. 2018-03-11 13:34:16 +01:00
James Cole
ed5cd2b9ca Add currency symbol. 2018-03-11 13:31:22 +01:00
James Cole
a9356ca1e2 Mark methods as deprecated. 2018-03-11 13:30:58 +01:00
James Cole
cfba11e9ca Code for #1244 2018-03-11 13:26:11 +01:00
James Cole
4304a3c916 Code for #1214 2018-03-11 13:22:34 +01:00
James Cole
9e6194bfdc Catch null pointer [skip ci] 2018-03-11 08:23:47 +01:00
James Cole
7d6c8aa9dc Fix null pointer. 2018-03-11 08:22:20 +01:00
James Cole
aad0864018 Various code cleanup [skip ci] 2018-03-10 22:38:20 +01:00
James Cole
a55d18709c More code to catch exceptions in #1238 2018-03-10 22:34:02 +01:00
James Cole
dd2f3c861b Optimize imports. 2018-03-10 20:30:09 +01:00
James Cole
da1dc67e1c Validation message. 2018-03-10 20:25:55 +01:00
James Cole
0c2b35e542 Improve bunq import. 2018-03-10 20:25:42 +01:00
James Cole
85dc1263ea Fix #1238 2018-03-10 20:25:11 +01:00
James Cole
c8ecb3e0ee Fix #1199 for web interface 2018-03-10 09:44:04 +01:00
James Cole
ce10036a27 Fix #1199 in API 2018-03-10 09:39:49 +01:00
James Cole
30e49846e0 First list existing devices, then try to get a new one. 2018-03-10 07:33:49 +01:00
James Cole
be97dd1c57 Expand various views. 2018-03-10 07:17:23 +01:00
James Cole
648a6dca42 Expand install routine. 2018-03-10 07:17:05 +01:00
James Cole
0566d0d198 Expand bunq import. 2018-03-10 07:16:38 +01:00
James Cole
dfc25722c9 Expand debug page with locale information. 2018-03-10 07:15:21 +01:00
James Cole
a436c55c50 Code for #1236 2018-03-10 06:49:03 +01:00
James Cole
0d58530f55 Fix #1237 2018-03-09 20:58:46 +01:00
James Cole
04b2eaf535 Fix tests that broke during Laravel 5.6 upgrade 2018-03-09 06:46:45 +01:00
James Cole
ace2ed8bd0 Fix #1213 2018-03-09 05:52:52 +01:00
James Cole
dff2d716a1 Move 2FA to profile #1153 2018-03-09 05:45:22 +01:00
James Cole
ad18b9b81b Remove optional chart (always enabled) 2018-03-09 05:44:35 +01:00
James Cole
eabfe0769b Update explanation for new PW hash check. 2018-03-09 04:48:17 +01:00
James Cole
19f7027718 Fix #1198 2018-03-09 04:47:43 +01:00
James Cole
f537945351 Fix #1236 2018-03-09 04:04:42 +01:00
James Cole
d02372ab90 Fix debug controller for Laravel 5.6 2018-03-08 21:08:26 +01:00
James Cole
1b020c522f Fix currency test. 2018-03-08 21:02:46 +01:00
James Cole
79d0450c77 Implement new password verifier #1187 2018-03-08 20:44:56 +01:00
James Cole
bc32bc8831 Stop Travis from optimising. 2018-03-08 06:13:06 +01:00
James Cole
f68a307eeb Fix file names, ignore installer in test env 2018-03-07 21:04:10 +01:00
James Cole
82e7479cfe Force fresh config var [skip ci] 2018-03-07 21:01:46 +01:00
James Cole
462fe5d89f Force migration [skip ci]Middleware log. [skip ci] 2018-03-07 20:59:32 +01:00
James Cole
b0d8ac83ae Middleware log. [skip ci] 2018-03-07 20:58:54 +01:00
James Cole
d8ac817c91 Middleware log. [skip ci] 2018-03-07 20:56:52 +01:00
James Cole
5105bc6f64 Add more debug logging to output. 2018-03-07 20:55:11 +01:00
James Cole
47c9f1e9b8 Update logging for Laravel 5.6 #1221 2018-03-07 20:47:39 +01:00
James Cole
49d0ed0c1b Fix null pointer. 2018-03-07 20:41:17 +01:00
James Cole
99f5151aab Remove coverage for methods that do not exist. 2018-03-07 20:39:33 +01:00
James Cole
0a056ad02d Upgrade to Laravel 5.6 #1221 2018-03-07 20:37:00 +01:00
James Cole
c76b634d0b Fix #1189 2018-03-07 20:27:10 +01:00
James Cole
a81698d50f Code for #1219 2018-03-07 20:25:58 +01:00
James Cole
bae79063e1 Code to fix #1234 2018-03-07 20:21:51 +01:00
James Cole
fb5323c283 Code to facilitate #1123 2018-03-07 20:21:36 +01:00
James Cole
e2d1de94b7 Fix tests to catch use of repositories 2018-03-07 10:18:50 +01:00
James Cole
7109fd8196 Correct reference to journal description 2018-03-07 10:18:36 +01:00
James Cole
a5fd821e0c Code to implement #1168 and #1197. 2018-03-07 10:18:22 +01:00
James Cole
6c63583e49 Fix test to always select correct journal. 2018-03-07 05:52:45 +01:00
James Cole
dd16e1b784 Expand list of bills for #1102 2018-03-07 05:52:34 +01:00
James Cole
d52d8d7970 Expand exception code and fix demo user redirect. 2018-03-07 05:51:51 +01:00
James Cole
f349aa47ce Merge pull request #1232 from benyanke/patch-1
Allow user to specify port
2018-03-06 05:22:46 +01:00
Ben Yanke
951aa9535e Allow user to specify port 2018-03-05 20:49:21 -06:00
1589 changed files with 150921 additions and 48240 deletions

View File

@@ -0,0 +1,11 @@
[program:cron]
command=/usr/sbin/cron -f -L 15
user=root
autostart=true
autorestart=true
stdout_events_enabled=true
stderr_events_enabled=true
stdout_logfile=/dev/stdout
stdout_logfile_maxbytes=0
startsecs=10
startretries=3

29
.deploy/docker/entrypoint.sh Executable file
View File

@@ -0,0 +1,29 @@
#!/bin/bash
# make sure the correct directories exists (suggested by @chrif):
mkdir -p $FIREFLY_PATH/storage/app
mkdir -p $FIREFLY_PATH/storage/app/public
mkdir -p $FIREFLY_PATH/storage/build
mkdir -p $FIREFLY_PATH/storage/database
mkdir -p $FIREFLY_PATH/storage/debugbar
mkdir -p $FIREFLY_PATH/storage/export
mkdir -p $FIREFLY_PATH/storage/framework/cache
mkdir -p $FIREFLY_PATH/storage/framework/sessions
mkdir -p $FIREFLY_PATH/storage/framework/testing
mkdir -p $FIREFLY_PATH/storage/framework/views
mkdir -p $FIREFLY_PATH/storage/logs
mkdir -p $FIREFLY_PATH/storage/upload
# make sure we own the volumes:
chown -R www-data:www-data -R $FIREFLY_PATH/storage
chmod -R 775 $FIREFLY_PATH/storage
# remove any lingering files that may break upgrades:
rm -f $FIREFLY_PATH/storage/logs/laravel.log
cat .env.docker | envsubst > .env
composer dump-autoload
php artisan package:discover
php artisan firefly:instructions install
exec /usr/bin/supervisord -c /etc/supervisor/supervisord.conf --nodaemon

View File

@@ -0,0 +1,6 @@
[program:apache2]
command=/bin/bash -c "source /etc/apache2/envvars && exec /usr/sbin/apache2 -DFOREGROUND"
stdout_events_enabled=true
stderr_events_enabled=true
stdout_logfile=/dev/stdout
stdout_logfile_maxbytes=0

View File

@@ -0,0 +1,30 @@
# supervisor config file
# Adapted from the config file distributed with the supervisor package on Debian
# Jessie
# Enable supervisord in non-daemon mode. Disable the logfile as we receive
# log messages via stdout/err. Set up the child process log directory in case
# the user doesn't set logging to stdout/err.
[supervisord]
nodaemon = true
logfile = NONE
pidfile = /var/run/supervisord.pid
childlogdir = /var/log/supervisor
loglevel=debug
# Enable supervisorctl via RPC interface over Unix socket
[unix_http_server]
file = /var/run/supervisor.sock
chmod = 0700
[rpcinterface:supervisor]
supervisor.rpcinterface_factory = supervisor.rpcinterface:make_main_rpcinterface
[supervisorctl]
serverurl = unix:///var/run/supervisor.sock
# Include conf files for child processes
# Debian/Ubuntu packages use /etc/supervisor/conf.d
[include]
files = /etc/supervisor/conf.d/*.conf

26
.deploy/docker/vhost.conf Normal file
View File

@@ -0,0 +1,26 @@
server {
listen 80 default_server;
server_name _ *.vm docker;
root "/app/public";
index index.php;
include /opt/docker/etc/nginx/vhost.common.d/*.conf;
}
##############
# SSL
##############
server {
listen 443 default_server;
server_name _ *.vm docker;
root "/app/public";
index index.php;
include /opt/docker/etc/nginx/vhost.common.d/*.conf;
include /opt/docker/etc/nginx/vhost.ssl.conf;
}

View File

@@ -0,0 +1,82 @@
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: mysql-pv-export-claim
labels:
app: firefly-local
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 20Gi
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: mysql-pv-upload-claim
labels:
app: firefly-local
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 20Gi
---
apiVersion: apps/v1beta1
kind: Deployment
metadata:
name: firefly-local
namespace: firefly
labels:
app: firefly-local
spec:
selector:
matchLabels:
app: firefly-local
template:
metadata:
labels:
app: firefly-local
spec:
containers:
- image: firefly-local
name: firefly-local
env:
- name: FF_APP_ENV
value: "local"
- name: FF_APP_KEY
value: "S0m3R@nd0mString0f32Ch@rsEx@ct1y"
- name: FF_DB_HOST
value: "172.17.0.9"
- name: FF_DB_NAME
value: "firefly_db"
- name: FF_DB_USER
value: "firefly_db"
- name: FF_DB_PASSWORD
value: "password"
volumeMounts:
- mountPath: "/var/www/firefly-iii/storage/export"
name: mysql-persistent-export
- mountPath: "/var/www/firefly-iii/storage/upload"
name: mysql-persistent-upload
imagePullPolicy: IfNotPresent
volumes:
- name: mysql-persistent-export
persistentVolumeClaim:
claimName: mysql-pv-export-claim
- name: mysql-persistent-upload
persistentVolumeClaim:
claimName: mysql-pv-upload-claim
---
apiVersion: v1
kind: Service
metadata:
name: firefly-local
spec:
ports:
- port: 80
type: NodePort
selector:
app: firefly-local

View File

@@ -0,0 +1,49 @@
apiVersion: v1
kind: Secret
metadata:
name: sql-pass
type: Opaque
data:
password: cGFzc3dvcmQ=
---
apiVersion: apps/v1beta1
kind: Deployment
metadata:
name: mysql
namespace: firefly
labels:
app: mysql
spec:
selector:
matchLabels:
app: mysql
template:
metadata:
labels:
app: mysql
spec:
containers:
- image: mysql
imagePullPolicy: IfNotPresent
name: mysql
env:
- name: MYSQL_ROOT_PASSWORD
valueFrom:
secretKeyRef:
name: sql-pass
key: password
ports:
- containerPort: 3306
name: mysql
---
apiVersion: v1
kind: Service
metadata:
name: mysql
spec:
ports:
- port: 3306
type: NodePort
selector:
app: mysql

View File

@@ -1,4 +1,3 @@
# Ignore composer specific files and vendor folder
composer.phar
composer.lock
vendor

View File

@@ -13,29 +13,37 @@ SITE_OWNER=${SITE_OWNER}
# Change it to a string of exactly 32 chars or use command `php artisan key:generate` to generate it
APP_KEY=${FF_APP_KEY}
# APP_URL and TRUSTED_PROXIES are useful when using Docker and/or a reverse proxy.
# Change this value to your preferred time zone.
# Example: Europe/Amsterdam
TZ=${TZ}
# This variable must match your installation's external address but keep in mind that
# it's only used on the command line as a fallback value.
APP_URL=${APP_URL}
# TRUSTED_PROXIES is a useful variable when using Docker and/or a reverse proxy.
TRUSTED_PROXIES=${TRUSTED_PROXIES}
# Database credentials. Make sure the database exists. I recommend a dedicated user for Firefly III
# If you use SQLite, set connection to `sqlite` and remove the database, username and password settings.
DB_CONNECTION=mysql
DB_HOST=${FF_DB_HOST}
DB_PORT=3306
DB_DATABASE=${FF_DB_NAME}
DB_USERNAME=${FF_DB_USER}
DB_PASSWORD=${FF_DB_PASSWORD}
# The log channel defines where your log entries go to.
# 'daily' is the default logging mode giving you 5 daily rotated log files in /storage/logs/.
# Several other options exist. You can use 'single' for one big fat error log (not recommended).
# Also available are 'syslog' and 'errorlog' which will log to the system itself.
APP_LOG=syslog
# Also available are 'syslog', 'errorlog' and 'stdout' which will log to the system itself.
LOG_CHANNEL=stdout
# Log level. You can set this from least severe to most severe:
# debug, info, notice, warning, error, critical, alert, emergency
# If you set it to debug your logs will grow large, and fast. If you set it to emergency probably
# nothing will get logged, ever.
APP_LOG_LEVEL=info
APP_LOG_LEVEL=${APP_LOG_LEVEL}
# Database credentials. Make sure the database exists. I recommend a dedicated user for Firefly III
# For other database types, please see the FAQ: http://firefly-iii.readthedocs.io/en/latest/support/faq.html
DB_CONNECTION=${FF_DB_CONNECTION}
DB_HOST=${FF_DB_HOST}
DB_PORT=${FF_DB_PORT}
DB_DATABASE=${FF_DB_NAME}
DB_USERNAME=${FF_DB_USER}
DB_PASSWORD=${FF_DB_PASSWORD}
# If you're looking for performance improvements, you could install memcached.
CACHE_DRIVER=file
@@ -47,6 +55,7 @@ COOKIE_DOMAIN=
COOKIE_SECURE=false
# If you want Firefly III to mail you, update these settings
# For instructions, see: https://firefly-iii.readthedocs.io/en/latest/installation/mail.html
MAIL_DRIVER=${MAIL_DRIVER}
MAIL_HOST=${MAIL_HOST}
MAIL_PORT=${MAIL_PORT}
@@ -55,6 +64,12 @@ MAIL_USERNAME=${MAIL_USERNAME}
MAIL_PASSWORD=${MAIL_PASSWORD}
MAIL_ENCRYPTION=${MAIL_ENCRYPTION}
# Other mail drivers:
MAILGUN_DOMAIN=${MAILGUN_DOMAIN}
MAILGUN_SECRET=${MAILGUN_SECRET}
MANDRILL_SECRET=${MANDRILL_SECRET}
SPARKPOST_SECRET=${SPARKPOST_SECRET}
# Firefly III can send you the following messages
SEND_REGISTRATION_MAIL=true
SEND_ERROR_MESSAGE=false
@@ -62,6 +77,11 @@ SEND_ERROR_MESSAGE=false
# Set a Mapbox API key here (see mapbox.com) so there might be a map available at various places.
MAPBOX_API_KEY=${MAPBOX_API_KEY}
# Set a Fixer IO API key here (see https://fixer.io) to enable live currency exchange rates.
# Please note that this will only work for paid fixer.io accounts because they severly limited
# the free API up to the point where you might as well offer nothing.
FIXER_API_KEY=${FIXER_API_KEY}
# If you wish to track your own behavior over Firefly III, set a valid analytics tracker ID here.
ANALYTICS_ID=${ANALYTICS_ID}
@@ -79,7 +99,6 @@ REDIS_PASSWORD=null
REDIS_PORT=6379
CACHE_PREFIX=firefly
SEARCH_RESULT_LIMIT=50
EXCHANGE_RATE_SERVICE=fixerio
PUSHER_KEY=
PUSHER_SECRET=
PUSHER_ID=
@@ -88,4 +107,6 @@ DEMO_PASSWORD=
IS_DOCKER=true
IS_SANDSTORM=false
IS_HEROKU=false
TZ=${TZ}
BUNQ_USE_SANDBOX=false
MAILGUN_DOMAIN=
MAILGUN_SECRET=

View File

@@ -15,25 +15,20 @@ APP_KEY=SomeRandomStringOf32CharsExactly
# Change this value to your preferred time zone.
# Example: Europe/Amsterdam
TZ=UTC
TZ=Europe/Amsterdam
# APP_URL and TRUSTED_PROXIES are useful when using Docker and/or a reverse proxy.
# This variable must match your installation's external address but keep in mind that
# it's only used on the command line as a fallback value.
APP_URL=http://localhost
# TRUSTED_PROXIES is a useful variable when using Docker and/or a reverse proxy.
TRUSTED_PROXIES=
# Database credentials. Make sure the database exists. I recommend a dedicated user for Firefly III
# If you use SQLite, set connection to `sqlite` and remove the database, username and password settings.
DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=homestead
DB_USERNAME=homestead
DB_PASSWORD=secret
# The log channel defines where your log entries go to.
# 'daily' is the default logging mode giving you 5 daily rotated log files in /storage/logs/.
# Several other options exist. You can use 'single' for one big fat error log (not recommended).
# Also available are 'syslog' and 'errorlog' which will log to the system itself.
APP_LOG=daily
# Also available are 'syslog', 'errorlog' and 'stdout' which will log to the system itself.
LOG_CHANNEL=daily
# Log level. You can set this from least severe to most severe:
# debug, info, notice, warning, error, critical, alert, emergency
@@ -41,6 +36,15 @@ APP_LOG=daily
# nothing will get logged, ever.
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: http://firefly-iii.readthedocs.io/en/latest/support/faq.html
DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=homestead
DB_USERNAME=homestead
DB_PASSWORD=secret
# If you're looking for performance improvements, you could install memcached.
CACHE_DRIVER=file
SESSION_DRIVER=file
@@ -51,7 +55,8 @@ COOKIE_DOMAIN=
COOKIE_SECURE=false
# If you want Firefly III to mail you, update these settings
MAIL_DRIVER=smtp
# For instructions, see: https://firefly-iii.readthedocs.io/en/latest/installation/mail.html
MAIL_DRIVER=log
MAIL_HOST=smtp.mailtrap.io
MAIL_PORT=2525
MAIL_FROM=changeme@example.com
@@ -59,6 +64,12 @@ MAIL_USERNAME=null
MAIL_PASSWORD=null
MAIL_ENCRYPTION=null
# Other mail drivers:
MAILGUN_DOMAIN=
MAILGUN_SECRET=
MANDRILL_SECRET=
SPARKPOST_SECRET=
# Firefly III can send you the following messages
SEND_REGISTRATION_MAIL=true
SEND_ERROR_MESSAGE=true
@@ -66,6 +77,11 @@ SEND_ERROR_MESSAGE=true
# Set a Mapbox API key here (see mapbox.com) so there might be a map available at various places.
MAPBOX_API_KEY=
# Set a Fixer IO API key here (see https://fixer.io) to enable live currency exchange rates.
# Please note that this will only work for paid fixer.io accounts because they severly limited
# the free API up to the point where you might as well offer nothing.
FIXER_API_KEY=
# If you wish to track your own behavior over Firefly III, set a valid analytics tracker ID here.
ANALYTICS_ID=
@@ -83,7 +99,6 @@ REDIS_PASSWORD=null
REDIS_PORT=6379
CACHE_PREFIX=firefly
SEARCH_RESULT_LIMIT=50
EXCHANGE_RATE_SERVICE=fixerio
PUSHER_KEY=
PUSHER_SECRET=
PUSHER_ID=
@@ -92,3 +107,6 @@ DEMO_PASSWORD=
IS_DOCKER=false
IS_SANDSTORM=false
IS_HEROKU=false
BUNQ_USE_SANDBOX=false
MAILGUN_DOMAIN=
MAILGUN_SECRET=

View File

@@ -17,9 +17,24 @@ APP_KEY=7ahyYVPVsmxjdhsweWCauGeJfwc92NP2
# Example: Europe/Amsterdam
TZ=UTC
# APP_URL and TRUSTED_PROXIES are useful when using Docker and/or a reverse proxy.
# This variable must match your installation's external address but keep in mind that
# it's only used on the command line as a fallback value.
APP_URL=http://localhost
TRUSTED_PROXIES=
# TRUSTED_PROXIES is a useful variable when using Docker and/or a reverse proxy.
TRUSTED_PROXIES=**
# The log channel defines where your log entries go to.
# 'daily' is the default logging mode giving you 5 daily rotated log files in /storage/logs/.
# 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.
LOG_CHANNEL=stdout
# Log level. You can set this from least severe to most severe:
# debug, info, notice, warning, error, critical, alert, emergency
# If you set it to debug your logs will grow large, and fast. If you set it to emergency probably
# nothing will get logged, ever.
APP_LOG_LEVEL=debug
# Database credentials. Make sure the database exists. I recommend a dedicated user for Firefly III
# If you use SQLite, set connection to `sqlite` and remove the database, username and password settings.
@@ -30,17 +45,6 @@ DB_CONNECTION=pgsql
# 'daily' is the default logging mode giving you 5 daily rotated log files in /storage/logs/.
# Several other options exist. You can use 'single' for one big fat error log (not recommended).
# Also available are 'syslog' and 'errorlog' which will log to the system itself.
APP_LOG=errorlog
# Log level. You can set this from least severe to most severe:
# debug, info, notice, warning, error, critical, alert, emergency
# If you set it to debug your logs will grow large, and fast. If you set it to emergency probably
# nothing will get logged, ever.
APP_LOG_LEVEL=debug
# If you're looking for performance improvements, you could install memcached.
CACHE_DRIVER=file
SESSION_DRIVER=file
@@ -51,7 +55,8 @@ COOKIE_DOMAIN=
COOKIE_SECURE=false
# If you want Firefly III to mail you, update these settings
MAIL_DRIVER=smtp
# For instructions, see: https://firefly-iii.readthedocs.io/en/latest/installation/mail.html
MAIL_DRIVER=log
MAIL_HOST=smtp.mailtrap.io
MAIL_PORT=2525
MAIL_FROM=changeme@example.com
@@ -59,6 +64,12 @@ MAIL_USERNAME=null
MAIL_PASSWORD=null
MAIL_ENCRYPTION=null
# Other mail drivers:
MAILGUN_DOMAIN=
MAILGUN_SECRET=
MANDRILL_SECRET=
SPARKPOST_SECRET=
# Firefly III can send you the following messages
SEND_REGISTRATION_MAIL=true
SEND_ERROR_MESSAGE=true
@@ -66,6 +77,11 @@ SEND_ERROR_MESSAGE=true
# Set a Mapbox API key here (see mapbox.com) so there might be a map available at various places.
MAPBOX_API_KEY=
# Set a Fixer IO API key here (see https://fixer.io) to enable live currency exchange rates.
# Please note that this will only work for paid fixer.io accounts because they severly limited
# the free API up to the point where you might as well offer nothing.
FIXER_API_KEY=
# If you wish to track your own behavior over Firefly III, set a valid analytics tracker ID here.
ANALYTICS_ID=
@@ -83,7 +99,6 @@ REDIS_PASSWORD=null
REDIS_PORT=6379
CACHE_PREFIX=firefly
SEARCH_RESULT_LIMIT=50
EXCHANGE_RATE_SERVICE=fixerio
PUSHER_KEY=
PUSHER_SECRET=
PUSHER_ID=
@@ -92,3 +107,6 @@ DEMO_PASSWORD=
IS_DOCKER=false
IS_SANDSTORM=false
IS_HEROKU=true
BUNQ_USE_SANDBOX=false
MAILGUN_DOMAIN=
MAILGUN_SECRET=

View File

@@ -17,10 +17,25 @@ APP_KEY=SomeRandomStringOf32CharsExactly
# Example: Europe/Amsterdam
TZ=UTC
# APP_URL and TRUSTED_PROXIES are useful when using Docker and/or a reverse proxy.
# This variable must match your installation's external address but keep in mind that
# it's only used on the command line as a fallback value.
APP_URL=http://localhost
# TRUSTED_PROXIES is a useful variable when using Docker and/or a reverse proxy.
TRUSTED_PROXIES=
# The log channel defines where your log entries go to.
# 'daily' is the default logging mode giving you 5 daily rotated log files in /storage/logs/.
# 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.
LOG_CHANNEL=stdout
# Log level. You can set this from least severe to most severe:
# debug, info, notice, warning, error, critical, alert, emergency
# If you set it to debug your logs will grow large, and fast. If you set it to emergency probably
# nothing will get logged, ever.
APP_LOG_LEVEL=debug
# Database credentials. Make sure the database exists. I recommend a dedicated user for Firefly III
# If you use SQLite, set connection to `sqlite` and remove the database, username and password settings.
DB_CONNECTION=mysql
@@ -30,17 +45,6 @@ DB_DATABASE=firefly
DB_USERNAME=firefly
DB_PASSWORD=firefly
# 'daily' is the default logging mode giving you 5 daily rotated log files in /storage/logs/.
# Several other options exist. You can use 'single' for one big fat error log (not recommended).
# Also available are 'syslog' and 'errorlog' which will log to the system itself.
APP_LOG=syslog
# Log level. You can set this from least severe to most severe:
# debug, info, notice, warning, error, critical, alert, emergency
# If you set it to debug your logs will grow large, and fast. If you set it to emergency probably
# nothing will get logged, ever.
APP_LOG_LEVEL=info
# If you're looking for performance improvements, you could install memcached.
CACHE_DRIVER=file
SESSION_DRIVER=file
@@ -51,7 +55,8 @@ COOKIE_DOMAIN=
COOKIE_SECURE=false
# If you want Firefly III to mail you, update these settings
MAIL_DRIVER=smtp
# For instructions, see: https://firefly-iii.readthedocs.io/en/latest/installation/mail.html
MAIL_DRIVER=log
MAIL_HOST=smtp.mailtrap.io
MAIL_PORT=2525
MAIL_FROM=changeme@example.com
@@ -59,6 +64,12 @@ MAIL_USERNAME=null
MAIL_PASSWORD=null
MAIL_ENCRYPTION=null
# Other mail drivers:
MAILGUN_DOMAIN=
MAILGUN_SECRET=
MANDRILL_SECRET=
SPARKPOST_SECRET=
# Firefly III can send you the following messages
SEND_REGISTRATION_MAIL=true
SEND_ERROR_MESSAGE=true
@@ -66,6 +77,11 @@ SEND_ERROR_MESSAGE=true
# Set a Mapbox API key here (see mapbox.com) so there might be a map available at various places.
MAPBOX_API_KEY=
# Set a Fixer IO API key here (see https://fixer.io) to enable live currency exchange rates.
# Please note that this will only work for paid fixer.io accounts because they severly limited
# the free API up to the point where you might as well offer nothing.
FIXER_API_KEY=
# If you wish to track your own behavior over Firefly III, set a valid analytics tracker ID here.
ANALYTICS_ID=
@@ -83,7 +99,6 @@ REDIS_PASSWORD=null
REDIS_PORT=6379
CACHE_PREFIX=firefly
SEARCH_RESULT_LIMIT=50
EXCHANGE_RATE_SERVICE=fixerio
PUSHER_KEY=
PUSHER_SECRET=
PUSHER_ID=
@@ -92,3 +107,6 @@ DEMO_PASSWORD=
IS_DOCKER=false
IS_SANDSTORM=true
IS_HEROKU=false
BUNQ_USE_SANDBOX=false
MAILGUN_DOMAIN=
MAILGUN_SECRET=

View File

@@ -1,33 +1,61 @@
# You can leave this on "local". If you change it to production most console commands will ask for extra confirmation.
# Never set it to "testing".
APP_ENV=testing
# Set to true if you want to see debug information in error screens.
APP_DEBUG=true
APP_NAME=FireflyIII
# This should be your email address
SITE_OWNER=thegrumpydictator+testing@gmail.com
# The encryption key for your database and sessions. Keep this very secure.
# If you generate a new one all existing data must be considered LOST.
# Change it to a string of exactly 32 chars or use command `php artisan key:generate` to generate it
APP_KEY=TestTestTestTestTestTestTestTest
APP_LOG=daily
APP_LOG_LEVEL=debug
APP_URL=http://localhost
TRUSTED_PROXIES=
# Change this value to your preferred time zone.
# Example: Europe/Amsterdam
TZ=Europe/Amsterdam
DB_CONNECTION=sqlite
DB_HOST=127.0.0.1
DB_PORT=3306
#DB_DATABASE=firefly
DB_USERNAME=homestead
DB_PASSWORD=
# This variable must match your installation's external address but keep in mind that
# it's only used on the command line as a fallback value.
APP_URL=http://localhost
BROADCAST_DRIVER=log
# TRUSTED_PROXIES is a useful variable when using Docker and/or a reverse proxy.
TRUSTED_PROXIES=
# The log channel defines where your log entries go to.
# 'daily' is the default logging mode giving you 5 daily rotated log files in /storage/logs/.
# 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.
LOG_CHANNEL=dailytest
# Log level. You can set this from least severe to most severe:
# debug, info, notice, warning, error, critical, alert, emergency
# If you set it to debug your logs will grow large, and fast. If you set it to emergency probably
# nothing will get logged, ever.
APP_LOG_LEVEL=info
# Database credentials. Make sure the database exists. I recommend a dedicated user for Firefly III
# For other database types, please see the FAQ: http://firefly-iii.readthedocs.io/en/latest/support/faq.html
DB_CONNECTION=sqlite
# If you're looking for performance improvements, you could install memcached.
CACHE_DRIVER=file
SESSION_DRIVER=file
QUEUE_DRIVER=sync
# Cookie settings. Should not be necessary to change these.
COOKIE_PATH="/"
COOKIE_DOMAIN=
COOKIE_SECURE=false
REDIS_HOST=127.0.0.1
REDIS_PASSWORD=null
REDIS_PORT=6379
# If you want Firefly III to mail you, update these settings
# For instructions, see: https://firefly-iii.readthedocs.io/en/latest/installation/mail.html
MAIL_DRIVER=log
MAIL_HOST=smtp.mailtrap.io
MAIL_PORT=2525
@@ -36,26 +64,49 @@ MAIL_USERNAME=null
MAIL_PASSWORD=null
MAIL_ENCRYPTION=null
# Other mail drivers:
MAILGUN_DOMAIN=
MAILGUN_SECRET=
MANDRILL_SECRET=
SPARKPOST_SECRET=
# Firefly III can send you the following messages
SEND_REGISTRATION_MAIL=true
SEND_ERROR_MESSAGE=false
CACHE_PREFIX=firefly
SEARCH_RESULT_LIMIT=50
EXCHANGE_RATE_SERVICE=fixerio
# Set a Mapbox API key here (see mapbox.com) so there might be a map available at various places.
MAPBOX_API_KEY=
ANALYTICS_ID=
SITE_OWNER=mail@example.com
USE_ENCRYPTION=true
# Set a Fixer IO API key here (see https://fixer.io) to enable live currency exchange rates.
# Please note that this will only work for paid fixer.io accounts because they severly limited
# the free API up to the point where you might as well offer nothing.
FIXER_API_KEY=
# If you wish to track your own behavior over Firefly III, set a valid analytics tracker ID here.
ANALYTICS_ID=
# Most parts of the database are encrypted by default, but you can turn this off if you want to.
# This makes it easier to migrate your database. Not that some fields will never be decrypted.
USE_ENCRYPTION=false
# Leave the following configuration vars as is.
# Unless you like to tinker and know what you're doing.
APP_NAME=FireflyIII
BROADCAST_DRIVER=log
QUEUE_DRIVER=sync
REDIS_HOST=127.0.0.1
REDIS_PASSWORD=null
REDIS_PORT=6379
CACHE_PREFIX=firefly_tst
SEARCH_RESULT_LIMIT=50
PUSHER_KEY=
PUSHER_SECRET=
PUSHER_ID=
DEMO_USERNAME=
DEMO_PASSWORD=
IS_DOCKER=false
IS_SANDSTORM=false
IS_HEROKU=false
BUNQ_USE_SANDBOX=true
MAILGUN_DOMAIN=
MAILGUN_SECRET=

25
.github/ISSUE_TEMPLATE/Bug_report.md vendored Normal file
View File

@@ -0,0 +1,25 @@
---
name: Bug report
about: Create a report to help Firefly III improve
---
**Bug description**
I am running Firefly III version x.x.x
(please give a clear and concise description of what the bug is)
**Steps to reproduce**
What do you need to do to trigger this bug?
**Expected behavior**
What do you expect to see after those steps?
**Extra info**
Please add extra info here, such as OS, browser, and the output from the /debug page of your Firefly III installation (click the version at the bottom).
**Bonus points**
Earn bonus points by:
- Post a stacktrace from your log files
- Add a screenshot

27
.github/ISSUE_TEMPLATE/Custom.md vendored Normal file
View File

@@ -0,0 +1,27 @@
---
name: I have a question or a problem
about: Ask away!
---
I am running Firefly III version x.x.x
**Description**
**Steps to reproduce**
(if relevant of course)
**Extra info**
Please add extra info here, such as OS, browser, and the output from the `/debug`-page of your Firefly III installation (click the version at the bottom).
**Bonus points**
Earn bonus points by:
- Add a screenshot
- Replicate the problem on the demo site https://demo.firefly-iii.org/

View File

@@ -0,0 +1,21 @@
---
name: Feature request
about: Suggest an idea or feature for Firefly III
---
**Description**
Please describe your feature request:
- I would like Firefly III to do X.
- What if you would add feature Y?
- Firefly III doesn't do Z.
**Solution**
Describe what your feature would add to Firefly III.
**What are alternatives?**
Please describe what alternatives currently exist.
**Additional context**
Add any other context or screenshots about the feature request here.

View File

@@ -1,11 +0,0 @@
I am running Firefly III version x.x.x
#### Description of my issue:
#### Steps to reproduce
(please include if this problem also exists on the demo site)
#### Other important details (log files, system info):
Please click the version number in the right corner of any Firefly III page to get debug information.

56
.github/stale.yml vendored Normal file
View File

@@ -0,0 +1,56 @@
# Configuration for probot-stale - https://github.com/probot/stale
# Number of days of inactivity before an Issue or Pull Request becomes stale
daysUntilStale: 14
# Number of days of inactivity before a stale Issue or Pull Request is closed.
# Set to false to disable. If disabled, issues still need to be closed manually, but will remain marked as stale.
daysUntilClose: 7
# Issues or Pull Requests with these labels will never be considered stale. Set to `[]` to disable
# - "[Status] Maybe Later"
exemptLabels:
- enhancement
- feature
- bug
# Set to true to ignore issues in a project (defaults to false)
exemptProjects: false
# Set to true to ignore issues in a milestone (defaults to false)
exemptMilestones: false
# Label to use when marking as stale
staleLabel: stale
# Comment to post when marking as stale. Set to `false` to disable
markComment: >
This issue has been automatically marked as stale because it has not had
recent activity. It will be closed if no further activity occurs. Thank you
for your contributions.
# Comment to post when removing the stale label.
# unmarkComment: >
# Your comment here.
# Comment to post when closing a stale Issue or Pull Request.
# closeComment: >
# Your comment here.
# Limit the number of actions per hour, from 1-30. Default is 30
limitPerRun: 30
# Limit to only `issues` or `pulls`
# only: issues
# Optionally, specify configuration settings that are specific to just 'issues' or 'pulls':
# pulls:
# daysUntilStale: 30
# markComment: >
# This pull request has been automatically marked as stale because it has not had
# recent activity. It will be closed if no further activity occurs. Thank you
# for your contributions.
# issues:
# exemptLabels:
# - confirmed

View File

@@ -9,9 +9,16 @@ VM_NAME = File.basename(File.dirname(File.dirname(__FILE__))) + "_sandstorm_#{Ti
# Vagrantfile API/syntax version. Don't touch unless you know what you're doing!
VAGRANTFILE_API_VERSION = "2"
# ugly hack to prevent hashicorp's bitrot. See https://github.com/hashicorp/vagrant/issues/9442
# this setting is required for pre-2.0 vagrant, but causes an error as of 2.0.3,
# remove entirely when confident nobody uses vagrant 1.x for anything.
unless Vagrant::DEFAULT_SERVER_URL.frozen?
Vagrant::DEFAULT_SERVER_URL.replace('https://vagrantcloud.com')
end
Vagrant.configure(VAGRANTFILE_API_VERSION) do |config|
# Base on the Sandstorm snapshots of the official Debian 8 (jessie) box.
config.vm.box = "sandstorm/debian-jessie64"
config.vm.box = "debian/contrib-jessie64"
if Vagrant.has_plugin?("vagrant-vbguest") then
# vagrant-vbguest is a Vagrant plugin that upgrades

View File

@@ -1,3 +1,253 @@
# 4.7.7
- [Issue 954](https://github.com/firefly-iii/firefly-iii/issues/954) Some additional view chart ranges
- [Issue 1710](https://github.com/firefly-iii/firefly-iii/issues/1710) Added a new currency ([hamuz](https://github.com/hamuz))
- Transactions will now store (in the database) how they were created.
- [Issue 907](https://github.com/firefly-iii/firefly-iii/issues/907) Better and more options on the transaction list.
- [Issue 1450](https://github.com/firefly-iii/firefly-iii/issues/1450) Add a rule to change the type of a transaction automagically
- [Issue 1701](https://github.com/firefly-iii/firefly-iii/issues/1701) Fix reference to PHP executable ([hertzg](https://github.com/hertzg))
- Budget limits have currency information, for future expansion.
- Some charts and pages can handle multiple currencies better.
- New GA code for those who use it.
- The credit card liability type has been removed.
- [Issue 896](https://github.com/firefly-iii/firefly-iii/issues/896) Better redirection when coming from deleted objects.
- [Issue 1519](https://github.com/firefly-iii/firefly-iii/issues/1519) Fix autocomplete tags
- [Issue 1607](https://github.com/firefly-iii/firefly-iii/issues/1607) Some fixes for the bunq api calls
- [Issue 1650](https://github.com/firefly-iii/firefly-iii/issues/1650) Add a negated amount column for CSV imports ([hamuz](https://github.com/hamuz))
- [Issue 1658](https://github.com/firefly-iii/firefly-iii/issues/1658) Make font heavy again.
- [Issue 1660](https://github.com/firefly-iii/firefly-iii/issues/1660) Add a negated amount column for CSV imports ([hamuz](https://github.com/hamuz))
- [Issue 1667](https://github.com/firefly-iii/firefly-iii/issues/1667) Fix pie charts
- [Issue 1668](https://github.com/firefly-iii/firefly-iii/issues/1668) YNAB iso_code fix
- [Issue 1670](https://github.com/firefly-iii/firefly-iii/issues/1670) Fix piggy bank API error
- [Issue 1671](https://github.com/firefly-iii/firefly-iii/issues/1671) More options for liability accounts.
- [Issue 1673](https://github.com/firefly-iii/firefly-iii/issues/1673) Fix reconciliation issues.
- [Issue 1675](https://github.com/firefly-iii/firefly-iii/issues/1675) Wrong sum in tag report.
- [Issue 1679](https://github.com/firefly-iii/firefly-iii/issues/1679) Change type of a transaction wouldn't trigger rules.
- [Issue 1682](https://github.com/firefly-iii/firefly-iii/issues/1682) Add liability accounts to transaction conversion
- [Issue 1683](https://github.com/firefly-iii/firefly-iii/issues/1683) See matching transaction showed transfers twice.
- [Issue 1685](https://github.com/firefly-iii/firefly-iii/issues/1685) fix autocomplete for rules
- [Issue 1690](https://github.com/firefly-iii/firefly-iii/issues/1690) Missing highlighted button in intro popup
- [Issue 1691](https://github.com/firefly-iii/firefly-iii/issues/1691) No mention of liabilities in demo text
- [Issue 1695](https://github.com/firefly-iii/firefly-iii/issues/1695) Small fixes in bills pages.
- [Issue 1708](https://github.com/firefly-iii/firefly-iii/issues/1708) Fix by [mathieupost](https://github.com/mathieupost) for bunq
- [Issue 1709](https://github.com/firefly-iii/firefly-iii/issues/1709) Fix oauth buttons
- [Issue 1712](https://github.com/firefly-iii/firefly-iii/issues/1712) Double slash fix by [hamuz](https://github.com/hamuz)
- [Issue 1719](https://github.com/firefly-iii/firefly-iii/issues/1719) Add missing accounts to API
- [Issue 1720](https://github.com/firefly-iii/firefly-iii/issues/1720) Fix validation for transaction type.
- [Issue 1723](https://github.com/firefly-iii/firefly-iii/issues/1723) API broken for currency exchange rates.
- [Issue 1728](https://github.com/firefly-iii/firefly-iii/issues/1728) Fix problem with transaction factory.
- [Issue 1729](https://github.com/firefly-iii/firefly-iii/issues/1729) Fix bulk transaction editor
- [Issue 1731](https://github.com/firefly-iii/firefly-iii/issues/1731) API failure for budget limits.
- Secure headers now allow Mapbox and the 2FA QR code.
# 4.7.6.2
- Docker file builds again.
- Fix CSS of OAuth2 authorization view.
# 4.7.6.1
- An issue where I switched variables from the Docker `.env` file to the normal `.env` file and vice versa -- breaking both.
- [Issue 1649](https://github.com/firefly-iii/firefly-iii/issues/1649) 2FA QR code would not show up due to very strict security policy headers
- Docker build gave a cURL error whenever it runs PHP commands.
# 4.7.6
- [Issue 145](https://github.com/firefly-iii/firefly-iii/issues/145) You can now download transactions from YNAB.
- [Issue 306](https://github.com/firefly-iii/firefly-iii/issues/306) You can now add liabilities to Firefly III.
- [Issue 740](https://github.com/firefly-iii/firefly-iii/issues/740) Various charts are now currency aware.
- [Issue 833](https://github.com/firefly-iii/firefly-iii/issues/833) Bills can use non-default currencies.
- [Issue 1578](https://github.com/firefly-iii/firefly-iii/issues/1578) Firefly III will notify you if the cron job hasn't fired.
- [Issue 1623](https://github.com/firefly-iii/firefly-iii/issues/1623) New transactions will link back from the success message.
- [Issue 1624](https://github.com/firefly-iii/firefly-iii/issues/1624) transactions will link to the object.
- You can call the cron job over the web now (see docs).
- You don't need to call the cron job every minute any more.
- Various charts are now red/green to signify income and expenses.
- Option to add or remove accounts from the net worth calculations.
- This will be the last release on PHP 7.1. Future versions will require PHP 7.2.
- [Issue 1460](https://github.com/firefly-iii/firefly-iii/issues/1460) Downloading transactions from bunq should go more smoothly.
- [Issue 1464](https://github.com/firefly-iii/firefly-iii/issues/1464) Fixed the docker file to work on Raspberry Pi's.
- [Issue 1540](https://github.com/firefly-iii/firefly-iii/issues/1540) The Docker file now has a working cron job for recurring transactions.
- [Issue 1564](https://github.com/firefly-iii/firefly-iii/issues/1564) Fix double transfers when importing from bunq.
- [Issue 1575](https://github.com/firefly-iii/firefly-iii/issues/1575) Some views would give a XSRF token warning
- [Issue 1576](https://github.com/firefly-iii/firefly-iii/issues/1576) Fix assigning budgets
- [Issue 1580](https://github.com/firefly-iii/firefly-iii/issues/1580) Missing string for translation
- [Issue 1581](https://github.com/firefly-iii/firefly-iii/issues/1581) Expand help text
- [Issue 1584](https://github.com/firefly-iii/firefly-iii/issues/1584) Link to administration is back.
- [Issue 1586](https://github.com/firefly-iii/firefly-iii/issues/1586) Date fields in import were mislabeled.
- [Issue 1593](https://github.com/firefly-iii/firefly-iii/issues/1593) Link types are translatable.
- [Issue 1594](https://github.com/firefly-iii/firefly-iii/issues/1594) Very long breadcrumbs are weird.
- [Issue 1598](https://github.com/firefly-iii/firefly-iii/issues/1598) Fix budget calculations.
- [Issue 1597](https://github.com/firefly-iii/firefly-iii/issues/1597) Piggy banks are always inactive.
- [Issue 1605](https://github.com/firefly-iii/firefly-iii/issues/1605) System will ignore foreign currency setting if user doesn't indicate the amount.
- [Issue 1608](https://github.com/firefly-iii/firefly-iii/issues/1608) Spelling error in command line import.
- [Issue 1609](https://github.com/firefly-iii/firefly-iii/issues/1609) Link to budgets page was absolute.
- [Issue 1615](https://github.com/firefly-iii/firefly-iii/issues/1615) Fix currency bug in transactions.
- [Issue 1616](https://github.com/firefly-iii/firefly-iii/issues/1616) Fix null pointer exception in pie charts.
- [Issue 1617](https://github.com/firefly-iii/firefly-iii/issues/1617) Fix for complex tag names in URL's.
- [Issue 1620](https://github.com/firefly-iii/firefly-iii/issues/1620) Fixed index reference in API.
- [Issue 1639](https://github.com/firefly-iii/firefly-iii/issues/1639) Firefly III trusts the Heroku load balancer, fixing deployment on Heroku.
- [Issue 1642](https://github.com/firefly-iii/firefly-iii/issues/1642) Fix issue with split journals.
- [Issue 1643](https://github.com/firefly-iii/firefly-iii/issues/1643) Fix reconciliation issue.
- Users can no longer give income a budget.
- Fix bug in Spectre import.
- Heroku would not make you owner.
- Add `.htaccess` files to all public directories.
- New secure headers will make Firefly III slightly more secure.
- The rule "tester" will now also take the "strict"-checkbox into account.
# 4.7.5.3
- [Issue 1527](https://github.com/firefly-iii/firefly-iii/issues/1527), fixed views for transactions without a budget.
- [Issue 1553](https://github.com/firefly-iii/firefly-iii/issues/1553), report could not handle transactions before the first one in the system.
- [Issue 1549](https://github.com/firefly-iii/firefly-iii/issues/1549) update a budget will also update any rules that refer to that budget.
- [Issue 1530](https://github.com/firefly-iii/firefly-iii/issues/1530), fix issue with bill chart.
- [Issue 1563](https://github.com/firefly-iii/firefly-iii/issues/1563), fix piggy bank suggested amount
- [Issue 1571](https://github.com/firefly-iii/firefly-iii/issues/1571), fix OAuth in Sandstorm
- [Issue 1568](https://github.com/firefly-iii/firefly-iii/issues/1568), bug in Sandstorm user code.
- [Issue 1569](https://github.com/firefly-iii/firefly-iii/issues/1569), optimized Sandstorm build by [ocdtrekkie](https://github.com/ocdtrekkie)
- Fixed a bug where transfers would be stored inversely when using the CSV import.
- Retired the "Rabobank description"-fix, because it is no longer necessary.
- Fixed a bug where users could not delete budget limits in the API.
- Piggy bank notes are visible again.
# 4.7.5.1
- [Issue 1531](https://github.com/firefly-iii/firefly-iii/issues/1531), the database routine incorrectly reports empty categories.
- [Issue 1532](https://github.com/firefly-iii/firefly-iii/issues/1532), broken dropdown for autosuggest things.
- [Issue 1533](https://github.com/firefly-iii/firefly-iii/issues/1533), fix where the import could not import category names.
- [Issue 1538](https://github.com/firefly-iii/firefly-iii/issues/1538), fix a bug where Spectre would not work when ignoring rules.
- [Issue 1542](https://github.com/firefly-iii/firefly-iii/issues/1542), fix a bug where the importer was incapable of generating new currencies.
- [Issue 1541](https://github.com/firefly-iii/firefly-iii/issues/1541), no longer ignore composer.lock in Docker ignore.
- Bills are stored inactive.
# 4.7.5
- A new feature called "recurring transactions" that will make Firefly III automatically create transactions for you.
- New API end points for attachments, available budgets, budgets, budget limits, categories, configuration, currency exchange rates, journal links, link types, piggy banks, preferences, recurring transactions, rules, rule groups and tags.
- Added support for YunoHost.
- The 2FA secret is visible so you can type it into 2FA apps.
- Bunq and Spectre imports will now ask to apply rules.
- Sandstorm users can now make API keys.
- Various typo's in the English translations. [issue 1493](https://github.com/firefly-iii/firefly-iii/issues/1493)
- Bug where Spectre was never called [issue 1492](https://github.com/firefly-iii/firefly-iii/issues/1492)
- Clear cache after journal is created through API [issue 1483](https://github.com/firefly-iii/firefly-iii/issues/1483)
- Make sure docker directories exist [issue 1500](https://github.com/firefly-iii/firefly-iii/issues/1500)
- Broken link to bill edit [issue 1505](https://github.com/firefly-iii/firefly-iii/issues/1505)
- Several bugs in the editing of split transactions [issue 1509](https://github.com/firefly-iii/firefly-iii/issues/1509)
- Import routine ignored formatting of several date fields [issue 1510](https://github.com/firefly-iii/firefly-iii/issues/1510)
- Piggy bank events now show the correct currency [issue 1446](https://github.com/firefly-iii/firefly-iii/issues/1446)
- Inactive accounts are no longer suggested [issue 1463](https://github.com/firefly-iii/firefly-iii/issues/1463)
- Some income / expense charts are less confusing [issue 1518](https://github.com/firefly-iii/firefly-iii/issues/1518)
- Validation bug in multi-currency create view [issue 1521](https://github.com/firefly-iii/firefly-iii/issues/1521)
# 4.7.4
- [Issue 1409](https://github.com/firefly-iii/firefly-iii/issues/1409), add Indian Rupee and explain that users can do this themselves [issue 1413](https://github.com/firefly-iii/firefly-iii/issues/1413)
- [Issue 1445](https://github.com/firefly-iii/firefly-iii/issues/1445), upgrade Curl in Docker image.
- [Issue 1386](https://github.com/firefly-iii/firefly-iii/issues/1386), quick links to often used pages.
- [Issue 1405](https://github.com/firefly-iii/firefly-iii/issues/1405), show proposed amount to piggy banks.
- [Issue 1416](https://github.com/firefly-iii/firefly-iii/issues/1416), ability to delete lost attachments.
- A completely rewritten import routine that can handle bunq (thanks everybody for testing!), CSV files and Spectre. Please make sure you read about this at http://bit.ly/FF3-new-import
- [Issue 1392](https://github.com/firefly-iii/firefly-iii/issues/1392), explicitly mention rules are inactive (when they are).
- [Issue 1406](https://github.com/firefly-iii/firefly-iii/issues/1406), bill conversion to rules will be smarter about the rules they create.
- [Issue 1369](https://github.com/firefly-iii/firefly-iii/issues/1369), you can now properly order piggy banks again.
- [Issue 1389](https://github.com/firefly-iii/firefly-iii/issues/1389), null-pointer in the import routine.
- [Issue 1400](https://github.com/firefly-iii/firefly-iii/issues/1400), missing translation.
- [Issue 1403](https://github.com/firefly-iii/firefly-iii/issues/1403), bill would always be marked as inactive in edit screen.
- [Issue 1418](https://github.com/firefly-iii/firefly-iii/issues/1418), missing note text on bill page.
- Export routine would break when encountering un-decryptable files.
- [Issue 1425](https://github.com/firefly-iii/firefly-iii/issues/1425), empty fields when edit multiple transactions at once.
- [Issue 1449](https://github.com/firefly-iii/firefly-iii/issues/1449), bad calculations in "budget left to spend" view.
- [Issue 1451](https://github.com/firefly-iii/firefly-iii/issues/1451), same but in another view.
- [Issue 1453](https://github.com/firefly-iii/firefly-iii/issues/1453), same as [issue 1403](https://github.com/firefly-iii/firefly-iii/issues/1403).
- [Issue 1455](https://github.com/firefly-iii/firefly-iii/issues/1455), could add income to a budget.
- [Issue 1442](https://github.com/firefly-iii/firefly-iii/issues/1442), issues with editing a split deposit.
- [Issue 1452](https://github.com/firefly-iii/firefly-iii/issues/1452), date range problems with tags.
- [Issue 1458](https://github.com/firefly-iii/firefly-iii/issues/1458), same for transactions.
- [Issue 1415](https://github.com/firefly-iii/firefly-iii/issues/1415), will email you when OAuth2 keys are generated.
# 4.7.3.2
- Forgot to increase the version number :(.
# 4.7.3.1
- Fixed a critical bug where the rules-engine would fire inadvertently.
# 4.7.3
- Currency added to API
- Firfely III will also generate a cash wallet for new users.
- Can now reset Spectre and bunq settings
- Docker file has a time zone
- Allow database connection to be configured in Docker file
- Can now view and edit attachments in edit-screen
- User can visit hidden `/attachments` page
- [Issue 1356](https://github.com/firefly-iii/firefly-iii/issues/1356): Budgets will show the remaining amount per day
- [Issue 1367](https://github.com/firefly-iii/firefly-iii/issues/1367): Rules now come in strict and non-strict mode.
- Added a security.txt
- More support for trusted proxies
- Improved edit routine for split transactions.
- Upgrade routine can handle `proc_close` being disabled.
- Bills now use rules to match transactions, making it more flexible.
- [Issue 1328](https://github.com/firefly-iii/firefly-iii/issues/1328): piggy banks no have a more useful chart.
- Spectre API upgraded to v4
- Move to MariaDB ([issue 1366](https://github.com/firefly-iii/firefly-iii/issues/1366))
- Piggy banks take currency from parent account ([issue 1334](https://github.com/firefly-iii/firefly-iii/issues/1334))
- [Issue 1341](https://github.com/firefly-iii/firefly-iii/issues/1341): Removed depricated command from dockerfile
- Several issues with docker image ([issue 1320](https://github.com/firefly-iii/firefly-iii/issues/1320), [issue 1382](https://github.com/firefly-iii/firefly-iii/issues/1382)).
- Fix giant tags and division by zero ([issue 1325](https://github.com/firefly-iii/firefly-iii/issues/1325) and others)
- Several issues with bunq import ([issue 1352](https://github.com/firefly-iii/firefly-iii/issues/1352), [issue 1330](https://github.com/firefly-iii/firefly-iii/issues/1330), [issue 1378](https://github.com/firefly-iii/firefly-iii/issues/1378), [issue 1380](https://github.com/firefly-iii/firefly-iii/issues/1380))
- [Issue 1246](https://github.com/firefly-iii/firefly-iii/issues/1246): date picker is internationalised
- [Issue 1327](https://github.com/firefly-iii/firefly-iii/issues/1327): fix formattting issues in piggy banks
- [Issue 1348](https://github.com/firefly-iii/firefly-iii/issues/1348): 500 error in API
- [Issue 1349](https://github.com/firefly-iii/firefly-iii/issues/1349): Errors in import routine
- Several fixes for (multi-currency) reconciliation ([issue 1336](https://github.com/firefly-iii/firefly-iii/issues/1336), [issue 1363](https://github.com/firefly-iii/firefly-iii/issues/1363))
- [Issue 1353](https://github.com/firefly-iii/firefly-iii/issues/1353): return NULL values in range-indicator
- Bug in split transaction edit routine
- Piggy bank percentage was very specific.
- Logging in Slack is easier to config.
- [Issue 1312](https://github.com/firefly-iii/firefly-iii/issues/1312) Import broken for ING accounts
- [Issue 1313](https://github.com/firefly-iii/firefly-iii/issues/1313) Error when creating new asset account
- [Issue 1317](https://github.com/firefly-iii/firefly-iii/issues/1317) Forgot an include :(
- Null pointer exception in transaction overview.
- Installations running in subdirs were incapable of creating OAuth tokens.
- OAuth keys were not created in all cases.
# 4.7.2
- [Issue 1123](https://github.com/firefly-iii/firefly-iii/issues/1123) First browser based update routine.
- Add support for Italian.
- [Issue 1232](https://github.com/firefly-iii/firefly-iii/issues/1232) Allow user to specify Docker database port.
- [Issue 1197](https://github.com/firefly-iii/firefly-iii/issues/1197) Beter account list overview
- [Issue 1202](https://github.com/firefly-iii/firefly-iii/issues/1202) Some budgetary warnings
- [Issue 1284](https://github.com/firefly-iii/firefly-iii/issues/1284) Experimental support for bunq import
- [Issue 1248](https://github.com/firefly-iii/firefly-iii/issues/1248) Ability to import BIC, ability to import SEPA fields.
- [Issue 1102](https://github.com/firefly-iii/firefly-iii/issues/1102) Summary line for bills
- More info to debug page.
- [Issue 1186](https://github.com/firefly-iii/firefly-iii/issues/1186) You can see the latest account balance in CRUD forms
- Add Kubernetes YAML files, kindly created by a FF3 user.
- [Issue 1244](https://github.com/firefly-iii/firefly-iii/issues/1244) Better line for "today" marker and add it to other chart as well ([issue 1214](https://github.com/firefly-iii/firefly-iii/issues/1214))
- [Issue 1219](https://github.com/firefly-iii/firefly-iii/issues/1219) Languages in dropdown
- [Issue 1189](https://github.com/firefly-iii/firefly-iii/issues/1189) Inactive accounts get removed from net worth
- [Issue 1220](https://github.com/firefly-iii/firefly-iii/issues/1220) Attachment description and notes migrated to just "notes".
- [Issue 1236](https://github.com/firefly-iii/firefly-iii/issues/1236) Multi currency balance box
- [Issue 1240](https://github.com/firefly-iii/firefly-iii/issues/1240) Better overview for accounts.
- [Issue 1292](https://github.com/firefly-iii/firefly-iii/issues/1292) Removed some charts from the "all"-overview of budgets and categories
- [Issue 1245](https://github.com/firefly-iii/firefly-iii/issues/1245) Improved recognition of IBANs
- Improved import routine.
- Update notifier will wait three days before notifying users.
- [Issue 1300](https://github.com/firefly-iii/firefly-iii/issues/1300) Virtual balance of credit cards does not count for net worth
- [Issue 1247](https://github.com/firefly-iii/firefly-iii/issues/1247) Can now see overspent amount
- [Issue 1221](https://github.com/firefly-iii/firefly-iii/issues/1221) Upgrade to Laravel 5.6
- [Issue 1187](https://github.com/firefly-iii/firefly-iii/issues/1187) Updated the password verifier to use Troy Hunt's new API
- Revenue chart is now on frontpage permanently
- [Issue 1153](https://github.com/firefly-iii/firefly-iii/issues/1153) 2FA settings are in your profile now
- [Issue 1227](https://github.com/firefly-iii/firefly-iii/issues/1227) Can set the timezone in config or in Docker
- [Issue 1294](https://github.com/firefly-iii/firefly-iii/issues/1294) Ability to link a transaction to itself
- Correct reference to journal description in split form.
- [Issue 1234](https://github.com/firefly-iii/firefly-iii/issues/1234) Fix budget page issues in SQLite
- [Issue 1262](https://github.com/firefly-iii/firefly-iii/issues/1262) Can now use double and epty headers in CSV files
- [Issue 1258](https://github.com/firefly-iii/firefly-iii/issues/1258) Fixed a possible date mismatch in piggy banks
- [Issue 1283](https://github.com/firefly-iii/firefly-iii/issues/1283) Bulk delete was broken
- [Issue 1293](https://github.com/firefly-iii/firefly-iii/issues/1293) Layout problem with notes
- [Issue 1257](https://github.com/firefly-iii/firefly-iii/issues/1257) Improve transaction lists query count
- [Issue 1291](https://github.com/firefly-iii/firefly-iii/issues/1291) Fixer IO problems
- [Issue 1239](https://github.com/firefly-iii/firefly-iii/issues/1239) Could not edit expense or revenue accounts ([issue 1298](https://github.com/firefly-iii/firefly-iii/issues/1298))
- [Issue 1297](https://github.com/firefly-iii/firefly-iii/issues/1297) Could not convert to withdrawal
- [Issue 1226](https://github.com/firefly-iii/firefly-iii/issues/1226) Category overview in default report shows no income.
- Various other bugs and problems ([issue 1198](https://github.com/firefly-iii/firefly-iii/issues/1198), [issue 1213](https://github.com/firefly-iii/firefly-iii/issues/1213), [issue 1237](https://github.com/firefly-iii/firefly-iii/issues/1237), [issue 1238](https://github.com/firefly-iii/firefly-iii/issues/1238), [issue 1199](https://github.com/firefly-iii/firefly-iii/issues/1199), [issue 1200](https://github.com/firefly-iii/firefly-iii/issues/1200))
- Fixed an issue with token validation on the command line.
# 4.7.1
- A brand new API. Read about it in the [documentation](http://firefly-iii.readthedocs.io/en/latest/).
- Add support for Spanish. [issue 1194](https://github.com/firefly-iii/firefly-iii/issues/1194)

View File

@@ -9,6 +9,10 @@ CURL_OPTS="--silent --show-error"
echo localhost > /etc/hostname
hostname localhost
# Install curl that is needed below.
apt-get update
apt-get install -y curl
# The following line copies stderr through stderr to cat without accidentally leaving it in the
# output file. Be careful when changing. See: https://github.com/sandstorm-io/vagrant-spk/pull/159
curl $CURL_OPTS https://install.sandstorm.io/ 2>&1 > /host-dot-sandstorm/caches/install.sh | cat

View File

@@ -37,15 +37,15 @@ HOME=/etc/mysql /usr/bin/mysql_install_db --force
# Spawn mysqld, php
HOME=/etc/mysql /usr/sbin/mysqld &
/usr/sbin/php-fpm7.1 --nodaemonize --fpm-config /etc/php/7.1/fpm/php-fpm.conf &
/usr/sbin/php-fpm7.2 --nodaemonize --fpm-config /etc/php/7.2/fpm/php-fpm.conf &
# Wait until mysql and php have bound their sockets, indicating readiness
while [ ! -e /var/run/mysqld/mysqld.sock ] ; do
echo "waiting for mysql to be available at /var/run/mysqld/mysqld.sock"
sleep .5
done
while [ ! -e /var/run/php7.1-fpm.sock ] ; do
echo "waiting for php7.1-fpm to be available at /var/run/php7.1-fpm.sock"
while [ ! -e /var/run/php7.2-fpm.sock ] ; do
echo "waiting for php7.2-fpm to be available at /var/run/php7.2-fpm.sock"
sleep .5
done

File diff suppressed because it is too large Load Diff

View File

@@ -15,8 +15,8 @@ const pkgdef :Spk.PackageDefinition = (
manifest = (
appTitle = (defaultText = "Firefly III"),
appVersion = 9,
appMarketingVersion = (defaultText = "4.7.1"),
appVersion = 17,
appMarketingVersion = (defaultText = "4.7.7"),
actions = [
# Define your "new document" handlers here.
@@ -65,9 +65,9 @@ const pkgdef :Spk.PackageDefinition = (
# Sizes are given in device-independent pixels, so if you took these
# screenshots on a Retina-style high DPI screen, divide each dimension by two.
(width = 1291, height = 800, png = embed "screenshots/screenshot-1.png"),
(width = 1291, height = 800, png = embed "screenshots/screenshot-2.png"),
(width = 1291, height = 800, png = embed "screenshots/screenshot-3.png"),
(width = 1290, height = 800, png = embed "screenshots/screenshot-1.png"),
(width = 1290, height = 800, png = embed "screenshots/screenshot-2.png"),
(width = 1290, height = 800, png = embed "screenshots/screenshot-3.png"),
],
changeLog = (defaultText = embed "changelog.md"),

Binary file not shown.

Before

Width:  |  Height:  |  Size: 120 KiB

After

Width:  |  Height:  |  Size: 173 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 122 KiB

After

Width:  |  Height:  |  Size: 171 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 107 KiB

After

Width:  |  Height:  |  Size: 163 KiB

View File

@@ -53,7 +53,7 @@ http {
}
location ~ \.php$ {
try_files $uri =404;
fastcgi_pass unix:/var/run/php7.1-fpm.sock;
fastcgi_pass unix:/var/run/php7.2-fpm.sock;
fastcgi_index index.php;
fastcgi_split_path_info ^(.+\.php)(/.+)$;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;

View File

@@ -15,11 +15,13 @@ apt-get install -y python-software-properties software-properties-common
# install all languages
sed -i 's/# de_DE.UTF-8 UTF-8/de_DE.UTF-8 UTF-8/g' /etc/locale.gen
sed -i 's/# fr_FR.UTF-8 UTF-8/fr_FR.UTF-8 UTF-8/g' /etc/locale.gen
sed -i 's/# id_ID.UTF-8 UTF-8/id_ID.UTF-8 UTF-8/g' /etc/locale.gen
sed -i 's/# it_IT.UTF-8 UTF-8/it_IT.UTF-8 UTF-8/g' /etc/locale.gen
sed -i 's/# nl_NL.UTF-8 UTF-8/nl_NL.UTF-8 UTF-8/g' /etc/locale.gen
sed -i 's/# pl_PL.UTF-8 UTF-8/pl_PL.UTF-8 UTF-8/g' /etc/locale.gen
sed -i 's/# pt_BR.UTF-8 UTF-8/pt_BR.UTF-8 UTF-8/g' /etc/locale.gen
sed -i 's/# ru_RU.UTF-8 UTF-8/ru_RU.UTF-8 UTF-8/g' /etc/locale.gen
sed -i 's/# tr_TR.UTF-8 UTF-8/tr_TR.UTF-8 UTF-8/g' /etc/locale.gen
dpkg-reconfigure --frontend=noninteractive locales
@@ -30,43 +32,43 @@ apt-key adv --keyserver keyserver.ubuntu.com --recv-keys E9C74FEEA2098A6E
add-apt-repository "deb http://packages.dotdeb.org jessie all"
# add another repos
apt-get install apt-transport-https lsb-release ca-certificates
apt-get install -y apt-transport-https lsb-release ca-certificates
wget -O /etc/apt/trusted.gpg.d/php.gpg https://packages.sury.org/php/apt.gpg
echo "deb https://packages.sury.org/php/ $(lsb_release -sc) main" > /etc/apt/sources.list.d/php.list
# install packages.
apt-get update
apt-get install -y nginx php7.1-fpm php7.1-mysql php7.1-gd php7.1-cli php7.1-curl git php7.1-dev php7.1-zip php7.1-intl php7.1-dom php7.1-mbstring php7.1-bcmath mysql-server
apt-get install -y nginx php7.2-fpm php7.2-mysql php7.2-gd php7.2-cli php7.2-curl git php7.2-dev php7.2-zip php7.2-intl php7.2-dom php7.2-mbstring php7.2-bcmath mysql-server
service nginx stop
service php7.1-fpm stop
service php7.2-fpm stop
service mysql stop
systemctl disable nginx
systemctl disable php7.1-fpm
systemctl disable php7.2-fpm
systemctl disable mysql
# make php.ini display errors:
sed -i 's/display_errors = Off/display_errors = On/g' /etc/php/7.1/fpm/php.ini
sed -i 's/display_errors = Off/display_errors = On/g' /etc/php/7.2/fpm/php.ini
# patch /etc/php/7.1/fpm/pool.d/www.conf to not change uid/gid to www-data
# patch /etc/php/7.2/fpm/pool.d/www.conf to not change uid/gid to www-data
sed --in-place='' \
--expression='s/^listen.owner = www-data/;listen.owner = www-data/' \
--expression='s/^listen.group = www-data/;listen.group = www-data/' \
/etc/php/7.1/fpm/pool.d/www.conf
# patch /etc/php/7.1/fpm/php-fpm.conf to not have a pidfile
/etc/php/7.2/fpm/pool.d/www.conf
# patch /etc/php/7.2/fpm/php-fpm.conf to not have a pidfile
sed --in-place='' \
--expression='s/^pid =/;pid =/' \
/etc/php/7.1/fpm/php-fpm.conf
/etc/php/7.2/fpm/php-fpm.conf
# move sock file to better dir:
sed --in-place='' \
--expression='s/^listen = \/run\/php\/php7.1-fpm.sock/listen = \/var\/run\/php7.1-fpm.sock/' \
/etc/php/7.1/fpm/pool.d/www.conf
--expression='s/^listen = \/run\/php\/php7.2-fpm.sock/listen = \/var\/run\/php7.2-fpm.sock/' \
/etc/php/7.2/fpm/pool.d/www.conf
# patch /etc/php/7.1/fpm/pool.d/www.conf to no clear environment variables
# patch /etc/php/7.2/fpm/pool.d/www.conf to no clear environment variables
# so we can pass in SANDSTORM=1 to apps
sed --in-place='' \
--expression='s/^;clear_env = no/clear_env=no/' \
/etc/php/7.1/fpm/pool.d/www.conf
/etc/php/7.2/fpm/pool.d/www.conf
# patch mysql conf to not change uid, and to use /var/tmp over /tmp
# for secure-file-priv see https://github.com/sandstorm-io/vagrant-spk/issues/195
sed --in-place='' \

View File

@@ -1,6 +1,6 @@
language: php
php:
- 7.1
- 7.2
cache:
directories:
@@ -12,21 +12,18 @@ install:
- composer update --no-scripts
- cp .env.testing .env
- php artisan clear-compiled
- php artisan optimize
- php artisan env
- cp .env.testing .env
- wget -q https://github.com/firefly-iii/test-data/raw/master/storage/database.sqlite -O storage/database/database.sqlite
- mkdir -p build/logs
script:
- phpunit -c phpunit.coverage.xml
- ./vendor/bin/phpunit -c phpunit.coverage.xml
after_success:
- travis_retry php vendor/bin/php-coveralls -x storage/build/clover-all.xml
- bash <(curl -s https://codecov.io/bash) -f storage/build/clover-all.xml
# safelist
branches:
only:
- develop
- master
- master

View File

@@ -1,37 +1,85 @@
# use PHP 7.1 and Apache as a base.
FROM php:7.1-apache
FROM php:7.2-apache
# If building on a RPi, use --build-arg cores=3 to use all cores when compiling
# to speed up the image build
ARG CORES
ENV CORES ${CORES:-1}
ENV FIREFLY_PATH /var/www/firefly-iii/
ENV CURL_VERSION 7.60.0
ENV OPENSSL_VERSION 1.1.1-pre6
LABEL version="1.0" maintainer="thegrumpydictator@gmail.com"
# set working dir
ENV FIREFLY_PATH /var/www/firefly-iii
WORKDIR $FIREFLY_PATH
ADD . $FIREFLY_PATH
# install packages
RUN apt-get update -y && \
apt-get install -y --no-install-recommends libcurl4-openssl-dev \
zlib1g-dev \
libjpeg62-turbo-dev \
libpng12-dev \
wget \
libpng-dev \
libicu-dev \
libedit-dev \
libtidy-dev \
libxml2-dev \
unzip \
libsqlite3-dev \
nano \
libpq-dev \
libbz2-dev \
gettext-base \
cron \
rsyslog \
supervisor \
locales && \
apt-get clean && \
rm -rf /var/lib/apt/lists/*
# Install latest curl
RUN cd /tmp && \
wget https://www.openssl.org/source/openssl-${OPENSSL_VERSION}.tar.gz && \
tar -xvf openssl-${OPENSSL_VERSION}.tar.gz && \
cd openssl-${OPENSSL_VERSION} && \
./config && \
make -j${CORES} && \
make install
RUN cd /tmp && \
wget https://curl.haxx.se/download/curl-${CURL_VERSION}.tar.gz && \
tar -xvf curl-${CURL_VERSION}.tar.gz && \
cd curl-${CURL_VERSION} && \
./configure --with-ssl --host=$(gcc -dumpmachine) && \
make -j${CORES} && \
make install
# Make sure that libcurl is using the newer curl libaries
RUN echo "/usr/local/lib" >> /etc/ld.so.conf.d/00-curl.conf && ldconfig
# Mimic the Debian/Ubuntu config file structure for supervisor
COPY .deploy/docker/supervisord.conf /etc/supervisor/supervisord.conf
RUN mkdir -p /etc/supervisor/conf.d /var/log/supervisor
# copy Firefly III supervisor conf file.
COPY ./.deploy/docker/firefly-iii.conf /etc/supervisor/conf.d/firefly-iii.conf
# copy cron job supervisor conf file.
COPY ./.deploy/docker/cronjob.conf /etc/supervisor/conf.d/cronjob.conf
# test crons added via crontab
RUN echo "0 3 * * * /usr/local/bin/php /var/www/firefly-iii/artisan firefly:cron" | crontab -
#RUN (crontab -l ; echo "*/1 * * * * free >> /var/www/firefly-iii/public/cron.html") 2>&1 | crontab -
# Install PHP exentions.
RUN docker-php-ext-install -j$(nproc) curl gd intl json readline tidy zip bcmath xml mbstring pdo_sqlite pdo_mysql bz2 pdo_pgsql
RUN docker-php-ext-install -j$(nproc) gd intl tidy zip bcmath pdo_mysql bz2 pdo_pgsql
# Install composer
RUN curl -sS https://getcomposer.org/installer | php -- --install-dir=/usr/local/bin --filename=composer
# Generate locales supported by Firefly III
RUN echo "de_DE.UTF-8 UTF-8\nen_US.UTF-8 UTF-8\nfr_FR.UTF-8 UTF-8\nid_ID.UTF-8 UTF-8\nnl_NL.UTF-8 UTF-8\npl_PL.UTF-8 UTF-8" > /etc/locale.gen && locale-gen
RUN echo "en_US.UTF-8 UTF-8\nde_DE.UTF-8 UTF-8\nfr_FR.UTF-8 UTF-8\nit_IT.UTF-8 UTF-8\nnl_NL.UTF-8 UTF-8\npl_PL.UTF-8 UTF-8\npt_BR.UTF-8 UTF-8\nru_RU.UTF-8 UTF-8\ntr_TR.UTF-8 UTF-8\n\n" > /etc/locale.gen && locale-gen
# copy Apache config to correct spot.
COPY ./docker/apache2.conf /etc/apache2/apache2.conf
COPY ./.deploy/docker/apache2.conf /etc/apache2/apache2.conf
# Enable apache mod rewrite..
RUN a2enmod rewrite
@@ -39,23 +87,28 @@ RUN a2enmod rewrite
# Enable apache mod ssl..
RUN a2enmod ssl
# Create volumes for several directories:
# Create volumes
VOLUME $FIREFLY_PATH/storage/export $FIREFLY_PATH/storage/upload
# Setup the Composer installer
RUN curl -sS https://getcomposer.org/installer | php -- --install-dir=/usr/local/bin --filename=composer
# Enable default site (Firefly III)
COPY ./docker/apache-firefly.conf /etc/apache2/sites-available/000-default.conf
COPY ./.deploy/docker/apache-firefly.conf /etc/apache2/sites-available/000-default.conf
# Make sure we own Firefly III directory
RUN chown -R www-data:www-data /var/www && chmod -R 775 $FIREFLY_PATH/storage
# Copy in Firefly Source
WORKDIR $FIREFLY_PATH
ADD . $FIREFLY_PATH
# Fix the link to curl:
RUN rm -rf /usr/local/lib/libcurl.so.4 && ln -s /usr/lib/x86_64-linux-gnu/libcurl.so.4.4.0 /usr/local/lib/libcurl.so.4
# Run composer
ENV COMPOSER_ALLOW_SUPERUSER 1
RUN composer install --prefer-dist --no-dev --no-scripts --no-suggest
# Expose port 80
EXPOSE 80
# Run entrypoint thing
ENTRYPOINT ["docker/entrypoint.sh"]
ENTRYPOINT [".deploy/docker/entrypoint.sh"]

View File

@@ -1,4 +1,5 @@
<?php
/**
* AboutController.php
* Copyright (c) 2018 thegrumpydictator@gmail.com
@@ -25,37 +26,30 @@ namespace FireflyIII\Api\V1\Controllers;
use DB;
use FireflyIII\Transformers\UserTransformer;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use League\Fractal\Manager;
use League\Fractal\Resource\Item;
use League\Fractal\Serializer\JsonApiSerializer;
/**
* Class AboutController
* Returns basic information about this installation.
*
* Class AboutController.
*/
class AboutController extends Controller
{
/**
* AccountController constructor.
* Returns system information.
*
* @throws \FireflyIII\Exceptions\FireflyException
* @return JsonResponse
*/
public function __construct()
{
parent::__construct();
}
/**
* @return \Illuminate\Http\JsonResponse
*/
public function about()
public function about(): JsonResponse
{
$search = ['~', '#'];
$replace = ['\~', '# '];
$phpVersion = str_replace($search, $replace, PHP_VERSION);
$phpOs = str_replace($search, $replace, php_uname());
$phpOs = str_replace($search, $replace, PHP_OS);
$currentDriver = DB::getDriverName();
$data
= [
@@ -64,18 +58,19 @@ class AboutController extends Controller
'php_version' => $phpVersion,
'os' => $phpOs,
'driver' => $currentDriver,
];
return response()->json(['data' => $data], 200)->header('Content-Type', 'application/vnd.api+json');
}
/**
* Returns information about the user.
*
* @param Request $request
*
* @return \Illuminate\Http\JsonResponse
* @return JsonResponse
*/
public function user(Request $request)
public function user(Request $request): JsonResponse
{
$manager = new Manager();
$baseUrl = $request->getSchemeAndHttpHost() . '/api/v1';
@@ -84,5 +79,4 @@ class AboutController extends Controller
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', 'application/vnd.api+json');
}
}

View File

@@ -29,6 +29,8 @@ use FireflyIII\Models\AccountType;
use FireflyIII\Repositories\Account\AccountRepositoryInterface;
use FireflyIII\Repositories\Currency\CurrencyRepositoryInterface;
use FireflyIII\Transformers\AccountTransformer;
use FireflyIII\User;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Pagination\LengthAwarePaginator;
use League\Fractal\Manager;
@@ -36,35 +38,35 @@ use League\Fractal\Pagination\IlluminatePaginatorAdapter;
use League\Fractal\Resource\Collection as FractalCollection;
use League\Fractal\Resource\Item;
use League\Fractal\Serializer\JsonApiSerializer;
use Preferences;
/**
* Class AccountController
* Class AccountController.
*
* @SuppressWarnings(PHPMD.CouplingBetweenObjects)
*/
class AccountController extends Controller
{
/** @var CurrencyRepositoryInterface */
/** @var CurrencyRepositoryInterface The currency repository */
private $currencyRepository;
/** @var AccountRepositoryInterface */
/** @var AccountRepositoryInterface The account repository */
private $repository;
/**
* AccountController constructor.
*
* @throws \FireflyIII\Exceptions\FireflyException
*/
public function __construct()
{
parent::__construct();
$this->middleware(
function ($request, $next) {
/** @var AccountRepositoryInterface repository */
/** @var User $user */
$user = auth()->user();
// @var AccountRepositoryInterface repository
$this->repository = app(AccountRepositoryInterface::class);
$this->repository->setUser(auth()->user());
$this->repository->setUser($user);
$this->currencyRepository = app(CurrencyRepositoryInterface::class);
$this->currencyRepository->setUser(auth()->user());
$this->currencyRepository->setUser($user);
return $next($request);
}
@@ -74,11 +76,11 @@ class AccountController extends Controller
/**
* Remove the specified resource from storage.
*
* @param \FireflyIII\Models\Account $account
* @param \FireflyIII\Models\Account $account
*
* @return \Illuminate\Http\Response
* @return JsonResponse
*/
public function delete(Account $account)
public function delete(Account $account): JsonResponse
{
$this->repository->destroy($account, null);
@@ -90,21 +92,21 @@ class AccountController extends Controller
*
* @param Request $request
*
* @return \Illuminate\Http\JsonResponse
* @return JsonResponse
*/
public function index(Request $request)
public function index(Request $request): JsonResponse
{
// create some objects:
$manager = new Manager();
$baseUrl = $request->getSchemeAndHttpHost() . '/api/v1';
$manager = new Manager;
$baseUrl = $request->getSchemeAndHttpHost() . '/api/v1';
// read type from URI
$type = $request->get('type') ?? 'all';
$this->parameters->set('type', $type);
// types to get, page size:
$types = $this->mapTypes($this->parameters->get('type'));
$pageSize = intval(Preferences::getForUser(auth()->user(), 'listPageSize', 50)->data);
$types = $this->mapTypes($this->parameters->get('type'));
$pageSize = (int)app('preferences')->getForUser(auth()->user(), 'listPageSize', 50)->data;
// get list of accounts. Count it and split it.
$collection = $this->repository->getAccountsByType($types);
@@ -124,14 +126,16 @@ class AccountController extends Controller
}
/**
* Show single instance.
*
* @param Request $request
* @param Account $account
*
* @return \Illuminate\Http\JsonResponse
*/
public function show(Request $request, Account $account)
public function show(Request $request, Account $account): JsonResponse
{
$manager = new Manager();
$manager = new Manager;
// add include parameter:
$include = $request->get('include') ?? '';
@@ -145,27 +149,28 @@ class AccountController extends Controller
}
/**
* Store a new instance.
*
* @param AccountRequest $request
*
* @return \Illuminate\Http\JsonResponse
*/
public function store(AccountRequest $request)
public function store(AccountRequest $request): JsonResponse
{
$data = $request->getAll();
// if currency ID is 0, find the currency by the code:
if ($data['currency_id'] === 0) {
if (0 === $data['currency_id']) {
$currency = $this->currencyRepository->findByCodeNull($data['currency_code']);
$data['currency_id'] = is_null($currency) ? 0 : $currency->id;
$data['currency_id'] = null === $currency ? 0 : $currency->id;
}
$account = $this->repository->store($data);
$manager = new Manager();
$manager = new Manager;
$baseUrl = $request->getSchemeAndHttpHost() . '/api/v1';
$manager->setSerializer(new JsonApiSerializer($baseUrl));
$resource = new Item($account, new AccountTransformer($this->parameters), 'accounts');
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', 'application/vnd.api+json');
}
/**
@@ -176,18 +181,18 @@ class AccountController extends Controller
*
* @return \Illuminate\Http\JsonResponse
*/
public function update(AccountRequest $request, Account $account)
public function update(AccountRequest $request, Account $account): JsonResponse
{
$data = $request->getAll();
// if currency ID is 0, find the currency by the code:
if ($data['currency_id'] === 0) {
if (0 === $data['currency_id']) {
$currency = $this->currencyRepository->findByCodeNull($data['currency_code']);
$data['currency_id'] = is_null($currency) ? 0 : $currency->id;
$data['currency_id'] = null === $currency ? 0 : $currency->id;
}
// set correct type:
$data['type'] = config('firefly.shortNamesByFullName.' . $account->accountType->type);
$this->repository->update($account, $data);
$manager = new Manager();
$manager = new Manager;
$baseUrl = $request->getSchemeAndHttpHost() . '/api/v1';
$manager->setSerializer(new JsonApiSerializer($baseUrl));
@@ -197,52 +202,29 @@ class AccountController extends Controller
}
/**
* All the available types.
*
* @param string $type
*
* @return array
*/
private function mapTypes(string $type): array
{
$types = [
'all' => [
AccountType::DEFAULT,
AccountType::CASH,
AccountType::ASSET,
AccountType::EXPENSE,
AccountType::REVENUE,
AccountType::INITIAL_BALANCE,
AccountType::BENEFICIARY,
AccountType::IMPORT,
AccountType::RECONCILIATION,
AccountType::LOAN,
],
'asset' => [
AccountType::DEFAULT,
AccountType::ASSET,
],
'cash' => [
AccountType::CASH,
],
'expense' => [
AccountType::EXPENSE,
AccountType::BENEFICIARY,
],
'revenue' => [
AccountType::REVENUE,
],
'special' => [
AccountType::CASH,
AccountType::INITIAL_BALANCE,
AccountType::IMPORT,
AccountType::RECONCILIATION,
AccountType::LOAN,
],
'hidden' => [
AccountType::INITIAL_BALANCE,
AccountType::IMPORT,
AccountType::RECONCILIATION,
AccountType::LOAN,
],
$types = [
'all' => [AccountType::DEFAULT, AccountType::CASH, AccountType::ASSET, AccountType::EXPENSE, AccountType::REVENUE,
AccountType::INITIAL_BALANCE, AccountType::BENEFICIARY, AccountType::IMPORT, AccountType::RECONCILIATION,
AccountType::LOAN,AccountType::DEBT, AccountType::MORTGAGE],
'asset' => [AccountType::DEFAULT, AccountType::ASSET,],
'cash' => [AccountType::CASH,],
'expense' => [AccountType::EXPENSE, AccountType::BENEFICIARY,],
'revenue' => [AccountType::REVENUE,],
'special' => [AccountType::CASH, AccountType::INITIAL_BALANCE, AccountType::IMPORT, AccountType::RECONCILIATION,],
'hidden' => [AccountType::INITIAL_BALANCE, AccountType::IMPORT, AccountType::RECONCILIATION],
'liability' => [AccountType::DEBT, AccountType::LOAN, AccountType::MORTGAGE, AccountType::CREDITCARD],
'liabilities' => [AccountType::DEBT, AccountType::LOAN, AccountType::MORTGAGE, AccountType::CREDITCARD],
'cc' => [AccountType::CREDITCARD],
'creditcard' => [AccountType::CREDITCARD],
'credit_card' => [AccountType::CREDITCARD],
AccountType::DEFAULT => [AccountType::DEFAULT],
AccountType::CASH => [AccountType::CASH],
AccountType::ASSET => [AccountType::ASSET],
@@ -253,11 +235,16 @@ class AccountController extends Controller
AccountType::IMPORT => [AccountType::IMPORT],
AccountType::RECONCILIATION => [AccountType::RECONCILIATION],
AccountType::LOAN => [AccountType::LOAN],
AccountType::MORTGAGE => [AccountType::MORTGAGE],
AccountType::DEBT => [AccountType::DEBT],
AccountType::CREDITCARD => [AccountType::CREDITCARD],
];
$return = $types['all'];
if (isset($types[$type])) {
return $types[$type];
$return = $types[$type];
}
return $types['all']; // @codeCoverageIgnore
return $return; // @codeCoverageIgnore
}
}

View File

@@ -0,0 +1,235 @@
<?php
/**
* AttachmentController.php
* Copyright (c) 2018 thegrumpydictator@gmail.com
*
* This file is part of Firefly III.
*
* Firefly III is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Firefly III 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Firefly III. If not, see <http://www.gnu.org/licenses/>.
*/
declare(strict_types=1);
namespace FireflyIII\Api\V1\Controllers;
use FireflyIII\Api\V1\Requests\AttachmentRequest;
use FireflyIII\Exceptions\FireflyException;
use FireflyIII\Helpers\Attachments\AttachmentHelperInterface;
use FireflyIII\Models\Attachment;
use FireflyIII\Repositories\Attachment\AttachmentRepositoryInterface;
use FireflyIII\Transformers\AttachmentTransformer;
use FireflyIII\User;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Http\Response as LaravelResponse;
use Illuminate\Pagination\LengthAwarePaginator;
use League\Fractal\Manager;
use League\Fractal\Pagination\IlluminatePaginatorAdapter;
use League\Fractal\Resource\Collection as FractalCollection;
use League\Fractal\Resource\Item;
use League\Fractal\Serializer\JsonApiSerializer;
/**
* Class AttachmentController.
*
* @SuppressWarnings(PHPMD.CouplingBetweenObjects)
*/
class AttachmentController extends Controller
{
/** @var AttachmentRepositoryInterface The attachment repository */
private $repository;
/**
* AccountController constructor.
*/
public function __construct()
{
parent::__construct();
$this->middleware(
function ($request, $next) {
/** @var User $user */
$user = auth()->user();
$this->repository = app(AttachmentRepositoryInterface::class);
$this->repository->setUser($user);
return $next($request);
}
);
}
/**
* Remove the specified resource from storage.
*
* @param Attachment $attachment
*
* @return JsonResponse
*/
public function delete(Attachment $attachment): JsonResponse
{
$this->repository->destroy($attachment);
return response()->json([], 204);
}
/**
* Download an attachment.
*
* @param Attachment $attachment
*
* @return LaravelResponse
* @throws FireflyException
*/
public function download(Attachment $attachment): LaravelResponse
{
if (false === $attachment->uploaded) {
throw new FireflyException('No file has been uploaded for this attachment (yet).');
}
if ($this->repository->exists($attachment)) {
$content = $this->repository->getContent($attachment);
$quoted = sprintf('"%s"', addcslashes(basename($attachment->filename), '"\\'));
/** @var LaravelResponse $response */
$response = response($content, 200);
$response
->header('Content-Description', 'File Transfer')
->header('Content-Type', 'application/octet-stream')
->header('Content-Disposition', 'attachment; filename=' . $quoted)
->header('Content-Transfer-Encoding', 'binary')
->header('Connection', 'Keep-Alive')
->header('Expires', '0')
->header('Cache-Control', 'must-revalidate, post-check=0, pre-check=0')
->header('Pragma', 'public')
->header('Content-Length', \strlen($content));
return $response;
}
throw new FireflyException('Could not find the indicated attachment. The file is no longer there.');
}
/**
* Display a listing of the resource.
*
* @param Request $request
*
* @return JsonResponse
*/
public function index(Request $request): JsonResponse
{
// create some objects:
$manager = new Manager;
$baseUrl = $request->getSchemeAndHttpHost() . '/api/v1';
// types to get, page size:
$pageSize = (int)app('preferences')->getForUser(auth()->user(), 'listPageSize', 50)->data;
// get list of accounts. Count it and split it.
$collection = $this->repository->get();
$count = $collection->count();
$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.attachments.index') . $this->buildParams());
// present to user.
$manager->setSerializer(new JsonApiSerializer($baseUrl));
$resource = new FractalCollection($attachments, new AttachmentTransformer($this->parameters), 'attachments');
$resource->setPaginator(new IlluminatePaginatorAdapter($paginator));
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', 'application/vnd.api+json');
}
/**
* Display the specified resource.
*
* @param Request $request
* @param Attachment $attachment
*
* @return JsonResponse
*/
public function show(Request $request, Attachment $attachment): JsonResponse
{
$manager = new Manager;
// add include parameter:
$include = $request->get('include') ?? '';
$manager->parseIncludes($include);
$baseUrl = $request->getSchemeAndHttpHost() . '/api/v1';
$manager->setSerializer(new JsonApiSerializer($baseUrl));
$resource = new Item($attachment, new AttachmentTransformer($this->parameters), 'attachments');
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', 'application/vnd.api+json');
}
/**
* Store a newly created resource in storage.
*
* @param AttachmentRequest $request
*
* @return JsonResponse
* @throws FireflyException
*/
public function store(AttachmentRequest $request): JsonResponse
{
$data = $request->getAll();
$attachment = $this->repository->store($data);
$manager = new Manager;
$baseUrl = $request->getSchemeAndHttpHost() . '/api/v1';
$manager->setSerializer(new JsonApiSerializer($baseUrl));
$resource = new Item($attachment, new AttachmentTransformer($this->parameters), 'attachments');
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', 'application/vnd.api+json');
}
/**
* Update the specified resource in storage.
*
* @param AttachmentRequest $request
* @param Attachment $attachment
*
* @return JsonResponse
*/
public function update(AttachmentRequest $request, Attachment $attachment): JsonResponse
{
$data = $request->getAll();
$this->repository->update($attachment, $data);
$manager = new Manager;
$baseUrl = $request->getSchemeAndHttpHost() . '/api/v1';
$manager->setSerializer(new JsonApiSerializer($baseUrl));
$resource = new Item($attachment, new AttachmentTransformer($this->parameters), 'attachments');
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', 'application/vnd.api+json');
}
/**
* Upload an attachment.
*
* @param Request $request
* @param Attachment $attachment
*
* @return JsonResponse
*/
public function upload(Request $request, Attachment $attachment): JsonResponse
{
/** @var AttachmentHelperInterface $helper */
$helper = app(AttachmentHelperInterface::class);
$body = $request->getContent();
$helper->saveAttachmentFromApi($attachment, $body);
return response()->json([], 204);
}
}

View File

@@ -0,0 +1,195 @@
<?php
/**
* AvailableBudgetController.php
* Copyright (c) 2018 thegrumpydictator@gmail.com
*
* This file is part of Firefly III.
*
* Firefly III is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Firefly III 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Firefly III. If not, see <http://www.gnu.org/licenses/>.
*/
declare(strict_types=1);
namespace FireflyIII\Api\V1\Controllers;
use FireflyIII\Api\V1\Requests\AvailableBudgetRequest;
use FireflyIII\Exceptions\FireflyException;
use FireflyIII\Models\AvailableBudget;
use FireflyIII\Repositories\Budget\BudgetRepositoryInterface;
use FireflyIII\Repositories\Currency\CurrencyRepositoryInterface;
use FireflyIII\Transformers\AvailableBudgetTransformer;
use FireflyIII\User;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Pagination\LengthAwarePaginator;
use League\Fractal\Manager;
use League\Fractal\Pagination\IlluminatePaginatorAdapter;
use League\Fractal\Resource\Collection as FractalCollection;
use League\Fractal\Resource\Item;
use League\Fractal\Serializer\JsonApiSerializer;
/**
* Class AvailableBudgetController.
*
* @SuppressWarnings(PHPMD.CouplingBetweenObjects)
*/
class AvailableBudgetController extends Controller
{
/** @var CurrencyRepositoryInterface The currency repository */
private $currencyRepository;
/** @var BudgetRepositoryInterface The budget repository */
private $repository;
/**
* AccountController constructor.
*/
public function __construct()
{
parent::__construct();
$this->middleware(
function ($request, $next) {
/** @var User $user */
$user = auth()->user();
$this->repository = app(BudgetRepositoryInterface::class);
$this->currencyRepository = app(CurrencyRepositoryInterface::class);
$this->repository->setUser($user);
return $next($request);
}
);
}
/**
* Remove the specified resource from storage.
*
* @param AvailableBudget $availableBudget
*
* @return JsonResponse
*/
public function delete(AvailableBudget $availableBudget): JsonResponse
{
$this->repository->destroyAvailableBudget($availableBudget);
return response()->json([], 204);
}
/**
* Display a listing of the resource.
*
* @param Request $request
*
* @return JsonResponse
*/
public function index(Request $request): JsonResponse
{
// create some objects:
$manager = new Manager;
$baseUrl = $request->getSchemeAndHttpHost() . '/api/v1';
// types to get, page size:
$pageSize = (int)app('preferences')->getForUser(auth()->user(), 'listPageSize', 50)->data;
// get list of available budgets. Count it and split it.
$collection = $this->repository->getAvailableBudgets();
$count = $collection->count();
$availableBudgets = $collection->slice(($this->parameters->get('page') - 1) * $pageSize, $pageSize);
// make paginator:
$paginator = new LengthAwarePaginator($availableBudgets, $count, $pageSize, $this->parameters->get('page'));
$paginator->setPath(route('api.v1.available_budgets.index') . $this->buildParams());
// present to user.
$manager->setSerializer(new JsonApiSerializer($baseUrl));
$resource = new FractalCollection($availableBudgets, new AvailableBudgetTransformer($this->parameters), 'available_budgets');
$resource->setPaginator(new IlluminatePaginatorAdapter($paginator));
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', 'application/vnd.api+json');
}
/**
* Display the specified resource.
*
* @param Request $request
* @param AvailableBudget $availableBudget
*
* @return JsonResponse
*/
public function show(Request $request, AvailableBudget $availableBudget): JsonResponse
{
$manager = new Manager;
// add include parameter:
$include = $request->get('include') ?? '';
$manager->parseIncludes($include);
$baseUrl = $request->getSchemeAndHttpHost() . '/api/v1';
$manager->setSerializer(new JsonApiSerializer($baseUrl));
$resource = new Item($availableBudget, new AvailableBudgetTransformer($this->parameters), 'available_budgets');
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', 'application/vnd.api+json');
}
/**
* Store a newly created resource in storage.
*
* @param AvailableBudgetRequest $request
*
* @return JsonResponse
* @throws FireflyException
*/
public function store(AvailableBudgetRequest $request): JsonResponse
{
$data = $request->getAll();
$currency = $this->currencyRepository->findNull($data['currency_id']);
if (null === $currency) {
$currency = $this->currencyRepository->findByCodeNull($data['currency_code']);
}
if (null === $currency) {
throw new FireflyException('Could not find the indicated currency.');
}
$availableBudget = $this->repository->setAvailableBudget($currency, $data['start_date'], $data['end_date'], $data['amount']);
$manager = new Manager;
$baseUrl = $request->getSchemeAndHttpHost() . '/api/v1';
$manager->setSerializer(new JsonApiSerializer($baseUrl));
$resource = new Item($availableBudget, new AvailableBudgetTransformer($this->parameters), 'available_budgets');
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', 'application/vnd.api+json');
}
/**
* Update the specified resource in storage.
*
* @param AvailableBudgetRequest $request
* @param AvailableBudget $availableBudget
*
* @return JsonResponse
*/
public function update(AvailableBudgetRequest $request, AvailableBudget $availableBudget): JsonResponse
{
$data = $request->getAll();
$this->repository->updateAvailableBudget($availableBudget, $data);
$manager = new Manager;
$baseUrl = $request->getSchemeAndHttpHost() . '/api/v1';
$manager->setSerializer(new JsonApiSerializer($baseUrl));
$resource = new Item($availableBudget, new AvailableBudgetTransformer($this->parameters), 'available_budgets');
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', 'application/vnd.api+json');
}
}

View File

@@ -1,4 +1,5 @@
<?php
/**
* BillController.php
* Copyright (c) 2018 thegrumpydictator@gmail.com
@@ -18,6 +19,7 @@
* You should have received a copy of the GNU General Public License
* along with Firefly III. If not, see <http://www.gnu.org/licenses/>.
*/
declare(strict_types=1);
namespace FireflyIII\Api\V1\Controllers;
@@ -27,6 +29,8 @@ use FireflyIII\Exceptions\FireflyException;
use FireflyIII\Models\Bill;
use FireflyIII\Repositories\Bill\BillRepositoryInterface;
use FireflyIII\Transformers\BillTransformer;
use FireflyIII\User;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Collection;
use League\Fractal\Manager;
@@ -34,29 +38,29 @@ use League\Fractal\Pagination\IlluminatePaginatorAdapter;
use League\Fractal\Resource\Collection as FractalCollection;
use League\Fractal\Resource\Item;
use League\Fractal\Serializer\JsonApiSerializer;
use Preferences;
/**
* Class BillController
* Class BillController.
*/
class BillController extends Controller
{
/** @var BillRepositoryInterface */
/** @var BillRepositoryInterface The bill repository */
private $repository;
/**
* BillController constructor.
*
* @throws \FireflyIII\Exceptions\FireflyException
*/
public function __construct()
{
parent::__construct();
$this->middleware(
function ($request, $next) {
/** @var User $admin */
$admin = auth()->user();
/** @var BillRepositoryInterface repository */
$this->repository = app(BillRepositoryInterface::class);
$this->repository->setUser(auth()->user());
$this->repository->setUser($admin);
return $next($request);
}
@@ -66,11 +70,11 @@ class BillController extends Controller
/**
* Remove the specified resource from storage.
*
* @param \FireflyIII\Models\Bill $bill
* @param Bill $bill
*
* @return \Illuminate\Http\Response
* @return JsonResponse
*/
public function delete(Bill $bill)
public function delete(Bill $bill): JsonResponse
{
$this->repository->destroy($bill);
@@ -82,11 +86,11 @@ class BillController extends Controller
*
* @param Request $request
*
* @return \Illuminate\Http\JsonResponse
* @return JsonResponse
*/
public function index(Request $request)
public function index(Request $request): JsonResponse
{
$pageSize = intval(Preferences::getForUser(auth()->user(), 'listPageSize', 50)->data);
$pageSize = (int)app('preferences')->getForUser(auth()->user(), 'listPageSize', 50)->data;
$paginator = $this->repository->getPaginator($pageSize);
/** @var Collection $bills */
$bills = $paginator->getCollection();
@@ -103,12 +107,14 @@ class BillController extends Controller
/**
* Show the specified bill.
*
* @param Request $request
* @param Bill $bill
*
* @return \Illuminate\Http\JsonResponse
* @return JsonResponse
*/
public function show(Request $request, Bill $bill)
public function show(Request $request, Bill $bill): JsonResponse
{
$manager = new Manager();
// add include parameter:
@@ -124,31 +130,39 @@ class BillController extends Controller
}
/**
* Store a bill.
*
* @param BillRequest $request
*
* @return \Illuminate\Http\JsonResponse
* @return JsonResponse
* @throws FireflyException
*/
public function store(BillRequest $request)
public function store(BillRequest $request): JsonResponse
{
$bill = $this->repository->store($request->getAll());
$manager = new Manager();
$baseUrl = $request->getSchemeAndHttpHost() . '/api/v1';
$manager->setSerializer(new JsonApiSerializer($baseUrl));
$bill = $this->repository->store($request->getAll());
if (null !== $bill) {
$manager = new Manager();
$baseUrl = $request->getSchemeAndHttpHost() . '/api/v1';
$manager->setSerializer(new JsonApiSerializer($baseUrl));
$resource = new Item($bill, new BillTransformer($this->parameters), 'bills');
$resource = new Item($bill, new BillTransformer($this->parameters), 'bills');
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', 'application/vnd.api+json');
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', 'application/vnd.api+json');
}
throw new FireflyException('Could not store new bill.'); // @codeCoverageIgnore
}
/**
* Update a bill.
*
* @param BillRequest $request
* @param Bill $bill
*
* @return \Illuminate\Http\JsonResponse
* @return JsonResponse
*/
public function update(BillRequest $request, Bill $bill)
public function update(BillRequest $request, Bill $bill): JsonResponse
{
$data = $request->getAll();
$bill = $this->repository->update($bill, $data);

View File

@@ -0,0 +1,188 @@
<?php
/**
* BudgetController.php
* Copyright (c) 2018 thegrumpydictator@gmail.com
*
* This file is part of Firefly III.
*
* Firefly III is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Firefly III 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Firefly III. If not, see <http://www.gnu.org/licenses/>.
*/
declare(strict_types=1);
namespace FireflyIII\Api\V1\Controllers;
use FireflyIII\Api\V1\Requests\BudgetRequest;
use FireflyIII\Exceptions\FireflyException;
use FireflyIII\Models\Budget;
use FireflyIII\Repositories\Budget\BudgetRepositoryInterface;
use FireflyIII\Transformers\BudgetTransformer;
use FireflyIII\User;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Pagination\LengthAwarePaginator;
use League\Fractal\Manager;
use League\Fractal\Pagination\IlluminatePaginatorAdapter;
use League\Fractal\Resource\Collection as FractalCollection;
use League\Fractal\Resource\Item;
use League\Fractal\Serializer\JsonApiSerializer;
/**
* Class BudgetController.
*
* @SuppressWarnings(PHPMD.CouplingBetweenObjects)
*/
class BudgetController extends Controller
{
/** @var BudgetRepositoryInterface The budget repository */
private $repository;
/**
* BudgetController constructor.
*/
public function __construct()
{
parent::__construct();
$this->middleware(
function ($request, $next) {
/** @var User $admin */
$admin = auth()->user();
/** @var BudgetRepositoryInterface repository */
$this->repository = app(BudgetRepositoryInterface::class);
$this->repository->setUser($admin);
return $next($request);
}
);
}
/**
* Remove the specified resource from storage.
*
* @param Budget $budget
*
* @return JsonResponse
*/
public function delete(Budget $budget): JsonResponse
{
$this->repository->destroy($budget);
return response()->json([], 204);
}
/**
* Display a listing of the resource.
*
* @param Request $request
*
* @return JsonResponse
*/
public function index(Request $request): JsonResponse
{
// create some objects:
$manager = new Manager;
$baseUrl = $request->getSchemeAndHttpHost() . '/api/v1';
// types to get, page size:
$pageSize = (int)app('preferences')->getForUser(auth()->user(), 'listPageSize', 50)->data;
// get list of budgets. Count it and split it.
$collection = $this->repository->getBudgets();
$count = $collection->count();
$budgets = $collection->slice(($this->parameters->get('page') - 1) * $pageSize, $pageSize);
// make paginator:
$paginator = new LengthAwarePaginator($budgets, $count, $pageSize, $this->parameters->get('page'));
$paginator->setPath(route('api.v1.budgets.index') . $this->buildParams());
// present to user.
$manager->setSerializer(new JsonApiSerializer($baseUrl));
$resource = new FractalCollection($budgets, new BudgetTransformer($this->parameters), 'budgets');
$resource->setPaginator(new IlluminatePaginatorAdapter($paginator));
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', 'application/vnd.api+json');
}
/**
* Show a budget.
*
* @param Request $request
* @param Budget $budget
*
* @return JsonResponse
*/
public function show(Request $request, Budget $budget): JsonResponse
{
$manager = new Manager();
// add include parameter:
$include = $request->get('include') ?? '';
$manager->parseIncludes($include);
$baseUrl = $request->getSchemeAndHttpHost() . '/api/v1';
$manager->setSerializer(new JsonApiSerializer($baseUrl));
$resource = new Item($budget, new BudgetTransformer($this->parameters), 'budgets');
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', 'application/vnd.api+json');
}
/**
* Store a budget.
*
* @param BudgetRequest $request
*
* @return JsonResponse
* @throws FireflyException
*/
public function store(BudgetRequest $request): JsonResponse
{
$budget = $this->repository->store($request->getAll());
if (null !== $budget) {
$manager = new Manager();
$baseUrl = $request->getSchemeAndHttpHost() . '/api/v1';
$manager->setSerializer(new JsonApiSerializer($baseUrl));
$resource = new Item($budget, new BudgetTransformer($this->parameters), 'budgets');
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', 'application/vnd.api+json');
}
throw new FireflyException('Could not store new budget.'); // @codeCoverageIgnore
}
/**
* Update a budget.
*
* @param BudgetRequest $request
* @param Budget $budget
*
* @return JsonResponse
*/
public function update(BudgetRequest $request, Budget $budget): JsonResponse
{
$data = $request->getAll();
$budget = $this->repository->update($budget, $data);
$manager = new Manager();
$baseUrl = $request->getSchemeAndHttpHost() . '/api/v1';
$manager->setSerializer(new JsonApiSerializer($baseUrl));
$resource = new Item($budget, new BudgetTransformer($this->parameters), 'budgets');
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', 'application/vnd.api+json');
}
}

View File

@@ -0,0 +1,197 @@
<?php
/**
* BudgetLimitController.php
* Copyright (c) 2018 thegrumpydictator@gmail.com
*
* This file is part of Firefly III.
*
* Firefly III is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Firefly III 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Firefly III. If not, see <http://www.gnu.org/licenses/>.
*/
declare(strict_types=1);
namespace FireflyIII\Api\V1\Controllers;
use FireflyIII\Api\V1\Requests\BudgetLimitRequest;
use FireflyIII\Exceptions\FireflyException;
use FireflyIII\Models\BudgetLimit;
use FireflyIII\Repositories\Budget\BudgetRepositoryInterface;
use FireflyIII\Transformers\BudgetLimitTransformer;
use FireflyIII\User;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Pagination\LengthAwarePaginator;
use Illuminate\Support\Collection;
use League\Fractal\Manager;
use League\Fractal\Pagination\IlluminatePaginatorAdapter;
use League\Fractal\Resource\Collection as FractalCollection;
use League\Fractal\Resource\Item;
use League\Fractal\Serializer\JsonApiSerializer;
/**
* Class BudgetLimitController.
*
* @SuppressWarnings(PHPMD.CouplingBetweenObjects)
*/
class BudgetLimitController extends Controller
{
/** @var BudgetRepositoryInterface The budget repository */
private $repository;
/**
* AccountController constructor.
*/
public function __construct()
{
parent::__construct();
$this->middleware(
function ($request, $next) {
/** @var User $user */
$user = auth()->user();
$this->repository = app(BudgetRepositoryInterface::class);
$this->repository->setUser($user);
return $next($request);
}
);
}
/**
* Remove the specified resource from storage.
*
* @param BudgetLimit $budgetLimit
*
* @return JsonResponse
*/
public function delete(BudgetLimit $budgetLimit): JsonResponse
{
$this->repository->destroyBudgetLimit($budgetLimit);
return response()->json([], 204);
}
/**
* Display a listing of the resource.
*
* @param Request $request
*
* @return JsonResponse
*/
public function index(Request $request): JsonResponse
{
$manager = new Manager;
$baseUrl = $request->getSchemeAndHttpHost() . '/api/v1';
$budgetId = (int)($request->get('budget_id') ?? 0);
$budget = $this->repository->findNull($budgetId);
$pageSize = (int)app('preferences')->getForUser(auth()->user(), 'listPageSize', 50)->data;
$this->parameters->set('budget_id', $budgetId);
$collection = new Collection;
if (null === $budget) {
$collection = $this->repository->getAllBudgetLimits($this->parameters->get('start'), $this->parameters->get('end'));
}
if (null !== $budget) {
$collection = $this->repository->getBudgetLimits($budget, $this->parameters->get('start'), $this->parameters->get('end'));
}
$count = $collection->count();
$budgetLimits = $collection->slice(($this->parameters->get('page') - 1) * $pageSize, $pageSize);
$paginator = new LengthAwarePaginator($budgetLimits, $count, $pageSize, $this->parameters->get('page'));
$paginator->setPath(route('api.v1.budget_limits.index') . $this->buildParams());
$manager->setSerializer(new JsonApiSerializer($baseUrl));
$resource = new FractalCollection($budgetLimits, new BudgetLimitTransformer($this->parameters), 'budget_limits');
$resource->setPaginator(new IlluminatePaginatorAdapter($paginator));
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', 'application/vnd.api+json');
}
/**
* Display the specified resource.
*
* @param Request $request
* @param BudgetLimit $budgetLimit
*
* @return JsonResponse
*/
public function show(Request $request, BudgetLimit $budgetLimit): JsonResponse
{
$manager = new Manager;
// add include parameter:
$include = $request->get('include') ?? '';
$manager->parseIncludes($include);
$baseUrl = $request->getSchemeAndHttpHost() . '/api/v1';
$manager->setSerializer(new JsonApiSerializer($baseUrl));
$resource = new Item($budgetLimit, new BudgetLimitTransformer($this->parameters), 'budget_limits');
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', 'application/vnd.api+json');
}
/**
* Store a newly created resource in storage.
*
* @param BudgetLimitRequest $request
*
* @return JsonResponse
* @throws FireflyException
*/
public function store(BudgetLimitRequest $request): JsonResponse
{
$data = $request->getAll();
$budget = $this->repository->findNull($data['budget_id']);
if (null === $budget) {
throw new FireflyException('Unknown budget.');
}
$data['budget'] = $budget;
$budgetLimit = $this->repository->storeBudgetLimit($data);
$manager = new Manager;
$baseUrl = $request->getSchemeAndHttpHost() . '/api/v1';
$manager->setSerializer(new JsonApiSerializer($baseUrl));
$resource = new Item($budgetLimit, new BudgetLimitTransformer($this->parameters), 'budget_limits');
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', 'application/vnd.api+json');
}
/**
* Update the specified resource in storage.
*
* @param BudgetLimitRequest $request
* @param BudgetLimit $budgetLimit
*
* @return JsonResponse
*/
public function update(BudgetLimitRequest $request, BudgetLimit $budgetLimit): JsonResponse
{
$data = $request->getAll();
$budget = $this->repository->findNull($data['budget_id']);
if (null === $budget) {
$budget = $budgetLimit->budget;
}
$data['budget'] = $budget;
$budgetLimit = $this->repository->updateBudgetLimit($budgetLimit, $data);
$manager = new Manager;
$baseUrl = $request->getSchemeAndHttpHost() . '/api/v1';
$manager->setSerializer(new JsonApiSerializer($baseUrl));
$resource = new Item($budgetLimit, new BudgetLimitTransformer($this->parameters), 'budget_limits');
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', 'application/vnd.api+json');
}
}

View File

@@ -0,0 +1,188 @@
<?php
/**
* CategoryController.php
* Copyright (c) 2018 thegrumpydictator@gmail.com
*
* This file is part of Firefly III.
*
* Firefly III is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Firefly III 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Firefly III. If not, see <http://www.gnu.org/licenses/>.
*/
declare(strict_types=1);
namespace FireflyIII\Api\V1\Controllers;
use FireflyIII\Api\V1\Requests\CategoryRequest;
use FireflyIII\Exceptions\FireflyException;
use FireflyIII\Models\Category;
use FireflyIII\Repositories\Category\CategoryRepositoryInterface;
use FireflyIII\Transformers\CategoryTransformer;
use FireflyIII\User;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Pagination\LengthAwarePaginator;
use League\Fractal\Manager;
use League\Fractal\Pagination\IlluminatePaginatorAdapter;
use League\Fractal\Resource\Collection as FractalCollection;
use League\Fractal\Resource\Item;
use League\Fractal\Serializer\JsonApiSerializer;
/**
* Class CategoryController.
*
* @SuppressWarnings(PHPMD.CouplingBetweenObjects)
*/
class CategoryController extends Controller
{
/** @var CategoryRepositoryInterface The category repository */
private $repository;
/**
* CategoryController constructor.
*/
public function __construct()
{
parent::__construct();
$this->middleware(
function ($request, $next) {
/** @var User $admin */
$admin = auth()->user();
/** @var CategoryRepositoryInterface repository */
$this->repository = app(CategoryRepositoryInterface::class);
$this->repository->setUser($admin);
return $next($request);
}
);
}
/**
* Remove the specified resource from storage.
*
* @param Category $category
*
* @return JsonResponse
*/
public function delete(Category $category): JsonResponse
{
$this->repository->destroy($category);
return response()->json([], 204);
}
/**
* Display a listing of the resource.
*
* @param Request $request
*
* @return JsonResponse
*/
public function index(Request $request): JsonResponse
{
// create some objects:
$manager = new Manager;
$baseUrl = $request->getSchemeAndHttpHost() . '/api/v1';
// types to get, page size:
$pageSize = (int)app('preferences')->getForUser(auth()->user(), 'listPageSize', 50)->data;
// get list of budgets. Count it and split it.
$collection = $this->repository->getCategories();
$count = $collection->count();
$categories = $collection->slice(($this->parameters->get('page') - 1) * $pageSize, $pageSize);
// make paginator:
$paginator = new LengthAwarePaginator($categories, $count, $pageSize, $this->parameters->get('page'));
$paginator->setPath(route('api.v1.categories.index') . $this->buildParams());
// present to user.
$manager->setSerializer(new JsonApiSerializer($baseUrl));
$resource = new FractalCollection($categories, new CategoryTransformer($this->parameters), 'categories');
$resource->setPaginator(new IlluminatePaginatorAdapter($paginator));
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', 'application/vnd.api+json');
}
/**
* Show the category.
*
* @param Request $request
* @param Category $category
*
* @return JsonResponse
*/
public function show(Request $request, Category $category): JsonResponse
{
$manager = new Manager();
// add include parameter:
$include = $request->get('include') ?? '';
$manager->parseIncludes($include);
$baseUrl = $request->getSchemeAndHttpHost() . '/api/v1';
$manager->setSerializer(new JsonApiSerializer($baseUrl));
$resource = new Item($category, new CategoryTransformer($this->parameters), 'categories');
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', 'application/vnd.api+json');
}
/**
* Store new category.
*
* @param CategoryRequest $request
*
* @return JsonResponse
* @throws FireflyException
*/
public function store(CategoryRequest $request): JsonResponse
{
$category = $this->repository->store($request->getAll());
if (null !== $category) {
$manager = new Manager();
$baseUrl = $request->getSchemeAndHttpHost() . '/api/v1';
$manager->setSerializer(new JsonApiSerializer($baseUrl));
$resource = new Item($category, new CategoryTransformer($this->parameters), 'categories');
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', 'application/vnd.api+json');
}
throw new FireflyException('Could not store new category.'); // @codeCoverageIgnore
}
/**
* Update the category.
*
* @param CategoryRequest $request
* @param Category $category
*
* @return JsonResponse
*/
public function update(CategoryRequest $request, Category $category): JsonResponse
{
$data = $request->getAll();
$category = $this->repository->update($category, $data);
$manager = new Manager();
$baseUrl = $request->getSchemeAndHttpHost() . '/api/v1';
$manager->setSerializer(new JsonApiSerializer($baseUrl));
$resource = new Item($category, new CategoryTransformer($this->parameters), 'categories');
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', 'application/vnd.api+json');
}
}

View File

@@ -0,0 +1,136 @@
<?php
/**
* ConfigurationController.php
* Copyright (c) 2018 thegrumpydictator@gmail.com
*
* This file is part of Firefly III.
*
* Firefly III is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Firefly III 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Firefly III. If not, see <http://www.gnu.org/licenses/>.
*/
declare(strict_types=1);
namespace FireflyIII\Api\V1\Controllers;
use FireflyIII\Exceptions\FireflyException;
use FireflyIII\Models\Configuration;
use FireflyIII\Repositories\User\UserRepositoryInterface;
use FireflyIII\User;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
/**
* Class ConfigurationController.
*/
class ConfigurationController extends Controller
{
/** @var UserRepositoryInterface The user repository */
private $repository;
/**
* BudgetController constructor.
*/
public function __construct()
{
parent::__construct();
$this->middleware(
function ($request, $next) {
/** @noinspection UnusedConstructorDependenciesInspection */
$this->repository = app(UserRepositoryInterface::class);
/** @var User $admin */
$admin = auth()->user();
if (!$this->repository->hasRole($admin, 'owner')) {
/** @noinspection ExceptionsAnnotatingAndHandlingInspection */
throw new FireflyException('No access to method.'); // @codeCoverageIgnore
}
return $next($request);
}
);
}
/**
* Show all configuration.
*
* @return JsonResponse
*/
public function index(): JsonResponse
{
$configData = $this->getConfigData();
return response()->json(['data' => $configData], 200)->header('Content-Type', 'application/vnd.api+json');
}
/**
* Update the configuration.
*
* @param Request $request
*
* @return JsonResponse
* @throws FireflyException
* @SuppressWarnings(PHPMD.CyclomaticComplexity)
*/
public function update(Request $request): JsonResponse
{
$name = $request->get('name');
$value = $request->get('value');
$valid = ['is_demo_site', 'permission_update_check', 'single_user_mode'];
if (!\in_array($name, $valid, true)) {
throw new FireflyException('You cannot edit this configuration value.');
}
$configValue = '';
switch ($name) {
case 'is_demo_site':
case 'single_user_mode':
$configValue = 'true' === $value;
break;
case 'permission_update_check':
$configValue = (int)$value >= -1 && (int)$value <= 1 ? (int)$value : -1;
break;
}
app('fireflyconfig')->set($name, $configValue);
$configData = $this->getConfigData();
return response()->json(['data' => $configData], 200)->header('Content-Type', 'application/vnd.api+json');
}
/**
* Get all config values.
*
* @return array
* @SuppressWarnings(PHPMD.CyclomaticComplexity)
*/
private function getConfigData(): array
{
/** @var Configuration $isDemoSite */
$isDemoSite = app('fireflyconfig')->get('is_demo_site');
/** @var Configuration $updateCheck */
$updateCheck = app('fireflyconfig')->get('permission_update_check');
/** @var Configuration $lastCheck */
$lastCheck = app('fireflyconfig')->get('last_update_check');
/** @var Configuration $singleUser */
$singleUser = app('fireflyconfig')->get('single_user_mode');
$data = [
'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,
'single_user_mode' => null === $singleUser ? null : $singleUser->data,
];
return $data;
}
}

View File

@@ -1,4 +1,5 @@
<?php
/**
* Controller.php
* Copyright (c) 2018 thegrumpydictator@gmail.com
@@ -18,84 +19,80 @@
* You should have received a copy of the GNU General Public License
* along with Firefly III. If not, see <http://www.gnu.org/licenses/>.
*/
declare(strict_types=1);
namespace FireflyIII\Api\V1\Controllers;
use Carbon\Carbon;
use Carbon\Exceptions\InvalidDateException;
use FireflyConfig;
use FireflyIII\Exceptions\FireflyException;
use Illuminate\Foundation\Auth\Access\AuthorizesRequests;
use Illuminate\Foundation\Bus\DispatchesJobs;
use Illuminate\Foundation\Validation\ValidatesRequests;
use Illuminate\Routing\Controller as BaseController;
use Log;
use Symfony\Component\HttpFoundation\ParameterBag;
/**
* Class Controller.
*
* @codeCoverageIgnore
* @SuppressWarnings(PHPMD.NumberOfChildren)
*/
class Controller extends BaseController
{
use AuthorizesRequests, DispatchesJobs, ValidatesRequests;
/** @var ParameterBag */
/** @var ParameterBag Parameters from the URI are stored here. */
protected $parameters;
/**
* Controller constructor.
*
* @throws FireflyException
*/
public function __construct()
{
// is site a demo site?
$isDemoSite = FireflyConfig::get('is_demo_site', config('firefly.configuration.is_demo_site'))->data;
// do not expose API on demo site:
if (true === $isDemoSite) {
throw new FireflyException('The API is not available on the demo site.');
}
// get global parameters
$this->parameters = $this->getParameters();
}
/**
* Method to help build URI's.
*
* @return string
*
* @SuppressWarnings(PHPMD.CyclomaticComplexity)
*/
protected function buildParams(): string
{
$return = '?';
$params = [];
foreach ($this->parameters as $key => $value) {
if($key === 'page') {
if ('page' === $key) {
continue;
}
if ($value instanceof Carbon) {
$params[$key] = $value->format('Y-m-d');
continue;
}
if (!$value instanceof Carbon) {
$params[$key] = $value;
}
$params[$key] = $value;
}
$return .= http_build_query($params);
if (strlen($return) === 1) {
return '';
}
return $return;
}
/**
* Method to grab all parameters from the URI.
*
* @return ParameterBag
* @SuppressWarnings(PHPMD.CyclomaticComplexity)
*/
private function getParameters(): ParameterBag
{
$bag = new ParameterBag;
$page = (int)request()->get('page');
if ($page === 0) {
if (0 === $page) {
$page = 1;
}
$bag->set('page', $page);
@@ -105,11 +102,12 @@ class Controller extends BaseController
foreach ($dates as $field) {
$date = request()->get($field);
$obj = null;
if (!is_null($date)) {
if (null !== $date) {
try {
$obj = new Carbon($date);
} catch (InvalidDateException $e) {
// don't care
Log::error(sprintf('Invalid date exception in API controller: %s', $e->getMessage()));
}
}
$bag->set($field, $obj);

View File

@@ -0,0 +1,219 @@
<?php
/**
* CurrencyController.php
* Copyright (c) 2018 thegrumpydictator@gmail.com
*
* This file is part of Firefly III.
*
* Firefly III is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Firefly III 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Firefly III. If not, see <http://www.gnu.org/licenses/>.
*/
declare(strict_types=1);
namespace FireflyIII\Api\V1\Controllers;
use FireflyIII\Api\V1\Requests\CurrencyRequest;
use FireflyIII\Exceptions\FireflyException;
use FireflyIII\Models\TransactionCurrency;
use FireflyIII\Repositories\Currency\CurrencyRepositoryInterface;
use FireflyIII\Repositories\User\UserRepositoryInterface;
use FireflyIII\Transformers\CurrencyTransformer;
use FireflyIII\User;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Pagination\LengthAwarePaginator;
use League\Fractal\Manager;
use League\Fractal\Pagination\IlluminatePaginatorAdapter;
use League\Fractal\Resource\Collection as FractalCollection;
use League\Fractal\Resource\Item;
use League\Fractal\Serializer\JsonApiSerializer;
/**
* Class CurrencyController.
*
* @SuppressWarnings(PHPMD.CouplingBetweenObjects)
*/
class CurrencyController extends Controller
{
/** @var CurrencyRepositoryInterface The currency repository */
private $repository;
/** @var UserRepositoryInterface The user repository */
private $userRepository;
/**
* CurrencyRepository constructor.
*/
public function __construct()
{
parent::__construct();
$this->middleware(
function ($request, $next) {
/** @var User $admin */
$admin = auth()->user();
/** @var CurrencyRepositoryInterface repository */
$this->repository = app(CurrencyRepositoryInterface::class);
$this->userRepository = app(UserRepositoryInterface::class);
$this->repository->setUser($admin);
return $next($request);
}
);
}
/**
* Remove the specified resource from storage.
*
* @param TransactionCurrency $currency
*
* @return JsonResponse
* @throws FireflyException
*/
public function delete(TransactionCurrency $currency): JsonResponse
{
/** @var User $admin */
$admin = auth()->user();
if (!$this->userRepository->hasRole($admin, 'owner')) {
// access denied:
throw new FireflyException('No access to method, user is not owner.'); // @codeCoverageIgnore
}
if (!$this->repository->canDeleteCurrency($currency)) {
throw new FireflyException('No access to method, currency is in use.'); // @codeCoverageIgnore
}
$this->repository->destroy($currency);
return response()->json([], 204);
}
/**
* Display a listing of the resource.
*
* @param Request $request
*
* @return JsonResponse
*/
public function index(Request $request): JsonResponse
{
$pageSize = (int)app('preferences')->getForUser(auth()->user(), 'listPageSize', 50)->data;
$collection = $this->repository->get();
$count = $collection->count();
// slice them:
$currencies = $collection->slice(($this->parameters->get('page') - 1) * $pageSize, $pageSize);
$paginator = new LengthAwarePaginator($currencies, $count, $pageSize, $this->parameters->get('page'));
$paginator->setPath(route('api.v1.currencies.index') . $this->buildParams());
$manager = new Manager();
$baseUrl = $request->getSchemeAndHttpHost() . '/api/v1';
$manager->setSerializer(new JsonApiSerializer($baseUrl));
$defaultCurrency = app('amount')->getDefaultCurrencyByUser(auth()->user());
$this->parameters->set('defaultCurrency', $defaultCurrency);
$resource = new FractalCollection($currencies, new CurrencyTransformer($this->parameters), 'currencies');
$resource->setPaginator(new IlluminatePaginatorAdapter($paginator));
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', 'application/vnd.api+json');
}
/**
* Show a currency.
*
* @param Request $request
* @param TransactionCurrency $currency
*
* @return JsonResponse
*/
public function show(Request $request, TransactionCurrency $currency): JsonResponse
{
$manager = new Manager();
// add include parameter:
$include = $request->get('include') ?? '';
$manager->parseIncludes($include);
$baseUrl = $request->getSchemeAndHttpHost() . '/api/v1';
$manager->setSerializer(new JsonApiSerializer($baseUrl));
$defaultCurrency = app('amount')->getDefaultCurrencyByUser(auth()->user());
$this->parameters->set('defaultCurrency', $defaultCurrency);
$resource = new Item($currency, new CurrencyTransformer($this->parameters), '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
*/
public function store(CurrencyRequest $request): JsonResponse
{
$currency = $this->repository->store($request->getAll());
if (null !== $currency) {
if (true === $request->boolean('default')) {
app('preferences')->set('currencyPreference', $currency->code);
app('preferences')->mark();
}
$manager = new Manager();
$baseUrl = $request->getSchemeAndHttpHost() . '/api/v1';
$manager->setSerializer(new JsonApiSerializer($baseUrl));
$defaultCurrency = app('amount')->getDefaultCurrencyByUser(auth()->user());
$this->parameters->set('defaultCurrency', $defaultCurrency);
$resource = new Item($currency, new CurrencyTransformer($this->parameters), 'currencies');
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', 'application/vnd.api+json');
}
throw new FireflyException('Could not store new currency.'); // @codeCoverageIgnore
}
/**
* Update a currency.
*
* @param CurrencyRequest $request
* @param TransactionCurrency $currency
*
* @return JsonResponse
*/
public function update(CurrencyRequest $request, TransactionCurrency $currency): JsonResponse
{
$data = $request->getAll();
$currency = $this->repository->update($currency, $data);
if (true === $request->boolean('default')) {
app('preferences')->set('currencyPreference', $currency->code);
app('preferences')->mark();
}
$manager = new Manager();
$baseUrl = $request->getSchemeAndHttpHost() . '/api/v1';
$manager->setSerializer(new JsonApiSerializer($baseUrl));
$defaultCurrency = app('amount')->getDefaultCurrencyByUser(auth()->user());
$this->parameters->set('defaultCurrency', $defaultCurrency);
$resource = new Item($currency, new CurrencyTransformer($this->parameters), 'currencies');
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', 'application/vnd.api+json');
}
}

View File

@@ -0,0 +1,111 @@
<?php
/**
* CurrencyExchangeRateController.php
* Copyright (c) 2018 thegrumpydictator@gmail.com
*
* This file is part of Firefly III.
*
* Firefly III is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Firefly III 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Firefly III. If not, see <http://www.gnu.org/licenses/>.
*/
declare(strict_types=1);
namespace FireflyIII\Api\V1\Controllers;
use Carbon\Carbon;
use FireflyIII\Exceptions\FireflyException;
use FireflyIII\Repositories\Currency\CurrencyRepositoryInterface;
use FireflyIII\Services\Currency\ExchangeRateInterface;
use FireflyIII\Transformers\CurrencyExchangeRateTransformer;
use FireflyIII\User;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use League\Fractal\Manager;
use League\Fractal\Resource\Item;
use League\Fractal\Serializer\JsonApiSerializer;
/**
* Class CurrencyExchangeRateController
*/
class CurrencyExchangeRateController extends Controller
{
/** @var CurrencyRepositoryInterface The currency repository */
private $repository;
/**
* CurrencyExchangeRateController constructor.
*/
public function __construct()
{
parent::__construct();
$this->middleware(
function ($request, $next) {
/** @var User $admin */
$admin = auth()->user();
$this->repository = app(CurrencyRepositoryInterface::class);
$this->repository->setUser($admin);
return $next($request);
}
);
}
/**
* Show an exchange rate.
*
* @param Request $request
*
* @return JsonResponse
* @throws FireflyException
*/
public function index(Request $request): JsonResponse
{
// create some objects:
$manager = new Manager;
$baseUrl = $request->getSchemeAndHttpHost() . '/api/v1';
$manager->setSerializer(new JsonApiSerializer($baseUrl));
$fromCurrency = $this->repository->findByCodeNull($request->get('from') ?? 'EUR');
$toCurrency = $this->repository->findByCodeNull($request->get('to') ?? 'USD');
if (null === $fromCurrency) {
throw new FireflyException('Unknown source currency.');
}
if (null === $toCurrency) {
throw new FireflyException('Unknown destination currency.');
}
$dateObj = Carbon::createFromFormat('Y-m-d', $request->get('date') ?? date('Y-m-d'));
$this->parameters->set('from', $fromCurrency->code);
$this->parameters->set('to', $toCurrency->code);
$this->parameters->set('date', $dateObj->format('Y-m-d'));
$rate = $this->repository->getExchangeRate($fromCurrency, $toCurrency, $dateObj);
if (null === $rate) {
/** @var User $admin */
$admin = auth()->user();
// create service:
/** @var ExchangeRateInterface $service */
$service = app(ExchangeRateInterface::class);
$service->setUser($admin);
$rate = $service->getRate($fromCurrency, $toCurrency, $dateObj);
}
$resource = new Item($rate, new CurrencyExchangeRateTransformer($this->parameters), 'currency_exchange_rates');
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', 'application/vnd.api+json');
}
}

View File

@@ -0,0 +1,216 @@
<?php
/**
* JournalLinkController.php
* Copyright (c) 2018 thegrumpydictator@gmail.com
*
* This file is part of Firefly III.
*
* Firefly III is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Firefly III 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Firefly III. If not, see <http://www.gnu.org/licenses/>.
*/
declare(strict_types=1);
namespace FireflyIII\Api\V1\Controllers;
use FireflyIII\Api\V1\Requests\JournalLinkRequest;
use FireflyIII\Exceptions\FireflyException;
use FireflyIII\Models\TransactionJournalLink;
use FireflyIII\Repositories\Journal\JournalRepositoryInterface;
use FireflyIII\Repositories\LinkType\LinkTypeRepositoryInterface;
use FireflyIII\Transformers\JournalLinkTransformer;
use FireflyIII\User;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Pagination\LengthAwarePaginator;
use League\Fractal\Manager;
use League\Fractal\Pagination\IlluminatePaginatorAdapter;
use League\Fractal\Resource\Collection as FractalCollection;
use League\Fractal\Resource\Item;
use League\Fractal\Serializer\JsonApiSerializer;
/**
* Class JournalLinkController.
*
* @SuppressWarnings(PHPMD.CouplingBetweenObjects)
*/
class JournalLinkController extends Controller
{
/** @var JournalRepositoryInterface The journal repository */
private $journalRepository;
/** @var LinkTypeRepositoryInterface The link type repository */
private $repository;
/**
* JournalLinkController constructor.
*/
public function __construct()
{
parent::__construct();
$this->middleware(
function ($request, $next) {
/** @var User $user */
$user = auth()->user();
$this->repository = app(LinkTypeRepositoryInterface::class);
$this->journalRepository = app(JournalRepositoryInterface::class);
$this->repository->setUser($user);
$this->journalRepository->setUser($user);
return $next($request);
}
);
}
/**
* Delete the resource.
*
* @param TransactionJournalLink $link
*
* @return JsonResponse
*/
public function delete(TransactionJournalLink $link): JsonResponse
{
$this->repository->destroyLink($link);
return response()->json([], 204);
}
/**
* List all of them.
*
* @param Request $request
*
* @return JsonResponse]
*/
public function index(Request $request): JsonResponse
{
// create some objects:
$manager = new Manager;
$baseUrl = $request->getSchemeAndHttpHost() . '/api/v1';
// read type from URI
$name = $request->get('name') ?? null;
// types to get, page size:
$pageSize = (int)app('preferences')->getForUser(auth()->user(), 'listPageSize', 50)->data;
$linkType = $this->repository->findByName($name);
// get list of accounts. Count it and split it.
$collection = $this->repository->getJournalLinks($linkType);
$count = $collection->count();
$journalLinks = $collection->slice(($this->parameters->get('page') - 1) * $pageSize, $pageSize);
// make paginator:
$paginator = new LengthAwarePaginator($journalLinks, $count, $pageSize, $this->parameters->get('page'));
$paginator->setPath(route('api.v1.journal_links.index') . $this->buildParams());
// present to user.
$manager->setSerializer(new JsonApiSerializer($baseUrl));
$resource = new FractalCollection($journalLinks, new JournalLinkTransformer($this->parameters), 'journal_links');
$resource->setPaginator(new IlluminatePaginatorAdapter($paginator));
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', 'application/vnd.api+json');
}
/**
* List single resource.
*
* @param Request $request
* @param TransactionJournalLink $journalLink
*
* @return JsonResponse
*/
public function show(Request $request, TransactionJournalLink $journalLink): JsonResponse
{
$manager = new Manager;
// add include parameter:
$include = $request->get('include') ?? '';
$manager->parseIncludes($include);
$baseUrl = $request->getSchemeAndHttpHost() . '/api/v1';
$manager->setSerializer(new JsonApiSerializer($baseUrl));
$resource = new Item($journalLink, new JournalLinkTransformer($this->parameters), 'journal_links');
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', 'application/vnd.api+json');
}
/**
* Store new object.
*
* @param JournalLinkRequest $request
*
* @return JsonResponse
* @throws FireflyException
*/
public function store(JournalLinkRequest $request): JsonResponse
{
$manager = new Manager;
// add include parameter:
$include = $request->get('include') ?? '';
$manager->parseIncludes($include);
$data = $request->getAll();
$inward = $this->journalRepository->findNull($data['inward_id'] ?? 0);
$outward = $this->journalRepository->findNull($data['outward_id'] ?? 0);
if (null === $inward || null === $outward) {
throw new FireflyException('Source or destination is NULL.');
}
$data['direction'] = 'inward';
$journalLink = $this->repository->storeLink($data, $inward, $outward);
$resource = new Item($journalLink, new JournalLinkTransformer($this->parameters), 'journal_links');
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', 'application/vnd.api+json');
}
/**
* Update object.
*
* @param JournalLinkRequest $request
* @param TransactionJournalLink $journalLink
*
* @return JsonResponse
* @throws FireflyException
*/
public function update(JournalLinkRequest $request, TransactionJournalLink $journalLink): JsonResponse
{
$manager = new Manager;
// add include parameter:
$include = $request->get('include') ?? '';
$manager->parseIncludes($include);
$data = $request->getAll();
$data['inward'] = $this->journalRepository->findNull($data['inward_id'] ?? 0);
$data['outward'] = $this->journalRepository->findNull($data['outward_id'] ?? 0);
if (null === $data['inward'] || null === $data['outward']) {
throw new FireflyException('Source or destination is NULL.');
}
$data['direction'] = 'inward';
$journalLink = $this->repository->updateLink($journalLink, $data);
$resource = new Item($journalLink, new JournalLinkTransformer($this->parameters), 'journal_links');
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', 'application/vnd.api+json');
}
}

View File

@@ -0,0 +1,210 @@
<?php
/**
* LinkTypeController.php
* Copyright (c) 2018 thegrumpydictator@gmail.com
*
* This file is part of Firefly III.
*
* Firefly III is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Firefly III 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Firefly III. If not, see <http://www.gnu.org/licenses/>.
*/
declare(strict_types=1);
namespace FireflyIII\Api\V1\Controllers;
use FireflyIII\Api\V1\Requests\LinkTypeRequest;
use FireflyIII\Exceptions\FireflyException;
use FireflyIII\Models\LinkType;
use FireflyIII\Repositories\LinkType\LinkTypeRepositoryInterface;
use FireflyIII\Repositories\User\UserRepositoryInterface;
use FireflyIII\Transformers\LinkTypeTransformer;
use FireflyIII\User;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Pagination\LengthAwarePaginator;
use League\Fractal\Manager;
use League\Fractal\Pagination\IlluminatePaginatorAdapter;
use League\Fractal\Resource\Collection as FractalCollection;
use League\Fractal\Resource\Item;
use League\Fractal\Serializer\JsonApiSerializer;
/**
* Class LinkTypeController.
*
* @SuppressWarnings(PHPMD.CouplingBetweenObjects)
*/
class LinkTypeController extends Controller
{
/** @var LinkTypeRepositoryInterface The link type repository */
private $repository;
/** @var UserRepositoryInterface The user repository */
private $userRepository;
/**
* LinkTypeController constructor.
*/
public function __construct()
{
parent::__construct();
$this->middleware(
function ($request, $next) {
/** @var User $user */
$user = auth()->user();
$this->repository = app(LinkTypeRepositoryInterface::class);
$this->userRepository = app(UserRepositoryInterface::class);
$this->repository->setUser($user);
return $next($request);
}
);
}
/**
* Delete the resource.
*
* @param LinkType $linkType
*
* @return JsonResponse
* @throws FireflyException
*/
public function delete(LinkType $linkType): JsonResponse
{
if (false === $linkType->editable) {
throw new FireflyException(sprintf('You cannot delete this link type (#%d, "%s")', $linkType->id, $linkType->name));
}
$this->repository->destroy($linkType, null);
return response()->json([], 204);
}
/**
* List all of them.
*
* @param Request $request
*
* @return JsonResponse]
*/
public function index(Request $request): JsonResponse
{
// create some objects:
$manager = new Manager;
$baseUrl = $request->getSchemeAndHttpHost() . '/api/v1';
$pageSize = (int)app('preferences')->getForUser(auth()->user(), 'listPageSize', 50)->data;
// get list of accounts. Count it and split it.
$collection = $this->repository->get();
$count = $collection->count();
$linkTypes = $collection->slice(($this->parameters->get('page') - 1) * $pageSize, $pageSize);
// make paginator:
$paginator = new LengthAwarePaginator($linkTypes, $count, $pageSize, $this->parameters->get('page'));
$paginator->setPath(route('api.v1.link_types.index') . $this->buildParams());
// present to user.
$manager->setSerializer(new JsonApiSerializer($baseUrl));
$resource = new FractalCollection($linkTypes, new LinkTypeTransformer($this->parameters), 'link_types');
$resource->setPaginator(new IlluminatePaginatorAdapter($paginator));
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', 'application/vnd.api+json');
}
/**
* List single resource.
*
* @param Request $request
* @param LinkType $linkType
*
* @return JsonResponse
*/
public function show(Request $request, LinkType $linkType): JsonResponse
{
$manager = new Manager;
// add include parameter:
$include = $request->get('include') ?? '';
$manager->parseIncludes($include);
$baseUrl = $request->getSchemeAndHttpHost() . '/api/v1';
$manager->setSerializer(new JsonApiSerializer($baseUrl));
$resource = new Item($linkType, new LinkTypeTransformer($this->parameters), 'link_types');
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', 'application/vnd.api+json');
}
/**
* Store new object.
*
* @param LinkTypeRequest $request
*
* @return JsonResponse
* @throws FireflyException
*/
public function store(LinkTypeRequest $request): JsonResponse
{
/** @var User $admin */
$admin = auth()->user();
if (!$this->userRepository->hasRole($admin, 'owner')) {
throw new FireflyException('You need the "owner"-role to do this.');
}
$data = $request->getAll();
// if currency ID is 0, find the currency by the code:
$linkType = $this->repository->store($data);
$manager = new Manager;
$baseUrl = $request->getSchemeAndHttpHost() . '/api/v1';
$manager->setSerializer(new JsonApiSerializer($baseUrl));
$resource = new Item($linkType, new LinkTypeTransformer($this->parameters), 'link_types');
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', 'application/vnd.api+json');
}
/**
* Update object.
*
* @param LinkTypeRequest $request
* @param LinkType $linkType
*
* @return JsonResponse
* @throws FireflyException
*/
public function update(LinkTypeRequest $request, LinkType $linkType): JsonResponse
{
if (false === $linkType->editable) {
throw new FireflyException(sprintf('You cannot edit this link type (#%d, "%s")', $linkType->id, $linkType->name));
}
/** @var User $admin */
$admin = auth()->user();
if (!$this->userRepository->hasRole($admin, 'owner')) {
throw new FireflyException('You need the "owner"-role to do this.');
}
$data = $request->getAll();
$this->repository->update($linkType, $data);
$manager = new Manager;
$baseUrl = $request->getSchemeAndHttpHost() . '/api/v1';
$manager->setSerializer(new JsonApiSerializer($baseUrl));
$resource = new Item($linkType, new LinkTypeTransformer($this->parameters), 'link_types');
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', 'application/vnd.api+json');
}
}

View File

@@ -0,0 +1,188 @@
<?php
/**
* PiggyBankController.php
* Copyright (c) 2018 thegrumpydictator@gmail.com
*
* This file is part of Firefly III.
*
* Firefly III is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Firefly III 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Firefly III. If not, see <http://www.gnu.org/licenses/>.
*/
declare(strict_types=1);
namespace FireflyIII\Api\V1\Controllers;
use FireflyIII\Api\V1\Requests\PiggyBankRequest;
use FireflyIII\Exceptions\FireflyException;
use FireflyIII\Models\PiggyBank;
use FireflyIII\Repositories\PiggyBank\PiggyBankRepositoryInterface;
use FireflyIII\Transformers\PiggyBankTransformer;
use FireflyIII\User;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Pagination\LengthAwarePaginator;
use League\Fractal\Manager;
use League\Fractal\Pagination\IlluminatePaginatorAdapter;
use League\Fractal\Resource\Collection as FractalCollection;
use League\Fractal\Resource\Item;
use League\Fractal\Serializer\JsonApiSerializer;
/**
* Class PiggyBankController.
*
* @SuppressWarnings(PHPMD.CouplingBetweenObjects)
*/
class PiggyBankController extends Controller
{
/** @var PiggyBankRepositoryInterface The piggy bank repository */
private $repository;
/**
* PiggyBankController constructor.
*/
public function __construct()
{
parent::__construct();
$this->middleware(
function ($request, $next) {
/** @var User $admin */
$admin = auth()->user();
$this->repository = app(PiggyBankRepositoryInterface::class);
$this->repository->setUser($admin);
return $next($request);
}
);
}
/**
* Delete the resource.
*
* @param PiggyBank $piggyBank
*
* @return JsonResponse
*/
public function delete(PiggyBank $piggyBank): JsonResponse
{
$this->repository->destroy($piggyBank);
return response()->json([], 204);
}
/**
* List all of them.
*
* @param Request $request
*
* @return JsonResponse]
*/
public function index(Request $request): JsonResponse
{
// create some objects:
$manager = new Manager;
$baseUrl = $request->getSchemeAndHttpHost() . '/api/v1';
// types to get, page size:
$pageSize = (int)app('preferences')->getForUser(auth()->user(), 'listPageSize', 50)->data;
// get list of budgets. Count it and split it.
$collection = $this->repository->getPiggyBanks();
$count = $collection->count();
$piggyBanks = $collection->slice(($this->parameters->get('page') - 1) * $pageSize, $pageSize);
// make paginator:
$paginator = new LengthAwarePaginator($piggyBanks, $count, $pageSize, $this->parameters->get('page'));
$paginator->setPath(route('api.v1.piggy_banks.index') . $this->buildParams());
// present to user.
$manager->setSerializer(new JsonApiSerializer($baseUrl));
$resource = new FractalCollection($piggyBanks, new PiggyBankTransformer($this->parameters), 'piggy_banks');
$resource->setPaginator(new IlluminatePaginatorAdapter($paginator));
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', 'application/vnd.api+json');
}
/**
* List single resource.
*
* @param Request $request
* @param PiggyBank $piggyBank
*
* @return JsonResponse
*/
public function show(Request $request, PiggyBank $piggyBank): JsonResponse
{
$manager = new Manager();
// add include parameter:
$include = $request->get('include') ?? '';
$manager->parseIncludes($include);
$baseUrl = $request->getSchemeAndHttpHost() . '/api/v1';
$manager->setSerializer(new JsonApiSerializer($baseUrl));
$resource = new Item($piggyBank, new PiggyBankTransformer($this->parameters), 'piggy_banks');
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', 'application/vnd.api+json');
}
/**
* Store new object.
*
* @param PiggyBankRequest $request
*
* @return JsonResponse
* @throws FireflyException
*/
public function store(PiggyBankRequest $request): JsonResponse
{
$piggyBank = $this->repository->store($request->getAll());
if (null !== $piggyBank) {
$manager = new Manager();
$baseUrl = $request->getSchemeAndHttpHost() . '/api/v1';
$manager->setSerializer(new JsonApiSerializer($baseUrl));
$resource = new Item($piggyBank, new PiggyBankTransformer($this->parameters), 'piggy_banks');
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', 'application/vnd.api+json');
}
throw new FireflyException('Could not store new piggy bank.');
}
/**
* Update piggy bank.
*
* @param PiggyBankRequest $request
* @param PiggyBank $piggyBank
*
* @return JsonResponse
*/
public function update(PiggyBankRequest $request, PiggyBank $piggyBank): JsonResponse
{
$piggyBank = $this->repository->update($piggyBank, $request->getAll());
$manager = new Manager();
$baseUrl = $request->getSchemeAndHttpHost() . '/api/v1';
$manager->setSerializer(new JsonApiSerializer($baseUrl));
$resource = new Item($piggyBank, new PiggyBankTransformer($this->parameters), 'piggy_banks');
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', 'application/vnd.api+json');
}
}

View File

@@ -0,0 +1,145 @@
<?php
/**
* PreferencesController.php
* Copyright (c) 2018 thegrumpydictator@gmail.com
*
* This file is part of Firefly III.
*
* Firefly III is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Firefly III 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Firefly III. If not, see <http://www.gnu.org/licenses/>.
*/
declare(strict_types=1);
namespace FireflyIII\Api\V1\Controllers;
use FireflyIII\Api\V1\Requests\PreferenceRequest;
use FireflyIII\Models\Preference;
use FireflyIII\Transformers\PreferenceTransformer;
use FireflyIII\User;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Collection;
use League\Fractal\Manager;
use League\Fractal\Resource\Collection as FractalCollection;
use League\Fractal\Resource\Item;
use League\Fractal\Serializer\JsonApiSerializer;
/**
*
* Class PreferenceController
*/
class PreferenceController extends Controller
{
/**
* List all of them.
*
* @param Request $request
*
* @return JsonResponse]
*/
public function index(Request $request): JsonResponse
{
/** @var User $user */
$user = auth()->user();
$available = [
'language', 'customFiscalYear', 'fiscalYearStart', 'currencyPreference',
'transaction_journal_optional_fields', 'frontPageAccounts', 'viewRange',
'listPageSize, twoFactorAuthEnabled',
];
$preferences = new Collection;
foreach ($available as $name) {
$pref = app('preferences')->getForUser($user, $name);
if (null !== $pref) {
$preferences->push($pref);
}
}
// create some objects:
$manager = new Manager;
$baseUrl = $request->getSchemeAndHttpHost() . '/api/v1';
// present to user.
$manager->setSerializer(new JsonApiSerializer($baseUrl));
$resource = new FractalCollection($preferences, new PreferenceTransformer($this->parameters), 'preferences');
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', 'application/vnd.api+json');
}
/**
* List single resource.
*
* @param Request $request
* @param Preference $preference
*
* @return JsonResponse
*/
public function show(Request $request, Preference $preference): JsonResponse
{
// create some objects:
$manager = new Manager;
$baseUrl = $request->getSchemeAndHttpHost() . '/api/v1';
// present to user.
$manager->setSerializer(new JsonApiSerializer($baseUrl));
$resource = new Item($preference, new PreferenceTransformer($this->parameters), 'preferences');
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', 'application/vnd.api+json');
}
/**
* Update a preference.
*
* @param PreferenceRequest $request
* @param Preference $preference
*
* @return JsonResponse
* @SuppressWarnings(PHPMD.CyclomaticComplexity)
*/
public function update(PreferenceRequest $request, Preference $preference): JsonResponse
{
$data = $request->getAll();
$newValue = $data['data'];
switch ($preference->name) {
default:
break;
case 'transaction_journal_optional_fields':
case 'frontPageAccounts':
$newValue = explode(',', $data['data']);
break;
case 'listPageSize':
$newValue = (int)$data['data'];
break;
case 'customFiscalYear':
case 'twoFactorAuthEnabled':
$newValue = 1 === (int)$data['data'];
break;
}
$result = app('preferences')->set($preference->name, $newValue);
// create some objects:
$manager = new Manager;
$baseUrl = $request->getSchemeAndHttpHost() . '/api/v1';
// present to user.
$manager->setSerializer(new JsonApiSerializer($baseUrl));
$resource = new Item($result, new PreferenceTransformer($this->parameters), 'preferences');
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', 'application/vnd.api+json');
}
}

View File

@@ -0,0 +1,180 @@
<?php
/**
* RecurrenceController.php
* Copyright (c) 2018 thegrumpydictator@gmail.com
*
* This file is part of Firefly III.
*
* Firefly III is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Firefly III 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Firefly III. If not, see <http://www.gnu.org/licenses/>.
*/
declare(strict_types=1);
namespace FireflyIII\Api\V1\Controllers;
use FireflyIII\Api\V1\Requests\RecurrenceRequest;
use FireflyIII\Models\Recurrence;
use FireflyIII\Repositories\Recurring\RecurringRepositoryInterface;
use FireflyIII\Transformers\RecurrenceTransformer;
use FireflyIII\User;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Pagination\LengthAwarePaginator;
use League\Fractal\Manager;
use League\Fractal\Pagination\IlluminatePaginatorAdapter;
use League\Fractal\Resource\Collection as FractalCollection;
use League\Fractal\Resource\Item;
use League\Fractal\Serializer\JsonApiSerializer;
/**
* Class RecurrenceController
*/
class RecurrenceController extends Controller
{
/** @var RecurringRepositoryInterface The recurring transaction repository */
private $repository;
/**
* RecurrenceController constructor.
*/
public function __construct()
{
parent::__construct();
$this->middleware(
function ($request, $next) {
/** @var User $user */
$user = auth()->user();
/** @var RecurringRepositoryInterface repository */
$this->repository = app(RecurringRepositoryInterface::class);
$this->repository->setUser($user);
return $next($request);
}
);
}
/**
* Delete the resource.
*
* @param Recurrence $recurrence
*
* @return JsonResponse
*/
public function delete(Recurrence $recurrence): JsonResponse
{
$this->repository->destroy($recurrence);
return response()->json([], 204);
}
/**
* List all of them.
*
* @param Request $request
*
* @return JsonResponse]
*/
public function index(Request $request): JsonResponse
{
// create some objects:
$manager = new Manager;
$baseUrl = $request->getSchemeAndHttpHost() . '/api/v1';
// types to get, page size:
$pageSize = (int)app('preferences')->getForUser(auth()->user(), 'listPageSize', 50)->data;
// get list of budgets. Count it and split it.
$collection = $this->repository->getAll();
$count = $collection->count();
$piggyBanks = $collection->slice(($this->parameters->get('page') - 1) * $pageSize, $pageSize);
// make paginator:
$paginator = new LengthAwarePaginator($piggyBanks, $count, $pageSize, $this->parameters->get('page'));
$paginator->setPath(route('api.v1.recurrences.index') . $this->buildParams());
// present to user.
$manager->setSerializer(new JsonApiSerializer($baseUrl));
$resource = new FractalCollection($piggyBanks, new RecurrenceTransformer($this->parameters), 'recurrences');
$resource->setPaginator(new IlluminatePaginatorAdapter($paginator));
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', 'application/vnd.api+json');
}
/**
* List single resource.
*
* @param Request $request
* @param Recurrence $recurrence
*
* @return JsonResponse
*/
public function show(Request $request, Recurrence $recurrence): JsonResponse
{
$manager = new Manager();
// add include parameter:
$include = $request->get('include') ?? '';
$manager->parseIncludes($include);
$baseUrl = $request->getSchemeAndHttpHost() . '/api/v1';
$manager->setSerializer(new JsonApiSerializer($baseUrl));
$resource = new Item($recurrence, new RecurrenceTransformer($this->parameters), 'recurrences');
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', 'application/vnd.api+json');
}
/**
* Store new object.
*
* @param RecurrenceRequest $request
*
* @return JsonResponse
*/
public function store(RecurrenceRequest $request): JsonResponse
{
$recurrence = $this->repository->store($request->getAll());
$manager = new Manager();
$baseUrl = $request->getSchemeAndHttpHost() . '/api/v1';
$manager->setSerializer(new JsonApiSerializer($baseUrl));
$resource = new Item($recurrence, new RecurrenceTransformer($this->parameters), 'recurrences');
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', 'application/vnd.api+json');
}
/**
* Update single recurrence.
*
* @param RecurrenceRequest $request
* @param Recurrence $recurrence
*
* @return JsonResponse
*/
public function update(RecurrenceRequest $request, Recurrence $recurrence): JsonResponse
{
$data = $request->getAll();
$category = $this->repository->update($recurrence, $data);
$manager = new Manager();
$baseUrl = $request->getSchemeAndHttpHost() . '/api/v1';
$manager->setSerializer(new JsonApiSerializer($baseUrl));
$resource = new Item($category, new RecurrenceTransformer($this->parameters), 'recurrences');
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', 'application/vnd.api+json');
}
}

View File

@@ -0,0 +1,178 @@
<?php
/**
* RuleController.php
* Copyright (c) 2018 thegrumpydictator@gmail.com
*
* This file is part of Firefly III.
*
* Firefly III is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Firefly III 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Firefly III. If not, see <http://www.gnu.org/licenses/>.
*/
declare(strict_types=1);
namespace FireflyIII\Api\V1\Controllers;
use FireflyIII\Api\V1\Requests\RuleRequest;
use FireflyIII\Models\Rule;
use FireflyIII\Repositories\Rule\RuleRepositoryInterface;
use FireflyIII\Transformers\RuleTransformer;
use FireflyIII\User;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Pagination\LengthAwarePaginator;
use League\Fractal\Manager;
use League\Fractal\Pagination\IlluminatePaginatorAdapter;
use League\Fractal\Resource\Collection as FractalCollection;
use League\Fractal\Resource\Item;
use League\Fractal\Serializer\JsonApiSerializer;
/**
* Class RuleController
*/
class RuleController extends Controller
{
/** @var RuleRepositoryInterface The rule repository */
private $ruleRepository;
/**
* RuleController constructor.
*/
public function __construct()
{
parent::__construct();
$this->middleware(
function ($request, $next) {
/** @var User $user */
$user = auth()->user();
$this->ruleRepository = app(RuleRepositoryInterface::class);
$this->ruleRepository->setUser($user);
return $next($request);
}
);
}
/**
* Delete the resource.
*
* @param Rule $rule
*
* @return JsonResponse
*/
public function delete(Rule $rule): JsonResponse
{
$this->ruleRepository->destroy($rule);
return response()->json([], 204);
}
/**
* List all of them.
*
* @param Request $request
*
* @return JsonResponse]
*/
public function index(Request $request): JsonResponse
{
// create some objects:
$manager = new Manager;
$baseUrl = $request->getSchemeAndHttpHost() . '/api/v1';
// types to get, page size:
$pageSize = (int)app('preferences')->getForUser(auth()->user(), 'listPageSize', 50)->data;
// get list of budgets. Count it and split it.
$collection = $this->ruleRepository->getAll();
$count = $collection->count();
$rules = $collection->slice(($this->parameters->get('page') - 1) * $pageSize, $pageSize);
// make paginator:
$paginator = new LengthAwarePaginator($rules, $count, $pageSize, $this->parameters->get('page'));
$paginator->setPath(route('api.v1.rules.index') . $this->buildParams());
// present to user.
$manager->setSerializer(new JsonApiSerializer($baseUrl));
$resource = new FractalCollection($rules, new RuleTransformer($this->parameters), 'rules');
$resource->setPaginator(new IlluminatePaginatorAdapter($paginator));
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', 'application/vnd.api+json');
}
/**
* List single resource.
*
* @param Request $request
* @param Rule $rule
*
* @return JsonResponse
*/
public function show(Request $request, Rule $rule): JsonResponse
{
$manager = new Manager();
// add include parameter:
$include = $request->get('include') ?? '';
$manager->parseIncludes($include);
$baseUrl = $request->getSchemeAndHttpHost() . '/api/v1';
$manager->setSerializer(new JsonApiSerializer($baseUrl));
$resource = new Item($rule, new RuleTransformer($this->parameters), 'rules');
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', 'application/vnd.api+json');
}
/**
* Store new object.
*
* @param RuleRequest $request
*
* @return JsonResponse
*/
public function store(RuleRequest $request): JsonResponse
{
$rule = $this->ruleRepository->store($request->getAll());
$manager = new Manager();
$baseUrl = $request->getSchemeAndHttpHost() . '/api/v1';
$manager->setSerializer(new JsonApiSerializer($baseUrl));
$resource = new Item($rule, new RuleTransformer($this->parameters), 'rules');
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', 'application/vnd.api+json');
}
/**
* Update a rule.
*
* @param RuleRequest $request
* @param Rule $rule
*
* @return JsonResponse
*/
public function update(RuleRequest $request, Rule $rule): JsonResponse
{
$rule = $this->ruleRepository->update($rule, $request->getAll());
$manager = new Manager();
$baseUrl = $request->getSchemeAndHttpHost() . '/api/v1';
$manager->setSerializer(new JsonApiSerializer($baseUrl));
$resource = new Item($rule, new RuleTransformer($this->parameters), 'rules');
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', 'application/vnd.api+json');
}
}

View File

@@ -0,0 +1,179 @@
<?php
/**
* RuleGroupController.php
* Copyright (c) 2018 thegrumpydictator@gmail.com
*
* This file is part of Firefly III.
*
* Firefly III is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Firefly III 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Firefly III. If not, see <http://www.gnu.org/licenses/>.
*/
declare(strict_types=1);
namespace FireflyIII\Api\V1\Controllers;
use FireflyIII\Api\V1\Requests\RuleGroupRequest;
use FireflyIII\Models\RuleGroup;
use FireflyIII\Repositories\RuleGroup\RuleGroupRepositoryInterface;
use FireflyIII\Transformers\RuleGroupTransformer;
use FireflyIII\User;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Pagination\LengthAwarePaginator;
use League\Fractal\Manager;
use League\Fractal\Pagination\IlluminatePaginatorAdapter;
use League\Fractal\Resource\Collection as FractalCollection;
use League\Fractal\Resource\Item;
use League\Fractal\Serializer\JsonApiSerializer;
/**
* Class RuleGroupController
*/
class RuleGroupController extends Controller
{
/** @var RuleGroupRepositoryInterface The rule group repository */
private $ruleGroupRepository;
/**
* RuleGroupController constructor.
*/
public function __construct()
{
parent::__construct();
$this->middleware(
function ($request, $next) {
/** @var User $user */
$user = auth()->user();
$this->ruleGroupRepository = app(RuleGroupRepositoryInterface::class);
$this->ruleGroupRepository->setUser($user);
return $next($request);
}
);
}
/**
* Delete the resource.
*
* @param RuleGroup $ruleGroup
*
* @return JsonResponse
*/
public function delete(RuleGroup $ruleGroup): JsonResponse
{
$this->ruleGroupRepository->destroy($ruleGroup, null);
return response()->json([], 204);
}
/**
* List all of them.
*
* @param Request $request
*
* @return JsonResponse]
*/
public function index(Request $request): JsonResponse
{
// create some objects:
$manager = new Manager;
$baseUrl = $request->getSchemeAndHttpHost() . '/api/v1';
// types to get, page size:
$pageSize = (int)app('preferences')->getForUser(auth()->user(), 'listPageSize', 50)->data;
// get list of rule groups. Count it and split it.
$collection = $this->ruleGroupRepository->get();
$count = $collection->count();
$ruleGroups = $collection->slice(($this->parameters->get('page') - 1) * $pageSize, $pageSize);
// make paginator:
$paginator = new LengthAwarePaginator($ruleGroups, $count, $pageSize, $this->parameters->get('page'));
$paginator->setPath(route('api.v1.rule_groups.index') . $this->buildParams());
// present to user.
$manager->setSerializer(new JsonApiSerializer($baseUrl));
$resource = new FractalCollection($ruleGroups, new RuleGroupTransformer($this->parameters), 'rule_groups');
$resource->setPaginator(new IlluminatePaginatorAdapter($paginator));
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', 'application/vnd.api+json');
}
/**
* List single resource.
*
* @param Request $request
* @param RuleGroup $ruleGroup
*
* @return JsonResponse
*/
public function show(Request $request, RuleGroup $ruleGroup): JsonResponse
{
$manager = new Manager();
// add include parameter:
$include = $request->get('include') ?? '';
$manager->parseIncludes($include);
$baseUrl = $request->getSchemeAndHttpHost() . '/api/v1';
$manager->setSerializer(new JsonApiSerializer($baseUrl));
$resource = new Item($ruleGroup, new RuleGroupTransformer($this->parameters), 'rule_groups');
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', 'application/vnd.api+json');
}
/**
* Store new object.
*
* @param RuleGroupRequest $request
*
* @return JsonResponse
*/
public function store(RuleGroupRequest $request): JsonResponse
{
$ruleGroup = $this->ruleGroupRepository->store($request->getAll());
$manager = new Manager();
$baseUrl = $request->getSchemeAndHttpHost() . '/api/v1';
$manager->setSerializer(new JsonApiSerializer($baseUrl));
$resource = new Item($ruleGroup, new RuleGroupTransformer($this->parameters), 'rule_groups');
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', 'application/vnd.api+json');
}
/**
* Update a rule group.
*
* @param RuleGroupRequest $request
* @param RuleGroup $ruleGroup
*
* @return JsonResponse
*/
public function update(RuleGroupRequest $request, RuleGroup $ruleGroup): JsonResponse
{
$ruleGroup = $this->ruleGroupRepository->update($ruleGroup, $request->getAll());
$manager = new Manager();
$baseUrl = $request->getSchemeAndHttpHost() . '/api/v1';
$manager->setSerializer(new JsonApiSerializer($baseUrl));
$resource = new Item($ruleGroup, new RuleGroupTransformer($this->parameters), 'rule_groups');
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', 'application/vnd.api+json');
}
}

View File

@@ -1,4 +1,5 @@
<?php
/**
* TransactionController.php
* Copyright (c) 2018 thegrumpydictator@gmail.com
@@ -24,7 +25,10 @@ declare(strict_types=1);
namespace FireflyIII\Api\V1\Controllers;
use FireflyIII\Api\V1\Requests\TransactionRequest;
use FireflyIII\Helpers\Collector\JournalCollectorInterface;
use FireflyIII\Events\StoredTransactionJournal;
use FireflyIII\Events\UpdatedTransactionJournal;
use FireflyIII\Exceptions\FireflyException;
use FireflyIII\Helpers\Collector\TransactionCollectorInterface;
use FireflyIII\Helpers\Filter\InternalTransferFilter;
use FireflyIII\Helpers\Filter\NegativeAmountFilter;
use FireflyIII\Helpers\Filter\PositiveAmountFilter;
@@ -32,38 +36,39 @@ use FireflyIII\Models\Transaction;
use FireflyIII\Models\TransactionType;
use FireflyIII\Repositories\Journal\JournalRepositoryInterface;
use FireflyIII\Transformers\TransactionTransformer;
use FireflyIII\User;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Collection;
use League\Fractal\Manager;
use League\Fractal\Pagination\IlluminatePaginatorAdapter;
use League\Fractal\Resource\Collection as FractalCollection;
use League\Fractal\Resource\Item;
use League\Fractal\Serializer\JsonApiSerializer;
use Log;
use Preferences;
/**
* Class TransactionController
* @SuppressWarnings(PHPMD.CouplingBetweenObjects)
*/
class TransactionController extends Controller
{
/** @var JournalRepositoryInterface */
/** @var JournalRepositoryInterface The journal repository */
private $repository;
/**
* TransactionController constructor.
*
* @throws \FireflyIII\Exceptions\FireflyException
*/
public function __construct()
{
parent::__construct();
$this->middleware(
function ($request, $next) {
/** @var User $admin */
$admin = auth()->user();
/** @var JournalRepositoryInterface repository */
$this->repository = app(JournalRepositoryInterface::class);
$this->repository->setUser(auth()->user());
$this->repository->setUser($admin);
return $next($request);
}
@@ -75,9 +80,9 @@ class TransactionController extends Controller
*
* @param \FireflyIII\Models\Transaction $transaction
*
* @return \Illuminate\Http\Response
* @return JsonResponse
*/
public function delete(Transaction $transaction)
public function delete(Transaction $transaction): JsonResponse
{
$journal = $transaction->transactionJournal;
$this->repository->destroy($journal);
@@ -86,46 +91,44 @@ class TransactionController extends Controller
}
/**
* Show all transactions.
*
* @param Request $request
*
* @return \Illuminate\Http\JsonResponse
* @return JsonResponse
*/
public function index(Request $request)
public function index(Request $request): JsonResponse
{
$pageSize = intval(Preferences::getForUser(auth()->user(), 'listPageSize', 50)->data);
// read type from URI
$type = $request->get('type') ?? 'default';
$pageSize = (int)app('preferences')->getForUser(auth()->user(), 'listPageSize', 50)->data;
$type = $request->get('type') ?? 'default';
$this->parameters->set('type', $type);
// types to get, page size:
$types = $this->mapTypes($this->parameters->get('type'));
$types = $this->mapTypes($this->parameters->get('type'));
$manager = new Manager();
$baseUrl = $request->getSchemeAndHttpHost() . '/api/v1';
$manager->setSerializer(new JsonApiSerializer($baseUrl));
// collect transactions using the journal collector
$collector = app(JournalCollectorInterface::class);
$collector->setUser(auth()->user());
/** @var User $admin */
$admin = auth()->user();
/** @var TransactionCollectorInterface $collector */
$collector = app(TransactionCollectorInterface::class);
$collector->setUser($admin);
$collector->withOpposingAccount()->withCategoryInformation()->withBudgetInformation();
$collector->setAllAssetAccounts();
// remove internal transfer filter:
if (in_array(TransactionType::TRANSFER, $types)) {
if (\in_array(TransactionType::TRANSFER, $types, true)) {
$collector->removeFilter(InternalTransferFilter::class);
}
if (!is_null($this->parameters->get('start')) && !is_null($this->parameters->get('end'))) {
if (null !== $this->parameters->get('start') && null !== $this->parameters->get('end')) {
$collector->setRange($this->parameters->get('start'), $this->parameters->get('end'));
}
$collector->setLimit($pageSize)->setPage($this->parameters->get('page'));
$collector->setTypes($types);
$paginator = $collector->getPaginatedJournals();
$paginator = $collector->getPaginatedTransactions();
$paginator->setPath(route('api.v1.transactions.index') . $this->buildParams());
$transactions = $paginator->getCollection();
$resource = new FractalCollection($transactions, new TransactionTransformer($this->parameters), 'transactions');
$resource->setPaginator(new IlluminatePaginatorAdapter($paginator));
@@ -134,23 +137,27 @@ class TransactionController extends Controller
/**
* Show a single transaction.
*
* @param Request $request
* @param Transaction $transaction
* @param string $include
*
* @return \Illuminate\Http\JsonResponse
* @return JsonResponse
*/
public function show(Request $request, Transaction $transaction)
public function show(Request $request, Transaction $transaction, string $include = null): JsonResponse
{
$manager = new Manager();
$baseUrl = $request->getSchemeAndHttpHost() . '/api/v1';
$manager->setSerializer(new JsonApiSerializer($baseUrl));
// add include parameter:
$include = $request->get('include') ?? '';
$include = $include ?? '';
$include = $request->get('include') ?? $include;
$manager->parseIncludes($include);
// collect transactions using the journal collector
$collector = app(JournalCollectorInterface::class);
$collector = app(TransactionCollectorInterface::class);
$collector->setUser(auth()->user());
$collector->withOpposingAccount()->withCategoryInformation()->withBudgetInformation();
// filter on specific journals.
@@ -165,23 +172,30 @@ class TransactionController extends Controller
$collector->addFilter(NegativeAmountFilter::class);
}
$transactions = $collector->getJournals();
$transactions = $collector->getTransactions();
$resource = new FractalCollection($transactions, new TransactionTransformer($this->parameters), 'transactions');
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', 'application/vnd.api+json');
}
/**
* @param TransactionRequest $request
* Store a new transaction.
*
* @return \Illuminate\Http\JsonResponse
* @param TransactionRequest $request
*
* @param JournalRepositoryInterface $repository
*
* @throws FireflyException
* @return JsonResponse
*/
public function store(TransactionRequest $request, JournalRepositoryInterface $repository)
public function store(TransactionRequest $request, JournalRepositoryInterface $repository): JsonResponse
{
$data = $request->getAll();
$data['user'] = auth()->user()->id;
$journal = $repository->store($data);
event(new StoredTransactionJournal($journal, 0));
$manager = new Manager();
$baseUrl = $request->getSchemeAndHttpHost() . '/api/v1';
$manager->setSerializer(new JsonApiSerializer($baseUrl));
@@ -191,7 +205,7 @@ class TransactionController extends Controller
$manager->parseIncludes($include);
// collect transactions using the journal collector
$collector = app(JournalCollectorInterface::class);
$collector = app(TransactionCollectorInterface::class);
$collector->setUser(auth()->user());
$collector->withOpposingAccount()->withCategoryInformation()->withBudgetInformation();
// filter on specific journals.
@@ -206,7 +220,7 @@ class TransactionController extends Controller
$collector->addFilter(NegativeAmountFilter::class);
}
$transactions = $collector->getJournals();
$transactions = $collector->getTransactions();
$resource = new FractalCollection($transactions, new TransactionTransformer($this->parameters), 'transactions');
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', 'application/vnd.api+json');
@@ -214,32 +228,32 @@ class TransactionController extends Controller
/**
* Update a transaction.
*
* @param TransactionRequest $request
* @param JournalRepositoryInterface $repository
* @param Transaction $transaction
*
* @return \Illuminate\Http\JsonResponse
* @return JsonResponse
*/
public function update(TransactionRequest $request, JournalRepositoryInterface $repository, Transaction $transaction)
public function update(TransactionRequest $request, JournalRepositoryInterface $repository, Transaction $transaction): JsonResponse
{
$data = $request->getAll();
$data['user'] = auth()->user()->id;
Log::debug('Inside transaction update');
$journal = $repository->update($transaction->transactionJournal, $data);
$manager = new Manager();
$baseUrl = $request->getSchemeAndHttpHost() . '/api/v1';
$journal = $repository->update($transaction->transactionJournal, $data);
$manager = new Manager();
$baseUrl = $request->getSchemeAndHttpHost() . '/api/v1';
$manager->setSerializer(new JsonApiSerializer($baseUrl));
event(new UpdatedTransactionJournal($journal));
// add include parameter:
$include = $request->get('include') ?? '';
$manager->parseIncludes($include);
// needs a lot of extra data to match the journal collector. Or just expand that one.
// collect transactions using the journal collector
$collector = app(JournalCollectorInterface::class);
$collector = app(TransactionCollectorInterface::class);
$collector->setUser(auth()->user());
$collector->withOpposingAccount()->withCategoryInformation()->withBudgetInformation();
// filter on specific journals.
@@ -254,7 +268,7 @@ class TransactionController extends Controller
$collector->addFilter(NegativeAmountFilter::class);
}
$transactions = $collector->getJournals();
$transactions = $collector->getTransactions();
$resource = new FractalCollection($transactions, new TransactionTransformer($this->parameters), 'transactions');
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', 'application/vnd.api+json');
@@ -262,72 +276,38 @@ class TransactionController extends Controller
}
/**
* All the types you can request.
*
* @param string $type
*
* @return array
*/
private function mapTypes(string $type): array
{
$types = [
'all' => [
TransactionType::WITHDRAWAL,
TransactionType::DEPOSIT,
TransactionType::TRANSFER,
TransactionType::OPENING_BALANCE,
TransactionType::RECONCILIATION,
],
'withdrawal' => [
TransactionType::WITHDRAWAL,
],
'withdrawals' => [
TransactionType::WITHDRAWAL,
],
'expense' => [
TransactionType::WITHDRAWAL,
],
'income' => [
TransactionType::DEPOSIT,
],
'deposit' => [
TransactionType::DEPOSIT,
],
'deposits' => [
TransactionType::DEPOSIT,
],
'transfer' => [
TransactionType::TRANSFER,
],
'transfers' => [
TransactionType::TRANSFER,
],
'opening_balance' => [
TransactionType::OPENING_BALANCE,
],
'reconciliation' => [
TransactionType::RECONCILIATION,
],
'reconciliations' => [
TransactionType::RECONCILIATION,
],
'special' => [
TransactionType::OPENING_BALANCE,
TransactionType::RECONCILIATION,
],
'specials' => [
TransactionType::OPENING_BALANCE,
TransactionType::RECONCILIATION,
],
'default' => [
TransactionType::WITHDRAWAL,
TransactionType::DEPOSIT,
TransactionType::TRANSFER,
],
$types = [
'all' => [TransactionType::WITHDRAWAL, TransactionType::DEPOSIT, TransactionType::TRANSFER, TransactionType::OPENING_BALANCE,
TransactionType::RECONCILIATION,],
'withdrawal' => [TransactionType::WITHDRAWAL,],
'withdrawals' => [TransactionType::WITHDRAWAL,],
'expense' => [TransactionType::WITHDRAWAL,],
'income' => [TransactionType::DEPOSIT,],
'deposit' => [TransactionType::DEPOSIT,],
'deposits' => [TransactionType::DEPOSIT,],
'transfer' => [TransactionType::TRANSFER,],
'transfers' => [TransactionType::TRANSFER,],
'opening_balance' => [TransactionType::OPENING_BALANCE,],
'reconciliation' => [TransactionType::RECONCILIATION,],
'reconciliations' => [TransactionType::RECONCILIATION,],
'special' => [TransactionType::OPENING_BALANCE, TransactionType::RECONCILIATION,],
'specials' => [TransactionType::OPENING_BALANCE, TransactionType::RECONCILIATION,],
'default' => [TransactionType::WITHDRAWAL, TransactionType::DEPOSIT, TransactionType::TRANSFER,],
];
$return = $types['default'];
if (isset($types[$type])) {
return $types[$type];
$return = $types[$type];
}
return $types['default']; // @codeCoverageIgnore
return $return;
}
}

View File

@@ -1,4 +1,5 @@
<?php
/**
* UserController.php
* Copyright (c) 2018 thegrumpydictator@gmail.com
@@ -24,9 +25,11 @@ declare(strict_types=1);
namespace FireflyIII\Api\V1\Controllers;
use FireflyIII\Api\V1\Requests\UserRequest;
use FireflyIII\Exceptions\FireflyException;
use FireflyIII\Repositories\User\UserRepositoryInterface;
use FireflyIII\Transformers\UserTransformer;
use FireflyIII\User;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Pagination\LengthAwarePaginator;
use League\Fractal\Manager;
@@ -34,22 +37,21 @@ use League\Fractal\Pagination\IlluminatePaginatorAdapter;
use League\Fractal\Resource\Collection as FractalCollection;
use League\Fractal\Resource\Item;
use League\Fractal\Serializer\JsonApiSerializer;
use Preferences;
use Symfony\Component\HttpFoundation\File\Exception\AccessDeniedException;
/**
* Class UserController
* Class UserController.
*
* @SuppressWarnings(PHPMD.CouplingBetweenObjects)
*/
class UserController extends Controller
{
/** @var UserRepositoryInterface */
/** @var UserRepositoryInterface The user repository */
private $repository;
/**
* UserController constructor.
*
* @throws \FireflyIII\Exceptions\FireflyException
*/
public function __construct()
{
@@ -69,16 +71,19 @@ class UserController extends Controller
*
* @param \FireflyIII\User $user
*
* @return \Illuminate\Http\Response
* @return JsonResponse
* @throws FireflyException
*/
public function delete(User $user)
public function delete(User $user): JsonResponse
{
if (auth()->user()->hasRole('owner')) {
/** @var User $admin */
$admin = auth()->user();
if ($this->repository->hasRole($admin, 'owner')) {
$this->repository->destroy($user);
return response()->json([], 204);
}
throw new AccessDeniedException(''); // @codeCoverageIgnore
throw new FireflyException('No access to method.'); // @codeCoverageIgnore
}
/**
@@ -86,12 +91,12 @@ class UserController extends Controller
*
* @param Request $request
*
* @return \Illuminate\Http\JsonResponse
* @return JsonResponse
*/
public function index(Request $request)
public function index(Request $request): JsonResponse
{
// user preferences
$pageSize = intval(Preferences::getForUser(auth()->user(), 'listPageSize', 50)->data);
$pageSize = (int)app('preferences')->getForUser(auth()->user(), 'listPageSize', 50)->data;
// make manager
$manager = new Manager();
@@ -115,12 +120,14 @@ class UserController extends Controller
}
/**
* Show a single user.
*
* @param Request $request
* @param User $user
*
* @return \Illuminate\Http\JsonResponse
* @return JsonResponse
*/
public function show(Request $request, User $user)
public function show(Request $request, User $user): JsonResponse
{
// make manager
$manager = new Manager();
@@ -138,11 +145,13 @@ class UserController extends Controller
}
/**
* Store a new user.
*
* @param UserRequest $request
*
* @return \Illuminate\Http\JsonResponse
* @return JsonResponse
*/
public function store(UserRequest $request)
public function store(UserRequest $request): JsonResponse
{
$data = $request->getAll();
$user = $this->repository->store($data);
@@ -163,12 +172,14 @@ class UserController extends Controller
}
/**
* Update a user.
*
* @param UserRequest $request
* @param User $user
*
* @return \Illuminate\Http\JsonResponse
* @return JsonResponse
*/
public function update(UserRequest $request, User $user)
public function update(UserRequest $request, User $user): JsonResponse
{
$data = $request->getAll();
$user = $this->repository->update($user, $data);

View File

@@ -1,4 +1,5 @@
<?php
/**
* AccountRequest.php
* Copyright (c) 2018 thegrumpydictator@gmail.com
@@ -22,7 +23,6 @@
declare(strict_types=1);
namespace FireflyIII\Api\V1\Requests;
/**
* Class AccountRequest
*/
@@ -30,6 +30,8 @@ class AccountRequest extends Request
{
/**
* Authorize logged in users.
*
* @return bool
*/
public function authorize(): bool
@@ -39,6 +41,8 @@ class AccountRequest extends Request
}
/**
* Get all data from the request.
*
* @return array
*/
public function getAll(): array
@@ -46,6 +50,7 @@ class AccountRequest extends Request
$data = [
'name' => $this->string('name'),
'active' => $this->boolean('active'),
'include_net_worth' => $this->boolean('include_net_worth'),
'accountType' => $this->string('type'),
'account_type_id' => null,
'currency_id' => $this->integer('currency_id'),
@@ -60,19 +65,35 @@ class AccountRequest extends Request
'ccType' => $this->string('cc_type'),
'ccMonthlyPaymentDate' => $this->string('cc_monthly_payment_date'),
'notes' => $this->string('notes'),
'interest' => $this->string('interest'),
'interest_period' => $this->string('interest_period'),
];
// new fields for liabilities
// 'liability_type' => $this->string('liability_type'),
// 'liability_start_date' => $this->date('liability_start_date'),
//];
if ('liability' === $data['accountType']) {
$data['openingBalance'] = bcmul($this->string('liability_amount'), '-1');
$data['openingBalanceDate'] = $this->date('liability_start_date');
$data['accountType'] = $this->string('liability_type');
$data['account_type_id'] = null;
}
return $data;
}
/**
* The rules that the incoming request must be matched against.
*
* @return array
*/
public function rules(): array
{
$accountRoles = join(',', config('firefly.accountRoles'));
$types = join(',', array_keys(config('firefly.subTitlesByIdentifier')));
$ccPaymentTypes = join(',', array_keys(config('firefly.ccTypes')));
$accountRoles = implode(',', config('firefly.accountRoles'));
$types = implode(',', array_keys(config('firefly.subTitlesByIdentifier')));
$ccPaymentTypes = implode(',', array_keys(config('firefly.ccTypes')));
$rules = [
'name' => 'required|min:1|uniqueAccountForUser',
'opening_balance' => 'numeric|required_with:opening_balance_date|nullable',
@@ -85,10 +106,18 @@ class AccountRequest extends Request
'account_number' => 'between:1,255|nullable|uniqueAccountNumberForUser',
'account_role' => 'in:' . $accountRoles . '|required_if:type,asset',
'active' => 'required|boolean',
'include_net_worth' => 'required|boolean',
'cc_type' => 'in:' . $ccPaymentTypes . '|required_if:account_role,ccAsset',
'cc_monthly_payment_date' => 'date' . '|required_if:account_role,ccAsset|required_if:cc_type,monthlyFull',
'type' => 'required|in:' . $types,
'notes' => 'min:0|max:65536',
// required fields for liabilities:
'liability_type' => 'required_if:type,liability|in:loan,debt,mortgage,credit card',
'liability_amount' => 'required_if:type,liability|min:0|numeric',
'liability_start_date' => 'required_if:type,liability|date',
'interest' => 'required_if:type,liability|between:0,100|numeric',
'interest_period' => 'required_if:type,liability|in:daily,monthly,yearly',
];
switch ($this->method()) {
default:

View File

@@ -0,0 +1,97 @@
<?php
/**
* AttachmentRequest.php
* Copyright (c) 2018 thegrumpydictator@gmail.com
*
* This file is part of Firefly III.
*
* Firefly III is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Firefly III 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Firefly III. If not, see <http://www.gnu.org/licenses/>.
*/
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;
/**
* Class AttachmentRequest
*/
class AttachmentRequest extends Request
{
/**
* Authorize logged in users.
*
* @return bool
*/
public function authorize(): bool
{
// Only allow authenticated users
return auth()->check();
}
/**
* Get all data from the request.
*
* @return array
*/
public function getAll(): array
{
return [
'filename' => $this->string('filename'),
'title' => $this->string('title'),
'notes' => $this->string('notes'),
'model' => $this->string('model'),
'model_id' => $this->integer('model_id'),
];
}
/**
* The rules that the incoming request must be matched against.
*
* @return array
*/
public function rules(): array
{
$models = implode(
',', [
Bill::class,
ImportJob::class,
TransactionJournal::class,
]
);
$model = $this->string('model');
$rules = [
'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)],
];
switch ($this->method()) {
default:
break;
case 'PUT':
case 'PATCH':
unset($rules['model'], $rules['model_id']);
$rules['filename'] = 'between:1,255';
break;
}
return $rules;
}
}

View File

@@ -0,0 +1,77 @@
<?php
/**
* AvailableBudgetRequest.php
* Copyright (c) 2018 thegrumpydictator@gmail.com
*
* This file is part of Firefly III.
*
* Firefly III is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Firefly III 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Firefly III. If not, see <http://www.gnu.org/licenses/>.
*/
declare(strict_types=1);
namespace FireflyIII\Api\V1\Requests;
/**
* Class AvailableBudgetRequest
*/
class AvailableBudgetRequest extends Request
{
/**
* Authorize logged in users.
*
* @return bool
*/
public function authorize(): bool
{
// Only allow authenticated users
return auth()->check();
}
/**
* Get all data from the request.
*
* @return array
*/
public function getAll(): array
{
return [
'currency_id' => $this->integer('currency_id'),
'currency_code' => $this->string('currency_code'),
'amount' => $this->string('amount'),
'start_date' => $this->date('start_date'),
'end_date' => $this->date('end_date'),
];
}
/**
* The rules that the incoming request must be matched against.
*
* @return array
*/
public function rules(): array
{
$rules = [
'currency_id' => 'numeric|exists:transaction_currencies,id|required_without:currency_code',
'currency_code' => 'min:3|max:3|exists:transaction_currencies,code|required_without:currency_id',
'amount' => 'required|numeric|more:0',
'start_date' => 'required|date|before:end_date',
'end_date' => 'required|date|after:start_date',
];
return $rules;
}
}

View File

@@ -1,4 +1,5 @@
<?php
/**
* BillRequest.php
* Copyright (c) 2018 thegrumpydictator@gmail.com
@@ -32,6 +33,8 @@ class BillRequest extends Request
{
/**
* Authorize logged in users.
*
* @return bool
*/
public function authorize(): bool
@@ -41,55 +44,56 @@ class BillRequest extends Request
}
/**
* Get all data from the request.
*
* @return array
*/
public function getAll(): array
{
$data = [
'name' => $this->string('name'),
'match' => $this->string('match'),
'amount_min' => $this->string('amount_min'),
'amount_max' => $this->string('amount_max'),
//'currency_id' => $this->integer('currency_id'),
//'currency_code' => $this->string('currency_code'),
'date' => $this->date('date'),
'repeat_freq' => $this->string('repeat_freq'),
'skip' => $this->integer('skip'),
'automatch' => $this->boolean('automatch'),
'active' => $this->boolean('active'),
'notes' => $this->string('notes'),
'name' => $this->string('name'),
'amount_min' => $this->string('amount_min'),
'amount_max' => $this->string('amount_max'),
'currency_id' => $this->integer('currency_id'),
'currency_code' => $this->string('currency_code'),
'date' => $this->date('date'),
'repeat_freq' => $this->string('repeat_freq'),
'skip' => $this->integer('skip'),
'automatch' => $this->boolean('automatch'),
'active' => $this->boolean('active'),
'notes' => $this->string('notes'),
];
return $data;
}
/**
* The rules that the incoming request must be matched against.
*
* @return array
*/
public function rules(): array
{
$rules = [
'name' => 'required|between:1,255|uniqueObjectForUser:bills,name',
'match' => 'required|between:1,255|uniqueObjectForUser:bills,match',
'amount_min' => 'required|numeric|more:0',
'amount_max' => 'required|numeric|more:0',
//'currency_id' => 'numeric|exists:transaction_currencies,id|required_without:currency_code',
//'currency_code' => 'min:3|max:3|exists:transaction_currencies,code|required_without:currency_id',
'date' => 'required|date',
'repeat_freq' => 'required|in:weekly,monthly,quarterly,half-year,yearly',
'skip' => 'required|between:0,31',
'automatch' => 'required|boolean',
'active' => 'required|boolean',
'notes' => 'between:1,65536',
'name' => 'required|between:1,255|uniqueObjectForUser:bills,name',
'amount_min' => 'required|numeric|more:0',
'amount_max' => 'required|numeric|more:0',
'currency_id' => 'numeric|exists:transaction_currencies,id|required_without:currency_code',
'currency_code' => 'min:3|max:3|exists:transaction_currencies,code|required_without:currency_id',
'date' => 'required|date',
'repeat_freq' => 'required|in:weekly,monthly,quarterly,half-year,yearly',
'skip' => 'required|between:0,31',
'automatch' => 'required|boolean',
'active' => 'required|boolean',
'notes' => 'between:1,65536',
];
switch ($this->method()) {
default:
break;
case 'PUT':
case 'PATCH':
$bill = $this->route()->parameter('bill');
$rules['name'] .= ',' . $bill->id;
$rules['match'] .= ',' . $bill->id;
$bill = $this->route()->parameter('bill');
$rules['name'] .= ',' . $bill->id;
break;
}
@@ -108,10 +112,10 @@ class BillRequest extends Request
$validator->after(
function (Validator $validator) {
$data = $validator->getData();
$min = floatval($data['amount_min'] ?? 0);
$max = floatval($data['amount_max'] ?? 0);
$min = (float)($data['amount_min'] ?? 0);
$max = (float)($data['amount_max'] ?? 0);
if ($min > $max) {
$validator->errors()->add('amount_min', trans('validation.amount_min_over_max'));
$validator->errors()->add('amount_min', (string)trans('validation.amount_min_over_max'));
}
}
);

View File

@@ -0,0 +1,83 @@
<?php
/**
* BudgetLimitRequest.php
* Copyright (c) 2018 thegrumpydictator@gmail.com
*
* This file is part of Firefly III.
*
* Firefly III is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Firefly III 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Firefly III. If not, see <http://www.gnu.org/licenses/>.
*/
declare(strict_types=1);
namespace FireflyIII\Api\V1\Requests;
/**
* Class BudgetLimitRequest
*/
class BudgetLimitRequest extends Request
{
/**
* Authorize logged in users.
*
* @return bool
*/
public function authorize(): bool
{
// Only allow authenticated users
return auth()->check();
}
/**
* Get all data from the request.
*
* @return array
*/
public function getAll(): array
{
return [
'budget_id' => $this->integer('budget_id'),
'start_date' => $this->date('start_date'),
'end_date' => $this->date('end_date'),
'amount' => $this->string('amount'),
];
}
/**
* The rules that the incoming request must be matched against.
*
* @return array
*/
public function rules(): array
{
$rules = [
'budget_id' => 'required|exists:budgets,id|belongsToUser:budgets,id',
'start_date' => 'required|before:end_date|date',
'end_date' => 'required|after:start_date|date',
'amount' => 'required|more:0',
];
switch ($this->method()) {
default:
break;
case 'PUT':
case 'PATCH':
$rules['budget_id'] = 'required|exists:budgets,id|belongsToUser:budgets,id';
break;
}
return $rules;
}
}

View File

@@ -0,0 +1,82 @@
<?php
/**
* BudgetRequest.php
* Copyright (c) 2018 thegrumpydictator@gmail.com
*
* This file is part of Firefly III.
*
* Firefly III is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Firefly III 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Firefly III. If not, see <http://www.gnu.org/licenses/>.
*/
declare(strict_types=1);
namespace FireflyIII\Api\V1\Requests;
use FireflyIII\Models\Budget;
/**
* Class BudgetRequest
*/
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
{
return [
'name' => $this->string('name'),
'active' => $this->boolean('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' => 'required|boolean',
];
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,81 @@
<?php
/**
* CategoryRequest.php
* Copyright (c) 2018 thegrumpydictator@gmail.com
*
* This file is part of Firefly III.
*
* Firefly III is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Firefly III 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Firefly III. If not, see <http://www.gnu.org/licenses/>.
*/
declare(strict_types=1);
namespace FireflyIII\Api\V1\Requests;
use FireflyIII\Models\Category;
/**
* Class CategoryRequest
*/
class CategoryRequest extends Request
{
/**
* Authorize logged in users.
*
* @return bool
*/
public function authorize(): bool
{
// Only allow authenticated users
return auth()->check();
}
/**
* Get all data from the request.
*
* @return array
*/
public function getAll(): array
{
return [
'name' => $this->string('name'),
'active' => $this->boolean('active'),
];
}
/**
* The rules that the incoming request must be matched against.
*
* @return array
*/
public function rules(): array
{
$rules = [
'name' => 'required|between:1,100|uniqueObjectForUser:categories,name',
'active' => 'required|boolean',
];
switch ($this->method()) {
default:
break;
case 'PUT':
case 'PATCH':
/** @var Category $category */
$category = $this->route()->parameter('category');
$rules['name'] = sprintf('required|between:1,100|uniqueObjectForUser:categories,name,%d', $category->id);
break;
}
return $rules;
}
}

View File

@@ -0,0 +1,89 @@
<?php
/**
* CurrencyRequest.php
* Copyright (c) 2018 thegrumpydictator@gmail.com
*
* This file is part of Firefly III.
*
* Firefly III is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Firefly III 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Firefly III. If not, see <http://www.gnu.org/licenses/>.
*/
declare(strict_types=1);
namespace FireflyIII\Api\V1\Requests;
/**
* Class CurrencyRequest
*/
class CurrencyRequest extends Request
{
/**
* Authorize logged in users.
*
* @return bool
*/
public function authorize(): bool
{
// Only allow authenticated users
return auth()->check();
}
/**
* Get all data from the request.
*
* @return array
*/
public function getAll(): array
{
return [
'name' => $this->string('name'),
'code' => $this->string('code'),
'symbol' => $this->string('symbol'),
'decimal_places' => $this->integer('decimal_places'),
'default' => $this->boolean('default'),
];
}
/**
* The rules that the incoming request must be matched against.
*
* @return array
*/
public function rules(): array
{
$rules = [
'name' => 'required|between:1,255|unique:transaction_currencies,name',
'code' => 'required|between:3,3|unique:transaction_currencies,code',
'symbol' => 'required|between:1,5|unique:transaction_currencies,symbol',
'decimal_places' => 'required|between:0,20|numeric|min:0|max:20',
'default' => 'boolean',
];
switch ($this->method()) {
default:
break;
case 'PUT':
case 'PATCH':
$currency = $this->route()->parameter('currency');
$rules['name'] = 'required|between:1,255|unique:transaction_currencies,name,' . $currency->id;
$rules['code'] = 'required|between:1,255|unique:transaction_currencies,code,' . $currency->id;
$rules['symbol'] = 'required|between:1,255|unique:transaction_currencies,symbol,' . $currency->id;
break;
}
return $rules;
}
}

View File

@@ -0,0 +1,131 @@
<?php
/**
* JournalLinkRequest.php
* Copyright (c) 2018 thegrumpydictator@gmail.com
*
* This file is part of Firefly III.
*
* Firefly III is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Firefly III 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Firefly III. If not, see <http://www.gnu.org/licenses/>.
*/
declare(strict_types=1);
namespace FireflyIII\Api\V1\Requests;
use FireflyIII\Repositories\Journal\JournalRepositoryInterface;
use FireflyIII\Repositories\LinkType\LinkTypeRepositoryInterface;
use Illuminate\Validation\Validator;
/**
*
* Class JournalLinkRequest
*/
class JournalLinkRequest extends Request
{
/**
* Authorize logged in users.
*
* @return bool
*/
public function authorize(): bool
{
// Only allow authenticated users
return auth()->check();
}
/**
* Get all data from the request.
*
* @return array
*/
public function getAll(): array
{
return [
'link_type_id' => $this->integer('link_type_id'),
'link_type_name' => $this->string('link_type_name'),
'inward_id' => $this->integer('inward_id'),
'outward_id' => $this->integer('outward_id'),
'notes' => $this->string('notes'),
];
}
/**
*
* The rules that the incoming request must be matched against.
*
* @return array
*/
public function rules(): array
{
return [
'link_type_id' => 'exists:link_types,id|required_without:link_type_name',
'link_type_name' => 'exists:link_types,name|required_without:link_type_id',
'inward_id' => 'required|belongsToUser:transaction_journals,id',
'outward_id' => 'required|belongsToUser:transaction_journals,id',
'notes' => 'between:0,65000',
];
}
/**
* Configure the validator instance.
*
* @param Validator $validator
*
* @return void
*/
public function withValidator(Validator $validator): void
{
$validator->after(
function (Validator $validator) {
$this->validateExistingLink($validator);
}
);
}
/**
* @param Validator $validator
*/
private function validateExistingLink(Validator $validator): void
{
/** @var LinkTypeRepositoryInterface $repository */
$repository = app(LinkTypeRepositoryInterface::class);
$repository->setUser(auth()->user());
/** @var JournalRepositoryInterface $journalRepos */
$journalRepos = app(JournalRepositoryInterface::class);
$journalRepos->setUser(auth()->user());
$data = $validator->getData();
$inwardId = (int)($data['inward_id'] ?? 0);
$outwardId = (int)($data['outward_id'] ?? 0);
$inward = $journalRepos->findNull($inwardId);
$outward = $journalRepos->findNull($outwardId);
if (null === $inward) {
$validator->errors()->add('inward_id', 'Invalid inward ID.');
return;
}
if (null === $outward) {
$validator->errors()->add('outward_id', 'Invalid outward ID.');
return;
}
if ($repository->findLink($inward, $outward)) {
$validator->errors()->add('outward_id', 'Already have a link between inward and outward.');
$validator->errors()->add('inward_id', 'Already have a link between inward and outward.');
}
}
}

View File

@@ -0,0 +1,91 @@
<?php
/**
* LinkTypeRequest.php
* Copyright (c) 2018 thegrumpydictator@gmail.com
*
* This file is part of Firefly III.
*
* Firefly III is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Firefly III 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Firefly III. If not, see <http://www.gnu.org/licenses/>.
*/
declare(strict_types=1);
namespace FireflyIII\Api\V1\Requests;
use FireflyIII\Models\LinkType;
use Illuminate\Validation\Rule;
/**
*
* Class LinkTypeRequest
*/
class LinkTypeRequest extends Request
{
/**
* Authorize logged in users.
*
* @return bool
*/
public function authorize(): bool
{
// Only allow authenticated users
return auth()->check();
}
/**
* Get all data from the request.
*
* @return array
*/
public function getAll(): array
{
return [
'name' => $this->string('name'),
'outward' => $this->string('outward'),
'inward' => $this->string('inward'),
];
}
/**
* The rules that the incoming request must be matched against.
*
* @return array
*/
public function rules(): array
{
$rules = [
'name' => 'required|unique:link_types,name|min:1',
'outward' => 'required|unique:link_types,outward|min:1|different:inward',
'inward' => 'required|unique:link_types,inward|min:1|different:outward',
];
switch ($this->method()) {
default:
break;
case 'PUT':
case 'PATCH':
/** @var LinkType $linkType */
$linkType = $this->route()->parameter('linkType');
$rules['name'] = ['required', Rule::unique('link_types', 'name')->ignore($linkType->id), 'min:1'];
$rules['outward'] = ['required', 'different:inward', Rule::unique('link_types', 'outward')->ignore($linkType->id), 'min:1'];
$rules['inward'] = ['required', 'different:outward', Rule::unique('link_types', 'inward')->ignore($linkType->id), 'min:1'];
break;
}
return $rules;
}
}

View File

@@ -0,0 +1,99 @@
<?php
/**
* PiggyBankRequest.php
* Copyright (c) 2018 thegrumpydictator@gmail.com
*
* This file is part of Firefly III.
*
* Firefly III is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Firefly III 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Firefly III. If not, see <http://www.gnu.org/licenses/>.
*/
declare(strict_types=1);
namespace FireflyIII\Api\V1\Requests;
use FireflyIII\Models\PiggyBank;
use FireflyIII\Rules\IsAssetAccountId;
/**
*
* Class PiggyBankRequest
*/
class PiggyBankRequest 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
{
$current = $this->string('current_amount');
$current = '' === $current ? '0' : $current;
return [
'name' => $this->string('name'),
'account_id' => $this->integer('account_id'),
'targetamount' => $this->string('target_amount'),
'current_amount' => $current,
'start_date' => $this->date('start_date'),
'target_date' => $this->date('target_date'),
'notes' => $this->string('notes'),
];
}
/**
* The rules that the incoming request must be matched against.
*
* @return array
*/
public function rules(): array
{
$rules = [
'name' => 'required|between:1,255|uniquePiggyBankForUser',
'account_id' => ['required', 'belongsToUser:accounts', new IsAssetAccountId],
'target_amount' => 'required|numeric|more:0',
'current_amount' => 'numeric|more:0|lte:target_amount',
'start_date' => 'date|nullable',
'target_date' => 'date|nullable|after:start_date',
'notes' => 'max:65000',
];
switch ($this->method()) {
default:
break;
case 'PUT':
case 'PATCH':
/** @var PiggyBank $piggyBank */
$piggyBank = $this->route()->parameter('piggyBank');
$rules['name'] = 'required|between:1,255|uniquePiggyBankForUser:' . $piggyBank->id;
break;
}
return $rules;
}
}

View File

@@ -1,7 +1,7 @@
<?php
/**
* ServerPublicKey.php
* Copyright (c) 2017 thegrumpydictator@gmail.com
* PreferenceRequest.php
* Copyright (c) 2018 thegrumpydictator@gmail.com
*
* This file is part of Firefly III.
*
@@ -18,41 +18,52 @@
* You should have received a copy of the GNU General Public License
* along with Firefly III. If not, see <http://www.gnu.org/licenses/>.
*/
declare(strict_types=1);
namespace FireflyIII\Services\Bunq\Object;
namespace FireflyIII\Api\V1\Requests;
/**
* Class ServerPublicKey.
*
* Class PreferenceRequest
*/
class ServerPublicKey extends BunqObject
class PreferenceRequest extends Request
{
/** @var string */
private $publicKey = '';
/**
* ServerPublicKey constructor.
* Authorize logged in users.
*
* @param array $response
* @return bool
*/
public function __construct(array $response)
public function authorize(): bool
{
$this->publicKey = $response['server_public_key'];
// Only allow authenticated users
return auth()->check();
}
/**
* @return string
* Get all data from the request.
*
* @return array
*/
public function getPublicKey(): string
public function getAll(): array
{
return $this->publicKey;
return [
'data' => $this->get('data'),
];
}
/**
* @param string $publicKey
* The rules that the incoming request must be matched against.
*
* @return array
*/
public function setPublicKey(string $publicKey)
public function rules(): array
{
$this->publicKey = $publicKey;
return [
'data' => 'required|between:1,65000',
];
}
}

View File

@@ -0,0 +1,203 @@
<?php
/**
* RecurrenceRequest.php
* Copyright (c) 2018 thegrumpydictator@gmail.com
*
* This file is part of Firefly III.
*
* Firefly III is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Firefly III 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Firefly III. If not, see <http://www.gnu.org/licenses/>.
*/
declare(strict_types=1);
namespace FireflyIII\Api\V1\Requests;
use Carbon\Carbon;
use FireflyIII\Rules\BelongsUser;
use FireflyIII\Validation\RecurrenceValidation;
use FireflyIII\Validation\TransactionValidation;
use Illuminate\Validation\Validator;
/**
* Class RecurrenceRequest
*/
class RecurrenceRequest extends Request
{
use RecurrenceValidation, TransactionValidation;
/**
* Authorize logged in users.
*
* @return bool
*/
public function authorize(): bool
{
// Only allow authenticated users
return auth()->check();
}
/**
* Get all data from the request.
*
* @return array
*/
public function getAll(): array
{
$return = [
'recurrence' => [
'type' => $this->string('type'),
'title' => $this->string('title'),
'description' => $this->string('description'),
'first_date' => $this->date('first_date'),
'repeat_until' => $this->date('repeat_until'),
'repetitions' => $this->integer('nr_of_repetitions'),
'apply_rules' => $this->boolean('apply_rules'),
'active' => $this->boolean('active'),
],
'meta' => [
'piggy_bank_id' => $this->integer('piggy_bank_id'),
'piggy_bank_name' => $this->string('piggy_bank_name'),
'tags' => explode(',', $this->string('tags')),
],
'transactions' => $this->getTransactionData(),
'repetitions' => $this->getRepetitionData(),
];
return $return;
}
/**
* The rules that the incoming request must be matched against.
*
* @return array
*/
public function rules(): array
{
$today = Carbon::now()->addDay();
return [
'type' => 'required|in:withdrawal,transfer,deposit',
'title' => 'required|between:1,255|uniqueObjectForUser:recurrences,title',
'description' => 'between:1,65000',
'first_date' => sprintf('required|date|after:%s', $today->format('Y-m-d')),
'repeat_until' => sprintf('date|after:%s', $today->format('Y-m-d')),
'nr_of_repetitions' => 'numeric|between:1,31',
'apply_rules' => 'required|boolean',
'active' => 'required|boolean',
'tags' => 'between:1,64000',
'piggy_bank_id' => 'numeric',
'repetitions.*.type' => 'required|in:daily,weekly,ndom,monthly,yearly',
'repetitions.*.moment' => 'between:0,10',
'repetitions.*.skip' => 'required|numeric|between:0,31',
'repetitions.*.weekend' => 'required|numeric|min:1|max:4',
'transactions.*.currency_id' => 'numeric|exists:transaction_currencies,id|required_without:transactions.*.currency_code',
'transactions.*.currency_code' => 'min:3|max:3|exists:transaction_currencies,code|required_without:transactions.*.currency_id',
'transactions.*.foreign_amount' => 'numeric|more:0',
'transactions.*.foreign_currency_id' => 'numeric|exists:transaction_currencies,id',
'transactions.*.foreign_currency_code' => 'min:3|max:3|exists:transaction_currencies,code',
'transactions.*.budget_id' => ['mustExist:budgets,id', new BelongsUser],
'transactions.*.category_name' => 'between:1,255|nullable',
'transactions.*.source_id' => ['numeric', 'nullable', new BelongsUser],
'transactions.*.source_name' => 'between:1,255|nullable',
'transactions.*.destination_id' => ['numeric', 'nullable', new BelongsUser],
'transactions.*.destination_name' => 'between:1,255|nullable',
'transactions.*.amount' => 'required|numeric|more:0',
'transactions.*.description' => 'required|between:1,255',
];
}
/**
* Configure the validator instance.
*
* @param Validator $validator
*
* @return void
*/
public function withValidator(Validator $validator): void
{
$validator->after(
function (Validator $validator) {
$this->validateOneTransaction($validator);
$this->validateOneRepetition($validator);
$this->validateRecurrenceRepetition($validator);
$this->validateRepetitionMoment($validator);
$this->validateForeignCurrencyInformation($validator);
$this->validateAccountInformation($validator);
}
);
}
/**
* Returns the repetition data as it is found in the submitted data.
*
* @return array
*/
private function getRepetitionData(): array
{
$return = [];
// repetition data:
/** @var array $repetitions */
$repetitions = $this->get('repetitions');
/** @var array $repetition */
foreach ($repetitions as $repetition) {
$return[] = [
'type' => $repetition['type'],
'moment' => $repetition['moment'],
'skip' => (int)$repetition['skip'],
'weekend' => (int)$repetition['weekend'],
];
}
return $return;
}
/**
* Returns the transaction data as it is found in the submitted data. It's a complex method according to code
* standards but it just has a lot of ??-statements because of the fields that may or may not exist.
*
* @return array
* @SuppressWarnings(PHPMD.NPathComplexity)
* @SuppressWarnings(PHPMD.CyclomaticComplexity)
*/
private function getTransactionData(): array
{
$return = [];
// transaction data:
/** @var array $transactions */
$transactions = $this->get('transactions');
/** @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,
'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,
'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'],
];
}
return $return;
}
}

View File

@@ -1,4 +1,5 @@
<?php
/**
* Request.php
* Copyright (c) 2018 thegrumpydictator@gmail.com
@@ -18,13 +19,19 @@
* You should have received a copy of the GNU General Public License
* along with Firefly III. If not, see <http://www.gnu.org/licenses/>.
*/
declare(strict_types=1);
namespace FireflyIII\Api\V1\Requests;
use FireflyIII\Http\Requests\Request as FireflyIIIRequest;
/**
* Class Request.
*
* Technically speaking this class does not have to be extended like this but who knows what the future brings.
*
* @SuppressWarnings(PHPMD.NumberOfChildren)
*/
class Request extends FireflyIIIRequest
{

View File

@@ -0,0 +1,85 @@
<?php
/**
* RuleGroupRequest.php
* Copyright (c) 2018 thegrumpydictator@gmail.com
*
* This file is part of Firefly III.
*
* Firefly III is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Firefly III 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Firefly III. If not, see <http://www.gnu.org/licenses/>.
*/
declare(strict_types=1);
namespace FireflyIII\Api\V1\Requests;
use FireflyIII\Models\RuleGroup;
/**
*
* Class RuleGroupRequest
*/
class RuleGroupRequest extends Request
{
/**
* Authorize logged in users.
*
* @return bool
*/
public function authorize(): bool
{
// Only allow authenticated users
return auth()->check();
}
/**
* Get all data from the request.
*
* @return array
*/
public function getAll(): array
{
return [
'title' => $this->string('title'),
'description' => $this->string('description'),
'active' => $this->boolean('active'),
];
}
/**
* The rules that the incoming request must be matched against.
*
* @return array
*/
public function rules(): array
{
$rules = [
'title' => 'required|between:1,100|uniqueObjectForUser:rule_groups,title',
'description' => 'between:1,5000|nullable',
'active' => 'required|boolean',
];
switch ($this->method()) {
default:
break;
case 'PUT':
case 'PATCH':
/** @var RuleGroup $ruleGroup */
$ruleGroup = $this->route()->parameter('ruleGroup');
$rules['title'] = 'required|between:1,100|uniqueObjectForUser:rule_groups,title,' . $ruleGroup->id;
break;
}
return $rules;
}
}

View File

@@ -0,0 +1,187 @@
<?php
/**
* RuleRequest.php
* Copyright (c) 2018 thegrumpydictator@gmail.com
*
* This file is part of Firefly III.
*
* Firefly III is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Firefly III 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Firefly III. If not, see <http://www.gnu.org/licenses/>.
*/
declare(strict_types=1);
namespace FireflyIII\Api\V1\Requests;
use Illuminate\Validation\Validator;
/**
* Class RuleRequest
*/
class RuleRequest 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
{
$data = [
'title' => $this->string('title'),
'description' => $this->string('description'),
'rule_group_id' => $this->integer('rule_group_id'),
'rule_group_title' => $this->string('rule_group_title'),
'trigger' => $this->string('trigger'),
'strict' => $this->boolean('strict'),
'stop_processing' => $this->boolean('stop_processing'),
'active' => $this->boolean('active'),
'rule_triggers' => $this->getRuleTriggers(),
'rule_actions' => $this->getRuleActions(),
];
return $data;
}
/**
* The rules that the incoming request must be matched against.
*
* @return array
*/
public function rules(): array
{
$validTriggers = array_keys(config('firefly.rule-triggers'));
$validActions = array_keys(config('firefly.rule-actions'));
// some actions require text:
$contextActions = implode(',', config('firefly.rule-actions-text'));
$rules = [
'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',
'rule_group_title' => 'nullable|between:1,255|required_without:rule_group_id|belongsToUser:rule_groups,title',
'trigger' => 'required|in:store-journal,update-journal',
'rule_triggers.*.name' => 'required|in:' . implode(',', $validTriggers),
'rule_triggers.*.stop_processing' => 'boolean',
'rule_triggers.*.value' => 'required|min:1|ruleTriggerValue',
'rule_actions.*.name' => 'required|in:' . implode(',', $validActions),
'rule_actions.*.value' => 'required_if:rule_actions.*.type,' . $contextActions . '|ruleActionValue',
'rule_actions.*.stop_processing' => 'boolean',
'strict' => 'required|boolean',
'stop_processing' => 'required|boolean',
'active' => 'required|boolean',
];
return $rules;
}
/**
* Configure the validator instance.
*
* @param Validator $validator
*
* @return void
*/
public function withValidator(Validator $validator): void
{
$validator->after(
function (Validator $validator) {
$this->atLeastOneTrigger($validator);
$this->atLeastOneAction($validator);
}
);
}
/**
* Adds an error to the validator when there are no repetitions in the array of data.
*
* @param Validator $validator
*/
protected function atLeastOneAction(Validator $validator): void
{
$data = $validator->getData();
$repetitions = $data['rule_actions'] ?? [];
// need at least one transaction
if (0 === \count($repetitions)) {
$validator->errors()->add('title', (string)trans('validation.at_least_one_action'));
}
}
/**
* Adds an error to the validator when there are no repetitions in the array of data.
*
* @param Validator $validator
*/
protected function atLeastOneTrigger(Validator $validator): void
{
$data = $validator->getData();
$repetitions = $data['rule_triggers'] ?? [];
// need at least one transaction
if (0 === \count($repetitions)) {
$validator->errors()->add('title', (string)trans('validation.at_least_one_trigger'));
}
}
/**
* @return array
*/
private function getRuleActions(): array
{
$actions = $this->get('rule_actions');
$return = [];
if (\is_array($actions)) {
foreach ($actions as $action) {
$return[] = [
'name' => $action['name'],
'value' => $action['value'],
'stop_processing' => 1 === (int)($action['stop-processing'] ?? '0'),
];
}
}
return $return;
}
/**
* @return array
*/
private function getRuleTriggers(): array
{
$triggers = $this->get('rule_triggers');
$return = [];
if (\is_array($triggers)) {
foreach ($triggers as $trigger) {
$return[] = [
'name' => $trigger['name'],
'value' => $trigger['value'],
'stop_processing' => 1 === (int)($trigger['stop-processing'] ?? '0'),
];
}
}
return $return;
}
}

View File

@@ -1,4 +1,5 @@
<?php
/**
* TransactionRequest.php
* Copyright (c) 2018 thegrumpydictator@gmail.com
@@ -23,12 +24,8 @@ declare(strict_types=1);
namespace FireflyIII\Api\V1\Requests;
use FireflyIII\Exceptions\FireflyException;
use FireflyIII\Models\Account;
use FireflyIII\Models\AccountType;
use FireflyIII\Models\Transaction;
use FireflyIII\Repositories\Account\AccountRepositoryInterface;
use FireflyIII\Rules\BelongsUser;
use FireflyIII\Validation\TransactionValidation;
use Illuminate\Validation\Validator;
@@ -37,7 +34,11 @@ use Illuminate\Validation\Validator;
*/
class TransactionRequest extends Request
{
use TransactionValidation;
/**
* Authorize logged in users.
*
* @return bool
*/
public function authorize(): bool
@@ -47,12 +48,15 @@ class TransactionRequest extends Request
}
/**
* Get all data. Is pretty complex because of all the ??-statements.
*
* @SuppressWarnings(PHPMD.CyclomaticComplexity)
* @SuppressWarnings(PHPMD.NPathComplexity)
* @return array
*/
public function getAll(): array
{
$data = [
// basic fields for journal:
'type' => $this->string('type'),
'date' => $this->date('date'),
'description' => $this->string('description'),
@@ -61,8 +65,6 @@ class TransactionRequest extends Request
'bill_id' => $this->integer('bill_id'),
'bill_name' => $this->string('bill_name'),
'tags' => explode(',', $this->string('tags')),
// then, custom fields for journal
'interest_date' => $this->date('interest_date'),
'book_date' => $this->date('book_date'),
'process_date' => $this->date('process_date'),
@@ -71,39 +73,18 @@ class TransactionRequest extends Request
'invoice_date' => $this->date('invoice_date'),
'internal_reference' => $this->string('internal_reference'),
'notes' => $this->string('notes'),
// then, transactions (see below).
'transactions' => [],
'original-source' => sprintf('api-v%s', config('firefly.api_version')),
'transactions' => $this->getTransactionData(),
];
foreach ($this->get('transactions') as $index => $transaction) {
$array = [
'description' => $transaction['description'] ?? null,
'amount' => $transaction['amount'],
'currency_id' => isset($transaction['currency_id']) ? intval($transaction['currency_id']) : null,
'currency_code' => isset($transaction['currency_code']) ? $transaction['currency_code'] : null,
'foreign_amount' => $transaction['foreign_amount'] ?? null,
'foreign_currency_id' => isset($transaction['foreign_currency_id']) ? intval($transaction['foreign_currency_id']) : null,
'foreign_currency_code' => $transaction['foreign_currency_code'] ?? null,
'budget_id' => isset($transaction['budget_id']) ? intval($transaction['budget_id']) : null,
'budget_name' => $transaction['budget_name'] ?? null,
'category_id' => isset($transaction['category_id']) ? intval($transaction['category_id']) : null,
'category_name' => $transaction['category_name'] ?? null,
'source_id' => isset($transaction['source_id']) ? intval($transaction['source_id']) : null,
'source_name' => isset($transaction['source_name']) ? strval($transaction['source_name']) : null,
'destination_id' => isset($transaction['destination_id']) ? intval($transaction['destination_id']) : null,
'destination_name' => isset($transaction['destination_name']) ? strval($transaction['destination_name']) : null,
'reconciled' => $transaction['reconciled'] ?? false,
'identifier' => $index,
];
$data['transactions'][] = $array;
}
return $data;
}
/**
* The rules that the incoming request must be matched against.
*
* @return array
* @SuppressWarnings(PHPMD.ExcessiveMethodLength)
*/
public function rules(): array
{
@@ -148,13 +129,8 @@ class TransactionRequest extends Request
'transactions.*.destination_name' => 'between:1,255|nullable',
];
switch ($this->method()) {
default:
break;
case 'PUT':
case 'PATCH':
unset($rules['type'], $rules['piggy_bank_id'], $rules['piggy_bank_name']);
break;
if ('PUT' === $this->method()) {
unset($rules['type'], $rules['piggy_bank_id'], $rules['piggy_bank_name']);
}
return $rules;
@@ -173,11 +149,11 @@ class TransactionRequest extends Request
{
$validator->after(
function (Validator $validator) {
$this->atLeastOneTransaction($validator);
$this->checkValidDescriptions($validator);
$this->equalToJournalDescription($validator);
$this->emptySplitDescriptions($validator);
$this->foreignCurrencyInformation($validator);
$this->validateOneTransaction($validator);
$this->validateDescriptions($validator);
$this->validateJournalDescription($validator);
$this->validateSplitDescriptions($validator);
$this->validateForeignCurrencyInformation($validator);
$this->validateAccountInformation($validator);
$this->validateSplitAccounts($validator);
}
@@ -185,316 +161,37 @@ class TransactionRequest extends Request
}
/**
* Throws an error when this asset account is invalid.
* Get transaction data.
*
* @param Validator $validator
* @param int|null $accountId
* @param null|string $accountName
* @param string $idField
* @param string $nameField
* @SuppressWarnings(PHPMD.CyclomaticComplexity)
* @SuppressWarnings(PHPMD.NPathComplexity)
* @return array
*/
protected function assetAccountExists(Validator $validator, ?int $accountId, ?string $accountName, string $idField, string $nameField): void
private function getTransactionData(): array
{
$accountId = intval($accountId);
$accountName = strval($accountName);
// both empty? hard exit.
if ($accountId < 1 && strlen($accountName) === 0) {
$validator->errors()->add($idField, trans('validation.filled', ['attribute' => $idField]));
return;
}
// ID belongs to user and is asset account:
/** @var AccountRepositoryInterface $repository */
$repository = app(AccountRepositoryInterface::class);
$repository->setUser(auth()->user());
$set = $repository->getAccountsById([$accountId]);
if ($set->count() === 1) {
/** @var Account $first */
$first = $set->first();
if ($first->accountType->type !== AccountType::ASSET) {
$validator->errors()->add($idField, trans('validation.belongs_user'));
return;
}
// we ignore the account name at this point.
return;
$return = [];
foreach ($this->get('transactions') as $index => $transaction) {
$return[] = [
'description' => $transaction['description'] ?? null,
'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,
'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,
'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,
'reconciled' => $transaction['reconciled'] ?? false,
'identifier' => $index,
];
}
$account = $repository->findByName($accountName, [AccountType::ASSET]);
if (is_null($account)) {
$validator->errors()->add($nameField, trans('validation.belongs_user'));
}
return;
return $return;
}
/**
* Adds an error to the validator when there are no transactions in the array of data.
*
* @param Validator $validator
*/
protected function atLeastOneTransaction(Validator $validator): void
{
$data = $validator->getData();
$transactions = $data['transactions'] ?? [];
// need at least one transaction
if (count($transactions) === 0) {
$validator->errors()->add('description', trans('validation.at_least_one_transaction'));
}
}
/**
* Adds an error to the "description" field when the user has submitted no descriptions and no
* journal description.
*
* @param Validator $validator
*/
protected function checkValidDescriptions(Validator $validator)
{
$data = $validator->getData();
$transactions = $data['transactions'] ?? [];
$journalDescription = strval($data['description'] ?? '');
$validDescriptions = 0;
foreach ($transactions as $index => $transaction) {
if (strlen(strval($transaction['description'] ?? '')) > 0) {
$validDescriptions++;
}
}
// no valid descriptions and empty journal description? error.
if ($validDescriptions === 0 && strlen($journalDescription) === 0) {
$validator->errors()->add('description', trans('validation.filled', ['attribute' => trans('validation.attributes.description')]));
}
}
/**
* Adds an error to the validator when the user submits a split transaction (more than 1 transactions)
* but does not give them a description.
*
* @param Validator $validator
*/
protected function emptySplitDescriptions(Validator $validator): void
{
$data = $validator->getData();
$transactions = $data['transactions'] ?? [];
foreach ($transactions as $index => $transaction) {
$description = strval($transaction['description'] ?? '');
// filled description is mandatory for split transactions.
if (count($transactions) > 1 && strlen($description) === 0) {
$validator->errors()->add(
'transactions.' . $index . '.description',
trans('validation.filled', ['attribute' => trans('validation.attributes.transaction_description')])
);
}
}
}
/**
* Adds an error to the validator when any transaction descriptions are equal to the journal description.
*
* @param Validator $validator
*/
protected function equalToJournalDescription(Validator $validator): void
{
$data = $validator->getData();
$transactions = $data['transactions'] ?? [];
$journalDescription = strval($data['description'] ?? '');
foreach ($transactions as $index => $transaction) {
$description = strval($transaction['description'] ?? '');
// description cannot be equal to journal description.
if ($description === $journalDescription) {
$validator->errors()->add('transactions.' . $index . '.description', trans('validation.equal_description'));
}
}
}
/**
* If the transactions contain foreign amounts, there must also be foreign currency information.
*
* @param Validator $validator
*/
protected function foreignCurrencyInformation(Validator $validator): void
{
$data = $validator->getData();
$transactions = $data['transactions'] ?? [];
foreach ($transactions as $index => $transaction) {
// must have currency info.
if (isset($transaction['foreign_amount'])
&& !(isset($transaction['foreign_currency_id'])
|| isset($transaction['foreign_currency_code']))) {
$validator->errors()->add(
'transactions.' . $index . '.foreign_amount',
trans('validation.require_currency_info')
);
}
}
}
/**
* Throws an error when the given opposing account (of type $type) is invalid.
* Empty data is allowed, system will default to cash.
*
* @param Validator $validator
* @param string $type
* @param int|null $accountId
* @param null|string $accountName
* @param string $idField
*/
protected function opposingAccountExists(Validator $validator, string $type, ?int $accountId, ?string $accountName, string $idField): void {
$accountId = intval($accountId);
$accountName = strval($accountName);
// both empty? done!
if ($accountId < 1 && strlen($accountName) === 0) {
return;
}
if ($accountId !== 0) {
// ID belongs to user and is $type account:
/** @var AccountRepositoryInterface $repository */
$repository = app(AccountRepositoryInterface::class);
$repository->setUser(auth()->user());
$set = $repository->getAccountsById([$accountId]);
if ($set->count() === 1) {
/** @var Account $first */
$first = $set->first();
if ($first->accountType->type !== $type) {
$validator->errors()->add($idField, trans('validation.belongs_user'));
return;
}
// we ignore the account name at this point.
return;
}
}
// not having an opposing account by this name is NOT a problem.
return;
}
/**
* Validates the given account information. Switches on given transaction type.
*
* @param Validator $validator
*
* @throws FireflyException
*/
protected function validateAccountInformation(Validator $validator): void
{
$data = $validator->getData();
$transactions = $data['transactions'] ?? [];
if (!isset($data['type'])) {
// the journal may exist in the request:
/** @var Transaction $transaction */
$transaction = $this->route()->parameter('transaction');
if (is_null($transaction)) {
return; // @codeCoverageIgnore
}
$data['type'] = strtolower($transaction->transactionJournal->transactionType->type);
}
foreach ($transactions as $index => $transaction) {
$sourceId = isset($transaction['source_id']) ? intval($transaction['source_id']) : null;
$sourceName = $transaction['source_name'] ?? null;
$destinationId = isset($transaction['destination_id']) ? intval($transaction['destination_id']) : null;
$destinationName = $transaction['destination_name'] ?? null;
switch ($data['type']) {
case 'withdrawal':
$idField = 'transactions.' . $index . '.source_id';
$nameField = 'transactions.' . $index . '.source_name';
$this->assetAccountExists($validator, $sourceId, $sourceName, $idField, $nameField);
$idField = 'transactions.' . $index . '.destination_id';
$this->opposingAccountExists($validator, AccountType::EXPENSE, $destinationId, $destinationName, $idField);
break;
case 'deposit':
$idField = 'transactions.' . $index . '.source_id';
$this->opposingAccountExists($validator, AccountType::REVENUE, $sourceId, $sourceName, $idField);
$idField = 'transactions.' . $index . '.destination_id';
$nameField = 'transactions.' . $index . '.destination_name';
$this->assetAccountExists($validator, $destinationId, $destinationName, $idField, $nameField);
break;
case 'transfer':
$idField = 'transactions.' . $index . '.source_id';
$nameField = 'transactions.' . $index . '.source_name';
$this->assetAccountExists($validator, $sourceId, $sourceName, $idField, $nameField);
$idField = 'transactions.' . $index . '.destination_id';
$nameField = 'transactions.' . $index . '.destination_name';
$this->assetAccountExists($validator, $destinationId, $destinationName, $idField, $nameField);
break;
default:
throw new FireflyException(sprintf('The validator cannot handle transaction type "%s" in validateAccountInformation().', $data['type']));
}
}
}
/**
* @param Validator $validator
*
* @throws FireflyException
*/
protected function validateSplitAccounts(Validator $validator)
{
$data = $validator->getData();
$count = isset($data['transactions']) ? count($data['transactions']) : 0;
if ($count < 2) {
return;
}
// this is pretty much impossible:
// @codeCoverageIgnoreStart
if (!isset($data['type'])) {
// the journal may exist in the request:
/** @var Transaction $transaction */
$transaction = $this->route()->parameter('transaction');
if (is_null($transaction)) {
return;
}
$data['type'] = strtolower($transaction->transactionJournal->transactionType->type);
}
// @codeCoverageIgnoreEnd
// collect all source ID's and destination ID's, if present:
$sources = [];
$destinations = [];
foreach ($data['transactions'] as $transaction) {
$sources[] = isset($transaction['source_id']) ? intval($transaction['source_id']) : 0;
$destinations[] = isset($transaction['destination_id']) ? intval($transaction['destination_id']) : 0;
}
$destinations = array_unique($destinations);
$sources = array_unique($sources);
// switch on type:
switch ($data['type']) {
case 'withdrawal':
if (count($sources) > 1) {
$validator->errors()->add('transactions.0.source_id', trans('validation.all_accounts_equal'));
}
break;
case 'deposit':
if (count($destinations) > 1) {
$validator->errors()->add('transactions.0.destination_id', trans('validation.all_accounts_equal'));
}
break;
case 'transfer':
if (count($sources) > 1 || count($destinations) > 1) {
$validator->errors()->add('transactions.0.source_id', trans('validation.all_accounts_equal'));
$validator->errors()->add('transactions.0.destination_id', trans('validation.all_accounts_equal'));
}
break;
default:
// @codeCoverageIgnoreStart
throw new FireflyException(
sprintf('The validator cannot handle transaction type "%s" in validateSplitAccounts().', $data['type'])
);
// @codeCoverageIgnoreEnd
}
return;
}
}

View File

@@ -1,4 +1,5 @@
<?php
/**
* UserRequest.php
* Copyright (c) 2018 thegrumpydictator@gmail.com
@@ -23,6 +24,7 @@ declare(strict_types=1);
namespace FireflyIII\Api\V1\Requests;
use FireflyIII\Repositories\User\UserRepositoryInterface;
use FireflyIII\User;
@@ -32,24 +34,32 @@ use FireflyIII\User;
class UserRequest extends Request
{
/**
* Authorize logged in users.
*
* @return bool
*/
public function authorize(): bool
{
$result = false;
// Only allow authenticated users
if (!auth()->check()) {
return false; // @codeCoverageIgnore
}
/** @var User $user */
$user = auth()->user();
if (!$user->hasRole('owner')) {
return false; // @codeCoverageIgnore
if (auth()->check()) {
/** @var User $user */
$user = auth()->user();
/** @var UserRepositoryInterface $repository */
$repository = app(UserRepositoryInterface::class);
if ($repository->hasRole($user, 'owner')) {
$result = true; // @codeCoverageIgnore
}
}
return true;
return $result;
}
/**
* Get all data from the request.
*
* @return array
*/
public function getAll(): array
@@ -64,6 +74,8 @@ class UserRequest extends Request
}
/**
* The rules that the incoming request must be matched against.
*
* @return array
*/
public function rules(): array

View File

@@ -1,7 +1,7 @@
<?php
/**
* CreateExport.php
* Copyright (c) 2017 thegrumpydictator@gmail.com
* Copyright (c) 2018 thegrumpydictator@gmail.com
*
* This file is part of Firefly III.
*
@@ -18,6 +18,9 @@
* You should have received a copy of the GNU General Public License
* along with Firefly III. If not, see <http://www.gnu.org/licenses/>.
*/
/** @noinspection MultipleReturnStatementsInspection */
declare(strict_types=1);
namespace FireflyIII\Console\Commands;
@@ -36,10 +39,13 @@ use Storage;
* Class CreateExport.
*
* Generates export from the command line.
*
* @codeCoverageIgnore
*/
class CreateExport extends Command
{
use VerifiesAccessToken;
/**
* The console command description.
*
@@ -60,27 +66,18 @@ class CreateExport extends Command
{--with_uploads : Include user\'s uploads?}';
/**
* Create a new command instance.
*/
public function __construct()
{
parent::__construct();
}
/**
* @SuppressWarnings(PHPMD.CyclomaticComplexity) // it's five its fine.
* @SuppressWarnings(PHPMD.ExcessiveMethodLength)
*
* Execute the console command.
*
* @return mixed
* @return int
* @SuppressWarnings(PHPMD.CyclomaticComplexity)
* @SuppressWarnings(PHPMD.ExcessiveMethodLength)
*/
public function handle()
public function handle(): int
{
if (!$this->verifyAccessToken()) {
$this->error('Invalid access token.');
return;
return 1;
}
$this->line('Full export is running...');
// make repositories
@@ -94,15 +91,18 @@ class CreateExport extends Command
$journalRepository = app(JournalRepositoryInterface::class);
// set user
$user = $userRepository->find(intval($this->option('user')));
$user = $userRepository->findNull((int)$this->option('user'));
if (null === $user) {
return 1;
}
$jobRepository->setUser($user);
$journalRepository->setUser($user);
$accountRepository->setUser($user);
// first date
$firstJournal = $journalRepository->first();
$firstJournal = $journalRepository->firstNull();
$first = new Carbon;
if (null !== $firstJournal->id) {
if (null !== $firstJournal) {
$first = $firstJournal->date;
}
@@ -141,6 +141,6 @@ class CreateExport extends Command
$this->line('The export has finished! You can find the ZIP file in this location:');
$this->line(storage_path(sprintf('export/%s', $fileName)));
return;
return 0;
}
}

View File

@@ -1,7 +1,7 @@
<?php
/**
* CreateImport.php
* Copyright (c) 2017 thegrumpydictator@gmail.com
* Copyright (c) 2018 thegrumpydictator@gmail.com
*
* This file is part of Firefly III.
*
@@ -18,24 +18,27 @@
* You should have received a copy of the GNU General Public License
* along with Firefly III. If not, see <http://www.gnu.org/licenses/>.
*/
/** @noinspection MultipleReturnStatementsInspection */
declare(strict_types=1);
namespace FireflyIII\Console\Commands;
use Artisan;
use Exception;
use FireflyIII\Exceptions\FireflyException;
use FireflyIII\Import\Logging\CommandHandler;
use FireflyIII\Import\Prerequisites\PrerequisitesInterface;
use FireflyIII\Import\Routine\RoutineInterface;
use FireflyIII\Import\Storage\ImportArrayStorage;
use FireflyIII\Repositories\ImportJob\ImportJobRepositoryInterface;
use FireflyIII\Repositories\User\UserRepositoryInterface;
use Illuminate\Console\Command;
use Illuminate\Support\MessageBag;
use Log;
use Monolog\Formatter\LineFormatter;
use Preferences;
/**
* Class CreateImport.
*
* @codeCoverageIgnore
*/
class CreateImport extends Command
{
@@ -54,150 +57,244 @@ class CreateImport extends Command
*/
protected $signature
= 'firefly:create-import
{file : The file to import.}
{configuration : The configuration file to use for the import.}
{file? : The file to import.}
{configuration? : The configuration file to use for the import.}
{--type=csv : The file type of the import.}
{--user= : The user ID that the import should import for.}
{--provider=file : The file type of the import.}
{--user=1 : The user ID that the import should import for.}
{--token= : The user\'s access token.}
{--start : Starts the job immediately.}';
/**
* Create a new command instance.
*/
public function __construct()
{
parent::__construct();
}
/**
* Run the command.
*
* @SuppressWarnings(PHPMD.ExcessiveMethodLength) // cannot be helped
* @SuppressWarnings(PHPMD.CyclomaticComplexity) // it's five exactly.
*
* @throws FireflyException
*/
public function handle()
public function handle(): int
{
if (!$this->verifyAccessToken()) {
$this->error('Invalid access token.');
$this->errorLine('Invalid access token.');
return;
return 1;
}
/** @var UserRepositoryInterface $userRepository */
$userRepository = app(UserRepositoryInterface::class);
$file = $this->argument('file');
$configuration = $this->argument('configuration');
$user = $userRepository->find(intval($this->option('user')));
$cwd = getcwd();
$type = strtolower($this->option('type'));
$userRepository = app(UserRepositoryInterface::class);
$file = (string)$this->argument('file');
$configuration = (string)$this->argument('configuration');
$user = $userRepository->findNull((int)$this->option('user'));
$cwd = getcwd();
$provider = strtolower((string)$this->option('provider'));
$configurationData = [];
if (null === $user) {
$this->errorLine('User is NULL.');
return 1;
}
if (!$this->validArguments()) {
return;
$this->errorLine('Invalid arguments.');
return 1;
}
if (\strlen($configuration) > 0) {
$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 1;
}
}
$configurationData = json_decode(file_get_contents($configuration), true);
if (null === $configurationData) {
$this->error(sprintf('Firefly III cannot read the contents of configuration file "%s" (working directory: "%s").', $configuration, $cwd));
return;
}
$this->line(sprintf('Going to create a job to import file: %s', $file));
$this->line(sprintf('Using configuration file: %s', $configuration));
$this->line(sprintf('Import into user: #%d (%s)', $user->id, $user->email));
$this->line(sprintf('Type of import: %s', $type));
$this->infoLine(sprintf('Going to create a job to import file: %s', $file));
$this->infoLine(sprintf('Using configuration file: %s', $configuration));
$this->infoLine(sprintf('Import into user: #%d (%s)', $user->id, $user->email));
$this->infoLine(sprintf('Type of import: %s', $provider));
/** @var ImportJobRepositoryInterface $jobRepository */
$jobRepository = app(ImportJobRepositoryInterface::class);
$jobRepository->setUser($user);
$job = $jobRepository->create($type);
$this->line(sprintf('Created job "%s"', $job->key));
$importJob = $jobRepository->create($provider);
$this->infoLine(sprintf('Created job "%s"', $importJob->key));
Artisan::call('firefly:encrypt-file', ['file' => $file, 'key' => $job->key]);
$this->line('Stored import data...');
$jobRepository->setConfiguration($job, $configurationData);
$jobRepository->updateStatus($job, 'configured');
$this->line('Stored configuration...');
if (true === $this->option('start')) {
$this->line('The import will start in a moment. This process is not visible...');
Log::debug('Go for import!');
// normally would refer to other firefly:start-import but that doesn't seem to work all to well...
$monolog = Log::getMonolog();
$handler = new CommandHandler($this);
$formatter = new LineFormatter(null, null, false, true);
$handler->setFormatter($formatter);
$monolog->pushHandler($handler);
// start the actual routine:
$type = 'csv' === $job->file_type ? 'file' : $job->file_type;
$key = sprintf('import.routine.%s', $type);
$className = config($key);
if (null === $className || !class_exists($className)) {
throw new FireflyException(sprintf('Cannot find import routine class for job of type "%s".', $type)); // @codeCoverageIgnore
// make sure that job has no prerequisites.
if ((bool)config(sprintf('import.has_prereq.%s', $provider))) {
// make prerequisites thing.
$class = (string)config(sprintf('import.prerequisites.%s', $provider));
if (!class_exists($class)) {
throw new FireflyException(sprintf('No class to handle prerequisites for "%s".', $provider)); // @codeCoverageIgnore
}
/** @var RoutineInterface $routine */
$routine = app($className);
$routine->setJob($job);
$routine->run();
/** @var PrerequisitesInterface $object */
$object = app($class);
$object->setUser($user);
if (!$object->isComplete()) {
$this->errorLine(sprintf('Import provider "%s" has prerequisites that can only be filled in using the browser.', $provider));
// give feedback.
/** @var MessageBag $error */
foreach ($routine->getErrors() as $index => $error) {
$this->error(sprintf('Error importing line #%d: %s', $index, $error));
return 1;
}
$this->line(
sprintf(
'The import has finished. %d transactions have been imported out of %d records.', $routine->getJournals()->count(), $routine->getLines()
)
);
}
// clear cache for user:
Preferences::setForUser($user, 'lastActivity', microtime());
// store file as attachment.
if (\strlen($file) > 0) {
$messages = $jobRepository->storeCLIUpload($importJob, 'import_file', $file);
if ($messages->count() > 0) {
$this->errorLine($messages->first());
return;
return 1;
}
$this->infoLine('File content saved.');
}
$this->infoLine('Job configuration saved.');
$jobRepository->setConfiguration($importJob, $configurationData);
$jobRepository->setStatus($importJob, 'ready_to_run');
if (true === $this->option('start')) {
$this->infoLine('The import routine has started. The process is not visible. Please wait.');
Log::debug('Go for import!');
// run it!
$key = sprintf('import.routine.%s', $provider);
$className = config($key);
if (null === $className || !class_exists($className)) {
// @codeCoverageIgnoreStart
$this->errorLine(sprintf('No routine for provider "%s"', $provider));
return 1;
// @codeCoverageIgnoreEnd
}
// keep repeating this call until job lands on "provider_finished"
$valid = ['provider_finished'];
$count = 0;
while (!\in_array($importJob->status, $valid, true) && $count < 6) {
Log::debug(sprintf('Now in loop #%d.', $count + 1));
/** @var RoutineInterface $routine */
$routine = app($className);
$routine->setImportJob($importJob);
try {
$routine->run();
} catch (FireflyException|Exception $e) {
$message = 'The import routine crashed: ' . $e->getMessage();
Log::error($message);
Log::error($e->getTraceAsString());
// set job errored out:
$jobRepository->setStatus($importJob, 'error');
$this->errorLine($message);
return 1;
}
$count++;
}
if ('provider_finished' === $importJob->status) {
$this->infoLine('Import has finished. Please wait for storage of data.');
// set job to be storing data:
$jobRepository->setStatus($importJob, 'storing_data');
/** @var ImportArrayStorage $storage */
$storage = app(ImportArrayStorage::class);
$storage->setImportJob($importJob);
try {
$storage->store();
} catch (FireflyException|Exception $e) {
$message = 'The import routine crashed: ' . $e->getMessage();
Log::error($message);
Log::error($e->getTraceAsString());
// set job errored out:
$jobRepository->setStatus($importJob, 'error');
$this->errorLine($message);
return 1;
}
// set storage to be finished:
$jobRepository->setStatus($importJob, 'storage_finished');
}
// give feedback:
$this->infoLine('Job has finished.');
if (null !== $importJob->tag) {
$this->infoLine(sprintf('%d transaction(s) have been imported.', $importJob->tag->transactionJournals->count()));
$this->infoLine(sprintf('You can find your transactions under tag "%s"', $importJob->tag->tag));
}
if (null === $importJob->tag) {
$this->errorLine('No transactions have been imported :(.');
}
if (\count($importJob->errors) > 0) {
$this->infoLine(sprintf('%d error(s) occurred:', \count($importJob->errors)));
foreach ($importJob->errors as $err) {
$this->errorLine('- ' . $err);
}
}
}
// clear cache for user:
app('preferences')->setForUser($user, 'lastActivity', microtime());
return 0;
}
/**
* @param string $message
* @param array|null $data
*/
private function errorLine(string $message, array $data = null): void
{
Log::error($message, $data ?? []);
$this->error($message);
}
/**
* @param string $message
* @param array $data
*/
private function infoLine(string $message, array $data = null): void
{
Log::info($message, $data ?? []);
$this->line($message);
}
/**
* Verify user inserts correct arguments.
*
* @noinspection MultipleReturnStatementsInspection
* @return bool
* @SuppressWarnings(PHPMD.CyclomaticComplexity) // it's five exactly.
*/
private function validArguments(): bool
{
/** @var UserRepositoryInterface $userRepository */
$userRepository = app(UserRepositoryInterface::class);
$file = $this->argument('file');
$configuration = $this->argument('configuration');
$user = $userRepository->find(intval($this->option('user')));
$cwd = getcwd();
$validTypes = config('import.options.file.import_formats');
$type = strtolower($this->option('type'));
if (null === $user) {
$this->error(sprintf('There is no user with ID %d.', $this->option('user')));
$file = (string)$this->argument('file');
$configuration = (string)$this->argument('configuration');
$cwd = getcwd();
$validTypes = config('import.options.file.import_formats');
$type = strtolower($this->option('type'));
$provider = strtolower($this->option('provider'));
$enabled = (bool)config(sprintf('import.enabled.%s', $provider));
if (false === $enabled) {
$this->errorLine(sprintf('Provider "%s" is not enabled.', $provider));
return false;
}
if (!in_array($type, $validTypes)) {
$this->error(sprintf('Cannot import file of type "%s"', $type));
if ('file' === $provider && !\in_array($type, $validTypes, true)) {
$this->errorLine(sprintf('Cannot import file of type "%s"', $type));
return false;
}
if (!file_exists($file)) {
$this->error(sprintf('Firefly III cannot find file "%s" (working directory: "%s").', $file, $cwd));
if ('file' === $provider && !file_exists($file)) {
$this->errorLine(sprintf('Firefly III cannot find file "%s" (working directory: "%s").', $file, $cwd));
return false;
}
if (!file_exists($configuration)) {
$this->error(sprintf('Firefly III cannot find configuration file "%s" (working directory: "%s").', $configuration, $cwd));
if ('file' === $provider && !file_exists($configuration)) {
$this->errorLine(sprintf('Firefly III cannot find configuration file "%s" (working directory: "%s").', $configuration, $cwd));
return false;
}

View File

@@ -0,0 +1,67 @@
<?php
namespace FireflyIII\Console\Commands;
use FireflyIII\Exceptions\FireflyException;
use FireflyIII\Support\Cronjobs\RecurringCronjob;
use Illuminate\Console\Command;
/**
* Class Cron
*
* @codeCoverageIgnore
*/
class Cron extends Command
{
/**
* The console command description.
*
* @var string
*/
protected $description = 'Runs all Firefly III cron-job related commands. Configure a cron job according to the official Firefly III documentation.';
/**
* The name and signature of the console command.
*
* @var string
*/
protected $signature = 'firefly:cron';
/**
* Create a new command instance.
*
* @return void
*/
public function __construct()
{
parent::__construct();
}
/**
* Execute the console command.
*
* @return mixed
*/
public function handle(): int
{
$recurring = new RecurringCronjob;
try {
$result = $recurring->fire();
} catch (FireflyException $e) {
$this->error($e->getMessage());
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;
}
}

View File

@@ -1,7 +1,7 @@
<?php
/**
* DecryptAttachment.php
* Copyright (c) 2017 thegrumpydictator@gmail.com
* Copyright (c) 2018 thegrumpydictator@gmail.com
*
* This file is part of Firefly III.
*
@@ -18,6 +18,9 @@
* You should have received a copy of the GNU General Public License
* along with Firefly III. If not, see <http://www.gnu.org/licenses/>.
*/
/** @noinspection MultipleReturnStatementsInspection */
declare(strict_types=1);
namespace FireflyIII\Console\Commands;
@@ -28,6 +31,8 @@ use Log;
/**
* Class DecryptAttachment.
*
* @codeCoverageIgnore
*/
class DecryptAttachment extends Command
{
@@ -47,54 +52,47 @@ class DecryptAttachment extends Command
= 'firefly:decrypt-attachment {id:The ID of the attachment.} {name:The file name of the attachment.}
{directory:Where the file must be stored.}';
/**
* Create a new command instance.
*/
public function __construct()
{
parent::__construct();
}
/**
* Execute the console command.
*
* @SuppressWarnings(PHPMD.CyclomaticComplexity) // it's five its fine.
* @SuppressWarnings(PHPMD.CyclomaticComplexity)
* @SuppressWarnings(PHPMD.ExcessiveMethodLength)
*
* @return int
*/
public function handle()
public function handle(): int
{
/** @var AttachmentRepositoryInterface $repository */
$repository = app(AttachmentRepositoryInterface::class);
$attachmentId = intval($this->argument('id'));
$attachmentId = (int)$this->argument('id');
$attachment = $repository->findWithoutUser($attachmentId);
$attachmentName = trim($this->argument('name'));
$storagePath = realpath(trim($this->argument('directory')));
if (null === $attachment->id) {
$attachmentName = trim((string)$this->argument('name'));
$storagePath = realpath(trim((string)$this->argument('directory')));
if (null === $attachment) {
$this->error(sprintf('No attachment with id #%d', $attachmentId));
Log::error(sprintf('DecryptAttachment: No attachment with id #%d', $attachmentId));
return;
return 1;
}
if ($attachmentName !== $attachment->filename) {
$this->error('File name does not match.');
Log::error('DecryptAttachment: File name does not match.');
return;
return 1;
}
if (!is_dir($storagePath)) {
$this->error(sprintf('Path "%s" is not a directory.', $storagePath));
Log::error(sprintf('DecryptAttachment: Path "%s" is not a directory.', $storagePath));
return;
return 1;
}
if (!is_writable($storagePath)) {
$this->error(sprintf('Path "%s" is not writable.', $storagePath));
Log::error(sprintf('DecryptAttachment: Path "%s" is not writable.', $storagePath));
return;
return 1;
}
$fullPath = $storagePath . DIRECTORY_SEPARATOR . $attachment->filename;
@@ -104,10 +102,10 @@ class DecryptAttachment extends Command
if (false === $result) {
$this->error('Could not write to file.');
return;
return 1;
}
$this->info(sprintf('%d bytes written. Exiting now..', $result));
return;
return 0;
}
}

View File

@@ -1,7 +1,7 @@
<?php
/**
* EncryptFile.php
* Copyright (c) 2017 thegrumpydictator@gmail.com
* Copyright (c) 2018 thegrumpydictator@gmail.com
*
* This file is part of Firefly III.
*
@@ -18,15 +18,19 @@
* You should have received a copy of the GNU General Public License
* along with Firefly III. If not, see <http://www.gnu.org/licenses/>.
*/
declare(strict_types=1);
namespace FireflyIII\Console\Commands;
use Crypt;
use FireflyIII\Exceptions\FireflyException;
use FireflyIII\Services\Internal\File\EncryptService;
use Illuminate\Console\Command;
/**
* Class EncryptFile.
*
* @codeCoverageIgnore
*/
class EncryptFile extends Command
{
@@ -44,31 +48,26 @@ class EncryptFile extends Command
*/
protected $signature = 'firefly:encrypt-file {file} {key}';
/**
* Create a new command instance.
*/
public function __construct()
{
parent::__construct();
}
/**
* Execute the console command.
*
* @throws \Illuminate\Contracts\Encryption\EncryptException
*/
public function handle()
public function handle(): int
{
$file = e(strval($this->argument('file')));
if (!file_exists($file)) {
$this->error(sprintf('File "%s" does not seem to exist.', $file));
$code = 0;
$file = (string)$this->argument('file');
$key = (string)$this->argument('key');
/** @var EncryptService $service */
$service = app(EncryptService::class);
return;
try {
$service->encrypt($file, $key);
} catch (FireflyException $e) {
$this->error($e->getMessage());
$code = 1;
}
$content = file_get_contents($file);
$content = Crypt::encrypt($content);
$newName = e(strval($this->argument('key'))) . '.upload';
$path = storage_path('upload') . '/' . $newName;
file_put_contents($path, $content);
$this->line(sprintf('Encrypted "%s" and put it in "%s"', $file, $path));
return $code;
}
}

View File

@@ -1,7 +1,7 @@
<?php
/**
* Import.php
* Copyright (c) 2017 thegrumpydictator@gmail.com
* Copyright (c) 2018 thegrumpydictator@gmail.com
*
* This file is part of Firefly III.
*
@@ -18,20 +18,25 @@
* You should have received a copy of the GNU General Public License
* along with Firefly III. If not, see <http://www.gnu.org/licenses/>.
*/
/** @noinspection MultipleReturnStatementsInspection */
/** @noinspection PhpDynamicAsStaticMethodCallInspection */
declare(strict_types=1);
namespace FireflyIII\Console\Commands;
use FireflyIII\Exceptions\FireflyException;
use FireflyIII\Import\Logging\CommandHandler;
use FireflyIII\Import\Routine\RoutineInterface;
use FireflyIII\Models\ImportJob;
use FireflyIII\Models\Tag;
use Illuminate\Console\Command;
use Illuminate\Support\MessageBag;
use Log;
/**
* Class Import.
*
* @codeCoverageIgnore
*/
class Import extends Command
{
@@ -49,40 +54,31 @@ class Import extends Command
*/
protected $signature = 'firefly:start-import {key}';
/**
* Create a new command instance.
*/
public function __construct()
{
parent::__construct();
}
/**
* Run the import routine.
* @SuppressWarnings(PHPMD.CyclomaticComplexity)
* @SuppressWarnings(PHPMD.ExcessiveMethodLength)
*
* @throws FireflyException
*/
public function handle()
public function handle(): int
{
Log::debug('Start start-import command');
$jobKey = $this->argument('key');
$job = ImportJob::where('key', $jobKey)->first();
$jobKey = (string)$this->argument('key');
/** @var ImportJob $job */
$job = ImportJob::where('key', $jobKey)->first();
if (null === $job) {
$this->error(sprintf('No job found with key "%s"', $jobKey));
$this->errorLine(sprintf('No job found with key "%s"', $jobKey));
return;
return 1;
}
if (!$this->isValid($job)) {
Log::error('Job is not valid for some reason. Exit.');
$this->errorLine('Job is not valid for some reason. Exit.');
return;
return 1;
}
$this->line(sprintf('Going to import job with key "%s" of type "%s"', $job->key, $job->file_type));
$monolog = Log::getMonolog();
$handler = new CommandHandler($this);
$monolog->pushHandler($handler);
$this->infoLine(sprintf('Going to import job with key "%s" of type "%s"', $job->key, $job->file_type));
// actually start job:
$type = 'csv' === $job->file_type ? 'file' : $job->file_type;
@@ -94,19 +90,52 @@ class Import extends Command
/** @var RoutineInterface $routine */
$routine = app($className);
$routine->setJob($job);
$routine->setImportJob($job);
$routine->run();
/** @var MessageBag $error */
foreach ($routine->getErrors() as $index => $error) {
$this->error(sprintf('Error importing line #%d: %s', $index, $error));
/**
* @var int $index
* @var string $error
*/
foreach ($job->errors as $index => $error) {
$this->errorLine(sprintf('Error importing line #%d: %s', $index, $error));
}
$this->line(
sprintf('The import has finished. %d transactions have been imported out of %d records.', $routine->getJournals()->count(), $routine->getLines())
);
/** @var Tag $tag */
$tag = $job->tag()->first();
$count = 0;
if (null === $tag) {
$count = $tag->transactionJournals()->count();
}
return;
$this->infoLine(sprintf('The import has finished. %d transactions have been imported.', $count));
return 0;
}
/**
* Displays an error.
*
* @param string $message
* @param array|null $data
*/
private function errorLine(string $message, array $data = null): void
{
Log::error($message, $data ?? []);
$this->error($message);
}
/**
* Displays an informational message.
*
* @param string $message
* @param array $data
*/
private function infoLine(string $message, array $data = null): void
{
Log::info($message, $data ?? []);
$this->line($message);
}
/**
@@ -119,15 +148,14 @@ class Import extends Command
private function isValid(ImportJob $job): bool
{
if (null === $job) {
Log::error('This job does not seem to exist.');
$this->error('This job does not seem to exist.');
$this->errorLine('This job does not seem to exist.');
return false;
}
if ('configured' !== $job->status) {
Log::error(sprintf('This job is not ready to be imported (status is %s).', $job->status));
$this->error('This job is not ready to be imported.');
$this->errorLine('This job is not ready to be imported.');
return false;
}

View File

@@ -1,7 +1,7 @@
<?php
/**
* ScanAttachments.php
* Copyright (c) 2017 thegrumpydictator@gmail.com
* Copyright (c) 2018 thegrumpydictator@gmail.com
*
* This file is part of Firefly III.
*
@@ -18,6 +18,9 @@
* You should have received a copy of the GNU General Public License
* along with Firefly III. If not, see <http://www.gnu.org/licenses/>.
*/
/** @noinspection PhpDynamicAsStaticMethodCallInspection */
declare(strict_types=1);
namespace FireflyIII\Console\Commands;
@@ -31,6 +34,8 @@ use Storage;
/**
* Class ScanAttachments.
*
* @codeCoverageIgnore
*/
class ScanAttachments extends Command
{
@@ -48,18 +53,10 @@ class ScanAttachments extends Command
*/
protected $signature = 'firefly:scan-attachments';
/**
* Create a new command instance.
*/
public function __construct()
{
parent::__construct();
}
/**
* Execute the console command.
*/
public function handle()
public function handle(): int
{
$attachments = Attachment::get();
$disk = Storage::disk('upload');
@@ -69,13 +66,13 @@ class ScanAttachments extends Command
try {
$content = $disk->get($fileName);
} catch (FileNotFoundException $e) {
$this->error(sprintf('Could not find data for attachment #%d', $attachment->id));
$this->error(sprintf('Could not find data for attachment #%d: %s', $attachment->id, $e->getMessage()));
continue;
}
try {
$decrypted = Crypt::decrypt($content);
} catch (DecryptException $e) {
$this->error(sprintf('Could not decrypt data of attachment #%d', $attachment->id));
$this->error(sprintf('Could not decrypt data of attachment #%d: %s', $attachment->id, $e->getMessage()));
continue;
}
$tmpfname = tempnam(sys_get_temp_dir(), 'FireflyIII');
@@ -87,5 +84,7 @@ class ScanAttachments extends Command
$attachment->save();
$this->line(sprintf('Fixed attachment #%d', $attachment->id));
}
return 0;
}
}

View File

@@ -1,7 +1,8 @@
<?php
/**
* UpgradeDatabase.php
* Copyright (c) 2017 thegrumpydictator@gmail.com
* Copyright (c) 2018 thegrumpydictator@gmail.com
*
* This file is part of Firefly III.
*
@@ -18,35 +19,53 @@
* You should have received a copy of the GNU General Public License
* along with Firefly III. If not, see <http://www.gnu.org/licenses/>.
*/
/** @noinspection MultipleReturnStatementsInspection */
/** @noinspection PhpStaticAsDynamicMethodCallInspection */
/** @noinspection PhpDynamicAsStaticMethodCallInspection */
declare(strict_types=1);
namespace FireflyIII\Console\Commands;
use DB;
use Exception;
use FireflyIII\Models\Account;
use FireflyIII\Models\AccountMeta;
use FireflyIII\Models\AccountType;
use FireflyIII\Models\Attachment;
use FireflyIII\Models\Bill;
use FireflyIII\Models\BudgetLimit;
use FireflyIII\Models\Note;
use FireflyIII\Models\Preference;
use FireflyIII\Models\Rule;
use FireflyIII\Models\RuleAction;
use FireflyIII\Models\RuleGroup;
use FireflyIII\Models\RuleTrigger;
use FireflyIII\Models\Transaction;
use FireflyIII\Models\TransactionCurrency;
use FireflyIII\Models\TransactionJournal;
use FireflyIII\Models\TransactionJournalMeta;
use FireflyIII\Models\TransactionType;
use FireflyIII\Repositories\Account\AccountRepositoryInterface;
use FireflyIII\Repositories\Currency\CurrencyRepositoryInterface;
use FireflyIII\Repositories\Journal\JournalRepositoryInterface;
use FireflyIII\User;
use Illuminate\Console\Command;
use Illuminate\Database\QueryException;
use Illuminate\Support\Collection;
use Log;
use Preferences;
use Schema;
use UnexpectedValueException;
/**
* Class UpgradeDatabase.
*
* Upgrade user database.
* @SuppressWarnings(PHPMD.ExcessiveClassComplexity)
* @SuppressWarnings(PHPMD.CouplingBetweenObjects)
*
*
* @SuppressWarnings(PHPMD.CouplingBetweenObjects) // it just touches a lot of things.
* @codeCoverageIgnore
*/
class UpgradeDatabase extends Command
{
@@ -63,20 +82,10 @@ class UpgradeDatabase extends Command
*/
protected $signature = 'firefly:upgrade-database';
/**
* Create a new command instance.
*/
public function __construct()
{
parent::__construct();
}
/**
* Execute the console command.
*
* @throws \Exception
*/
public function handle()
public function handle(): int
{
$this->setTransactionIdentifier();
$this->updateAccountCurrencies();
@@ -86,9 +95,161 @@ class UpgradeDatabase extends Command
$this->updateOtherCurrencies();
$this->line('Done updating currency information..');
$this->migrateNotes();
$this->migrateAttachmentData();
$this->migrateBillsToRules();
$this->budgetLimitCurrency();
$this->removeCCLiabilities();
$this->info('Firefly III database is up to date.');
return;
return 0;
}
/**
* Since it is one routine these warnings make sense and should be supressed.
*
* @SuppressWarnings(PHPMD.CyclomaticComplexity)
* @SuppressWarnings(PHPMD.ExcessiveMethodLength)
* @SuppressWarnings(PHPMD.NPathComplexity)
*/
public function migrateBillsToRules(): void
{
foreach (User::get() as $user) {
/** @var Preference $lang */
$lang = app('preferences')->getForUser($user, 'language', 'en_US');
$groupName = (string)trans('firefly.rulegroup_for_bills_title', [], $lang->data);
$ruleGroup = $user->ruleGroups()->where('title', $groupName)->first();
$currencyPreference = app('preferences')->getForUser($user, 'currencyPreference', config('firefly.default_currency', 'EUR'));
if (null === $currencyPreference) {
$this->error('User has no currency preference. Impossible.');
return;
}
$currency = TransactionCurrency::where('code', $currencyPreference->data)->first();
if (null === $currency) {
$this->line('Fall back to default currency in migrateBillsToRules().');
$currency = app('amount')->getDefaultCurrency();
}
if (null === $ruleGroup) {
$array = RuleGroup::get(['order'])->pluck('order')->toArray();
$order = \count($array) > 0 ? max($array) + 1 : 1;
$ruleGroup = RuleGroup::create(
[
'user_id' => $user->id,
'title' => (string)trans('firefly.rulegroup_for_bills_title', [], $lang->data),
'description' => (string)trans('firefly.rulegroup_for_bills_description', [], $lang->data),
'order' => $order,
'active' => 1,
]
);
}
// loop bills.
$order = 1;
/** @var Collection $collection */
$collection = $user->bills()->get();
/** @var Bill $bill */
foreach ($collection as $bill) {
if ('MIGRATED_TO_RULES' !== $bill->match) {
$rule = Rule::create(
[
'user_id' => $user->id,
'rule_group_id' => $ruleGroup->id,
'title' => (string)trans('firefly.rule_for_bill_title', ['name' => $bill->name], $lang->data),
'description' => (string)trans('firefly.rule_for_bill_description', ['name' => $bill->name], $lang->data),
'order' => $order,
'active' => $bill->active,
'stop_processing' => 1,
]
);
// add default trigger
RuleTrigger::create(
[
'rule_id' => $rule->id,
'trigger_type' => 'user_action',
'trigger_value' => 'store-journal',
'active' => 1,
'stop_processing' => 0,
'order' => 1,
]
);
// add trigger for description
$match = implode(' ', explode(',', $bill->match));
RuleTrigger::create(
[
'rule_id' => $rule->id,
'trigger_type' => 'description_contains',
'trigger_value' => $match,
'active' => 1,
'stop_processing' => 0,
'order' => 2,
]
);
if ($bill->amount_max !== $bill->amount_min) {
// add triggers for amounts:
RuleTrigger::create(
[
'rule_id' => $rule->id,
'trigger_type' => 'amount_less',
'trigger_value' => round($bill->amount_max, $currency->decimal_places),
'active' => 1,
'stop_processing' => 0,
'order' => 3,
]
);
RuleTrigger::create(
[
'rule_id' => $rule->id,
'trigger_type' => 'amount_more',
'trigger_value' => round((float)$bill->amount_min, $currency->decimal_places),
'active' => 1,
'stop_processing' => 0,
'order' => 4,
]
);
}
if ($bill->amount_max === $bill->amount_min) {
RuleTrigger::create(
[
'rule_id' => $rule->id,
'trigger_type' => 'amount_exactly',
'trigger_value' => round((float)$bill->amount_min, $currency->decimal_places),
'active' => 1,
'stop_processing' => 0,
'order' => 3,
]
);
}
// create action
RuleAction::create(
[
'rule_id' => $rule->id,
'action_type' => 'link_to_bill',
'action_value' => $bill->name,
'order' => 1,
'active' => 1,
'stop_processing' => 0,
]
);
$order++;
$bill->match = 'MIGRATED_TO_RULES';
$bill->save();
$this->line(sprintf('Updated bill #%d ("%s") so it will use rules.', $bill->id, $bill->name));
}
// give bills a currency when they dont have one.
if (null === $bill->transaction_currency_id) {
$this->line(sprintf('Gave bill #%d ("%s") a currency (%s).', $bill->id, $bill->name, $currency->name));
$bill->transactionCurrency()->associate($currency);
$bill->save();
}
}
}
}
/**
@@ -118,31 +279,36 @@ class UpgradeDatabase extends Command
$journalIds = array_unique($result->pluck('id')->toArray());
foreach ($journalIds as $journalId) {
$this->updateJournalidentifiers(intval($journalId));
$this->updateJournalidentifiers((int)$journalId);
}
return;
}
/**
* Each (asset) account must have a reference to a preferred currency. If the account does not have one, it's forced upon the account.
*
* @SuppressWarnings(PHPMD.CyclomaticComplexity) // it's seven but it can't really be helped.
* @SuppressWarnings(PHPMD.CyclomaticComplexity)
* @SuppressWarnings(PHPMD.ExcessiveMethodLength)
*/
public function updateAccountCurrencies(): void
{
$accounts = Account::leftJoin('account_types', 'account_types.id', '=', 'accounts.account_type_id')
->whereIn('account_types.type', [AccountType::DEFAULT, AccountType::ASSET])->get(['accounts.*']);
/** @var AccountRepositoryInterface $repository */
$repository = app(AccountRepositoryInterface::class);
$accounts->each(
function (Account $account) {
function (Account $account) use ($repository) {
$repository->setUser($account->user);
// get users preference, fall back to system pref.
$defaultCurrencyCode = Preferences::getForUser($account->user, 'currencyPreference', config('firefly.default_currency', 'EUR'))->data;
$defaultCurrencyCode = app('preferences')->getForUser($account->user, 'currencyPreference', config('firefly.default_currency', 'EUR'))->data;
$defaultCurrency = TransactionCurrency::where('code', $defaultCurrencyCode)->first();
$accountCurrency = intval($account->getMeta('currency_id'));
$accountCurrency = (int)$repository->getMetaValue($account, 'currency_id');
$openingBalance = $account->getOpeningBalance();
$obCurrency = intval($openingBalance->transaction_currency_id);
$obCurrency = (int)$openingBalance->transaction_currency_id;
if (null === $defaultCurrency) {
throw new UnexpectedValueException('The default currency is NULL, and this is more or less impossible.');
}
// both 0? set to default currency:
if (0 === $accountCurrency && 0 === $obCurrency) {
@@ -175,7 +341,6 @@ class UpgradeDatabase extends Command
}
);
return;
}
/**
@@ -185,19 +350,22 @@ class UpgradeDatabase extends Command
* Both source and destination must match the respective currency preference of the related asset account.
* So FF3 must verify all transactions.
*
* @SuppressWarnings(PHPMD.CyclomaticComplexity)
* @SuppressWarnings(PHPMD.ExcessiveMethodLength)
*/
public function updateOtherCurrencies(): void
{
/** @var CurrencyRepositoryInterface $repository */
$repository = app(CurrencyRepositoryInterface::class);
$set = TransactionJournal
/** @var AccountRepositoryInterface $accountRepos */
$accountRepos = app(AccountRepositoryInterface::class);
$set = TransactionJournal
::leftJoin('transaction_types', 'transaction_types.id', '=', 'transaction_journals.transaction_type_id')
->whereIn('transaction_types.type', [TransactionType::WITHDRAWAL, TransactionType::DEPOSIT, TransactionType::OPENING_BALANCE])
->get(['transaction_journals.*']);
$set->each(
function (TransactionJournal $journal) use ($repository) {
function (TransactionJournal $journal) use ($repository, $accountRepos) {
// get the transaction with the asset account in it:
/** @var Transaction $transaction */
$transaction = $journal->transactions()
@@ -207,9 +375,13 @@ class UpgradeDatabase extends Command
if (null === $transaction) {
return;
}
$accountRepos->setUser($journal->user);
/** @var Account $account */
$account = $transaction->account;
$currency = $repository->find(intval($account->getMeta('currency_id')));
$account = $transaction->account;
$currency = $repository->findNull((int)$accountRepos->getMetaValue($account, 'currency_id'));
if (null === $currency) {
return;
}
$transactions = $journal->transactions()->get();
$transactions->each(
function (Transaction $transaction) use ($currency) {
@@ -219,8 +391,8 @@ class UpgradeDatabase extends Command
}
// when mismatch in transaction:
if (!(intval($transaction->transaction_currency_id) === intval($currency->id))) {
$transaction->foreign_currency_id = intval($transaction->transaction_currency_id);
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();
@@ -233,7 +405,6 @@ class UpgradeDatabase extends Command
}
);
return;
}
/**
@@ -246,7 +417,7 @@ class UpgradeDatabase extends Command
* Both source and destination must match the respective currency preference. So FF3 must verify ALL
* transactions.
*/
public function updateTransferCurrencies()
public function updateTransferCurrencies(): void
{
$set = TransactionJournal
::leftJoin('transaction_types', 'transaction_types.id', '=', 'transaction_journals.transaction_type_id')
@@ -268,26 +439,82 @@ class UpgradeDatabase extends Command
);
}
/**
*
*/
private function budgetLimitCurrency(): void
{
$budgetLimits = BudgetLimit::get();
/** @var BudgetLimit $budgetLimit */
foreach ($budgetLimits as $budgetLimit) {
if (null === $budgetLimit->transaction_currency_id) {
$budget = $budgetLimit->budget;
if (null !== $budget) {
$user = $budget->user;
if (null !== $user) {
$currency = \Amount::getDefaultCurrencyByUser($user);
$budgetLimit->transaction_currency_id = $currency->id;
$budgetLimit->save();
$this->line(
sprintf('Budget limit #%d (part of budget "%s") now has a currency setting (%s).', $budgetLimit->id, $budget->name, $currency->name)
);
}
}
}
}
}
private function createNewTypes(): void
{
// create transaction type "Reconciliation".
$type = TransactionType::where('type', TransactionType::RECONCILIATION)->first();
if (is_null($type)) {
if (null === $type) {
TransactionType::create(['type' => TransactionType::RECONCILIATION]);
}
$account = AccountType::where('type', AccountType::RECONCILIATION)->first();
if (is_null($account)) {
if (null === $account) {
AccountType::create(['type' => AccountType::RECONCILIATION]);
}
}
/**
* Move the description of each attachment (when not NULL) to the notes or to a new note object
* for all attachments.
*/
private function migrateAttachmentData(): void
{
$attachments = Attachment::get();
/** @var Attachment $att */
foreach ($attachments as $att) {
// move description:
$description = (string)$att->description;
if (\strlen($description) > 0) {
// find or create note:
$note = $att->notes()->first();
if (null === $note) {
$note = new Note;
$note->noteable()->associate($att);
}
$note->text = $description;
$note->save();
// clear description:
$att->description = '';
$att->save();
Log::debug(sprintf('Migrated attachment #%s description to note #%d', $att->id, $note->id));
}
}
}
/**
* Move all the journal_meta notes to their note object counter parts.
*
* @throws \Exception
*/
private function migrateNotes(): void
{
/** @noinspection PhpUndefinedMethodInspection */
$set = TransactionJournalMeta::whereName('notes')->get();
/** @var TransactionJournalMeta $meta */
foreach ($set as $meta) {
@@ -301,7 +528,33 @@ class UpgradeDatabase extends Command
$note->text = $meta->data;
$note->save();
Log::debug(sprintf('Migrated meta note #%d to Note #%d', $meta->id, $note->id));
$meta->delete();
try {
$meta->delete();
} catch (Exception $e) {
Log::error(sprintf('Could not delete old meta entry #%d: %s', $meta->id, $e->getMessage()));
}
}
}
/**
*
*/
private function removeCCLiabilities(): void
{
$ccType = AccountType::where('type', AccountType::CREDITCARD)->first();
$debtType =AccountType::where('type', AccountType::DEBT)->first();
if(null === $ccType || null === $debtType) {
return;
}
/** @var Collection $accounts */
$accounts = Account::where('account_type_id', $ccType->id)->get();
foreach($accounts as $account) {
$account->account_type_id = $debtType->id;
$account->save();
$this->line(sprintf('Converted credit card liability account "%s" (#%d) to generic debt liability.', $account->name, $account->id));
}
if($accounts->count() > 0) {
$this->info('Credit card liability types are no longer supported and have been converted to generic debts. See: http://bit.ly/FF3-credit-cards');
}
}
@@ -314,10 +567,17 @@ class UpgradeDatabase extends Command
{
/** @var CurrencyRepositoryInterface $repository */
$repository = app(CurrencyRepositoryInterface::class);
$currency = $repository->find(intval($transaction->account->getMeta('currency_id')));
$journal = $transaction->transactionJournal;
/** @var AccountRepositoryInterface $accountRepos */
$accountRepos = app(AccountRepositoryInterface::class);
$accountRepos->setUser($transaction->account->user);
$currency = $repository->findNull((int)$accountRepos->getMetaValue($transaction->account, 'currency_id'));
$journal = $transaction->transactionJournal;
if (!(intval($currency->id) === intval($journal->transaction_currency_id))) {
if (null === $currency) {
return;
}
if (!((int)$currency->id === (int)$journal->transaction_currency_id)) {
$this->line(
sprintf(
'Transfer #%d ("%s") has been updated to use %s instead of %s.',
@@ -331,7 +591,6 @@ class UpgradeDatabase extends Command
$journal->save();
}
return;
}
/**
@@ -348,7 +607,7 @@ class UpgradeDatabase extends Command
/** @var Transaction $transaction */
foreach ($transactions as $transaction) {
// find opposing:
$amount = bcmul(strval($transaction->amount), '-1');
$amount = bcmul((string)$transaction->amount, '-1');
try {
/** @var Transaction $opposing */
@@ -377,7 +636,6 @@ class UpgradeDatabase extends Command
++$identifier;
}
return;
}
/**
@@ -386,11 +644,11 @@ class UpgradeDatabase extends Command
*
* The transaction that is sent to this function MUST be the source transaction (amount negative).
*
* Method is long and complex bit I'm taking it for granted.
* Method is long and complex but I'll allow it. https://imgur.com/gallery/dVDJiez
*
* @SuppressWarnings(PHPMD.CyclomaticComplexity)
* @SuppressWarnings(PHPMD.ExcessiveMethodLength)
* @SuppressWarnings(PHPMD.NPathComplexity)
* @SuppressWarnings(PHPMD.CyclomaticComplexity)
*
* @param Transaction $transaction
*/
@@ -398,18 +656,31 @@ class UpgradeDatabase extends Command
{
/** @var CurrencyRepositoryInterface $repository */
$repository = app(CurrencyRepositoryInterface::class);
$currency = $repository->find(intval($transaction->account->getMeta('currency_id')));
/** @var AccountRepositoryInterface $accountRepos */
$accountRepos = app(AccountRepositoryInterface::class);
/** @var JournalRepositoryInterface $journalRepos */
$journalRepos = app(JournalRepositoryInterface::class);
$accountRepos->setUser($transaction->account->user);
$journalRepos->setUser($transaction->account->user);
$currency = $repository->findNull((int)$accountRepos->getMetaValue($transaction->account, 'currency_id'));
if (null === $currency) {
Log::error(sprintf('Account #%d ("%s") must have currency preference but has none.', $transaction->account->id, $transaction->account->name));
return;
}
// has no currency ID? Must have, so fill in using account preference:
if (null === $transaction->transaction_currency_id) {
$transaction->transaction_currency_id = intval($currency->id);
$transaction->transaction_currency_id = (int)$currency->id;
Log::debug(sprintf('Transaction #%d has no currency setting, now set to %s', $transaction->id, $currency->code));
$transaction->save();
}
// does not match the source account (see above)? Can be fixed
// when mismatch in transaction and NO foreign amount is set:
if (!(intval($transaction->transaction_currency_id) === intval($currency->id)) && null === $transaction->foreign_amount) {
if (!((int)$transaction->transaction_currency_id === (int)$currency->id) && null === $transaction->foreign_amount) {
Log::debug(
sprintf(
'Transaction #%d has a currency setting #%d that should be #%d. Amount remains %s, currency is changed.',
@@ -419,7 +690,7 @@ class UpgradeDatabase extends Command
$transaction->amount
)
);
$transaction->transaction_currency_id = intval($currency->id);
$transaction->transaction_currency_id = (int)$currency->id;
$transaction->save();
}
@@ -428,16 +699,16 @@ class UpgradeDatabase extends Command
$journal = $transaction->transactionJournal;
/** @var Transaction $opposing */
$opposing = $journal->transactions()->where('amount', '>', 0)->where('identifier', $transaction->identifier)->first();
$opposingCurrency = $repository->find(intval($opposing->account->getMeta('currency_id')));
$opposingCurrency = $repository->findNull((int)$accountRepos->getMetaValue($opposing->account, 'currency_id'));
if (null === $opposingCurrency->id) {
if (null === $opposingCurrency) {
Log::error(sprintf('Account #%d ("%s") must have currency preference but has none.', $opposing->account->id, $opposing->account->name));
return;
}
// if the destination account currency is the same, both foreign_amount and foreign_currency_id must be NULL for both transactions:
if (intval($opposingCurrency->id) === intval($currency->id)) {
if ((int)$opposingCurrency->id === (int)$currency->id) {
// update both transactions to match:
$transaction->foreign_amount = null;
$transaction->foreign_currency_id = null;
@@ -446,12 +717,21 @@ class UpgradeDatabase extends Command
$opposing->transaction_currency_id = $currency->id;
$transaction->save();
$opposing->save();
Log::debug(sprintf('Cleaned up transaction #%d and #%d', $transaction->id, $opposing->id));
Log::debug(
sprintf(
'Currency for account "%s" is %s, and currency for account "%s" is also
%s, so %s #%d (#%d and #%d) has been verified to be to %s exclusively.',
$opposing->account->name, $opposingCurrency->code,
$transaction->account->name, $transaction->transactionCurrency->code,
$journal->transactionType->type, $journal->id,
$transaction->id, $opposing->id, $currency->code
)
);
return;
}
// if destination account currency is different, both transactions must have this currency as foreign currency id.
if (!(intval($opposingCurrency->id) === intval($currency->id))) {
if (!((int)$opposingCurrency->id === (int)$currency->id)) {
$transaction->foreign_currency_id = $opposingCurrency->id;
$opposing->foreign_currency_id = $opposingCurrency->id;
$transaction->save();
@@ -461,31 +741,31 @@ class UpgradeDatabase extends Command
// if foreign amount of one is null and the other is not, use this to restore:
if (null === $transaction->foreign_amount && null !== $opposing->foreign_amount) {
$transaction->foreign_amount = bcmul(strval($opposing->foreign_amount), '-1');
$transaction->foreign_amount = bcmul((string)$opposing->foreign_amount, '-1');
$transaction->save();
Log::debug(sprintf('Restored foreign amount of transaction (1) #%d to %s', $transaction->id, $transaction->foreign_amount));
}
// if foreign amount of one is null and the other is not, use this to restore (other way around)
if (null === $opposing->foreign_amount && null !== $transaction->foreign_amount) {
$opposing->foreign_amount = bcmul(strval($transaction->foreign_amount), '-1');
$opposing->foreign_amount = bcmul((string)$transaction->foreign_amount, '-1');
$opposing->save();
Log::debug(sprintf('Restored foreign amount of transaction (2) #%d to %s', $opposing->id, $opposing->foreign_amount));
}
// when both are zero, try to grab it from journal:
if (null === $opposing->foreign_amount && null === $transaction->foreign_amount) {
$foreignAmount = $journal->getMeta('foreign_amount');
$foreignAmount = $journalRepos->getMetaField($journal, 'foreign_amount');
if (null === $foreignAmount) {
Log::debug(sprintf('Journal #%d has missing foreign currency data, forced to do 1:1 conversion :(.', $transaction->transaction_journal_id));
$transaction->foreign_amount = bcmul(strval($transaction->amount), '-1');
$opposing->foreign_amount = bcmul(strval($opposing->amount), '-1');
$transaction->foreign_amount = bcmul((string)$transaction->amount, '-1');
$opposing->foreign_amount = bcmul((string)$opposing->amount, '-1');
$transaction->save();
$opposing->save();
return;
}
$foreignPositive = app('steam')->positive(strval($foreignAmount));
$foreignPositive = app('steam')->positive((string)$foreignAmount);
Log::debug(
sprintf(
'Journal #%d has missing foreign currency info, try to restore from meta-data ("%s").',
@@ -499,7 +779,6 @@ class UpgradeDatabase extends Command
$opposing->save();
}
return;
}
}

View File

@@ -1,7 +1,7 @@
<?php
/**
* UpgradeFireflyInstructions.php
* Copyright (c) 2017 thegrumpydictator@gmail.com
* Copyright (c) 2018 thegrumpydictator@gmail.com
*
* This file is part of Firefly III.
*
@@ -18,6 +18,7 @@
* You should have received a copy of the GNU General Public License
* along with Firefly III. If not, see <http://www.gnu.org/licenses/>.
*/
declare(strict_types=1);
namespace FireflyIII\Console\Commands;
@@ -26,6 +27,8 @@ use Illuminate\Console\Command;
/**
* Class UpgradeFireflyInstructions.
*
* @codeCoverageIgnore
*/
class UpgradeFireflyInstructions extends Command
{
@@ -42,25 +45,19 @@ class UpgradeFireflyInstructions extends Command
*/
protected $signature = 'firefly:instructions {task}';
/**
* Create a new command instance.
*/
public function __construct()
{
parent::__construct();
}
/**
* Execute the console command.
*/
public function handle()
public function handle(): int
{
if ('update' === $this->argument('task')) {
if ('update' === (string)$this->argument('task')) {
$this->updateInstructions();
}
if ('install' === $this->argument('task')) {
if ('install' === (string)$this->argument('task')) {
$this->installInstructions();
}
return 0;
}
/**
@@ -68,7 +65,7 @@ class UpgradeFireflyInstructions extends Command
*
* @param string $text
*/
private function boxed(string $text)
private function boxed(string $text): void
{
$parts = explode("\n", wordwrap($text));
foreach ($parts as $string) {
@@ -81,7 +78,7 @@ class UpgradeFireflyInstructions extends Command
*
* @param string $text
*/
private function boxedInfo(string $text)
private function boxedInfo(string $text): void
{
$parts = explode("\n", wordwrap($text));
foreach ($parts as $string) {
@@ -92,7 +89,7 @@ class UpgradeFireflyInstructions extends Command
/**
* Render instructions.
*/
private function installInstructions()
private function installInstructions(): void
{
/** @var string $version */
$version = config('firefly.version');
@@ -100,8 +97,7 @@ class UpgradeFireflyInstructions extends Command
$text = '';
foreach (array_keys($config) as $compare) {
// if string starts with:
$len = strlen($compare);
if (substr($version, 0, $len) === $compare) {
if (0 === strpos($version, $compare)) {
$text = $config[$compare];
}
}
@@ -126,7 +122,7 @@ class UpgradeFireflyInstructions extends Command
/**
* Show a line.
*/
private function showLine()
private function showLine(): void
{
$line = '+';
for ($i = 0; $i < 78; ++$i) {
@@ -139,7 +135,7 @@ class UpgradeFireflyInstructions extends Command
/**
* Render upgrade instructions.
*/
private function updateInstructions()
private function updateInstructions(): void
{
/** @var string $version */
$version = config('firefly.version');
@@ -147,8 +143,7 @@ class UpgradeFireflyInstructions extends Command
$text = '';
foreach (array_keys($config) as $compare) {
// if string starts with:
$len = strlen($compare);
if (substr($version, 0, $len) === $compare) {
if (0 === strpos($version, $compare)) {
$text = $config[$compare];
}
}

View File

@@ -1,8 +1,7 @@
<?php
/**
* UseEncryption.php
* Copyright (c) 2017 thegrumpydictator@gmail.com
* Copyright (c) 2018 thegrumpydictator@gmail.com
*
* This file is part of Firefly III.
*
@@ -19,6 +18,7 @@
* You should have received a copy of the GNU General Public License
* along with Firefly III. If not, see <http://www.gnu.org/licenses/>.
*/
declare(strict_types=1);
namespace FireflyIII\Console\Commands;
@@ -28,6 +28,7 @@ use Illuminate\Support\Str;
/**
* Class UseEncryption.
* @codeCoverageIgnore
*/
class UseEncryption extends Command
{
@@ -44,23 +45,15 @@ class UseEncryption extends Command
*/
protected $signature = 'firefly:use-encryption';
/**
* Create a new command instance.
*/
public function __construct()
{
parent::__construct();
}
/**
* Execute the console command.
*/
public function handle()
public function handle(): int
{
if (config('firefly.encryption') === true) {
if (true === config('firefly.encryption')) {
$this->info('Firefly III configuration calls for encrypted data.');
}
if (config('firefly.encryption') === false) {
if (false === config('firefly.encryption')) {
$this->info('Firefly III configuration calls for unencrypted data.');
}
$this->handleObjects('Account', 'name', 'encrypted');
@@ -70,6 +63,8 @@ class UseEncryption extends Command
$this->handleObjects('Category', 'name', 'encrypted');
$this->handleObjects('PiggyBank', 'name', 'encrypted');
$this->handleObjects('TransactionJournal', 'description', 'encrypted');
return 0;
}
/**
@@ -79,18 +74,21 @@ class UseEncryption extends Command
* @param string $field
* @param string $indicator
*/
public function handleObjects(string $class, string $field, string $indicator)
public function handleObjects(string $class, string $field, string $indicator): void
{
$fqn = sprintf('FireflyIII\Models\%s', $class);
$encrypt = config('firefly.encryption') === true ? 0 : 1;
$set = $fqn::where($indicator, $encrypt)->get();
$encrypt = true === config('firefly.encryption') ? 0 : 1;
/** @noinspection PhpUndefinedMethodInspection */
$set = $fqn::where($indicator, $encrypt)->get();
foreach ($set as $entry) {
$newName = $entry->$field;
$entry->$field = $newName;
/** @noinspection PhpUndefinedMethodInspection */
$entry->save();
}
/** @noinspection PhpUndefinedMethodInspection */
$this->line(sprintf('Updated %d %s.', $set->count(), strtolower(Str::plural($class))));
}
}

View File

@@ -1,7 +1,7 @@
<?php
/**
* VerifiesAccessToken.php
* Copyright (c) 2017 thegrumpydictator@gmail.com
* Copyright (c) 2018 thegrumpydictator@gmail.com
*
* This file is part of Firefly III.
*
@@ -18,18 +18,19 @@
* You should have received a copy of the GNU General Public License
* along with Firefly III. If not, see <http://www.gnu.org/licenses/>.
*/
declare(strict_types=1);
namespace FireflyIII\Console\Commands;
use FireflyIII\Repositories\User\UserRepositoryInterface;
use Log;
use Preferences;
/**
* Trait VerifiesAccessToken.
*
* Verifies user access token for sensitive commands.
* @codeCoverageIgnore
*/
trait VerifiesAccessToken
{
@@ -49,18 +50,18 @@ trait VerifiesAccessToken
*/
protected function verifyAccessToken(): bool
{
$userId = intval($this->option('user'));
$token = strval($this->option('token'));
$userId = (int)$this->option('user');
$token = (string)$this->option('token');
/** @var UserRepositoryInterface $repository */
$repository = app(UserRepositoryInterface::class);
$user = $repository->find($userId);
$user = $repository->findNull($userId);
if (null === $user) {
Log::error(sprintf('verifyAccessToken(): no such user for input "%d"', $userId));
return false;
}
$accessToken = Preferences::getForUser($user, 'access_token', null);
$accessToken = app('preferences')->getForUser($user, 'access_token', null);
if (null === $accessToken) {
Log::error(sprintf('User #%d has no access token, so cannot access command line options.', $userId));
@@ -68,7 +69,7 @@ trait VerifiesAccessToken
}
if (!($accessToken->data === $token)) {
Log::error(sprintf('Invalid access token for user #%d.', $userId));
Log::error(sprintf('Token given is "%s", expected "%s".', $token, $accessToken->data));
Log::error(sprintf('Token given is "%s", expected something else.', $token));
return false;
}

View File

@@ -1,7 +1,7 @@
<?php
/**
* VerifyDatabase.php
* Copyright (c) 2017 thegrumpydictator@gmail.com
* Copyright (c) 2018 thegrumpydictator@gmail.com
*
* This file is part of Firefly III.
*
@@ -18,6 +18,9 @@
* You should have received a copy of the GNU General Public License
* along with Firefly III. If not, see <http://www.gnu.org/licenses/>.
*/
/** @noinspection PhpDynamicAsStaticMethodCallInspection */
declare(strict_types=1);
namespace FireflyIII\Console\Commands;
@@ -27,6 +30,7 @@ use DB;
use FireflyIII\Models\Account;
use FireflyIII\Models\AccountType;
use FireflyIII\Models\Budget;
use FireflyIII\Models\Category;
use FireflyIII\Models\LinkType;
use FireflyIII\Models\PiggyBankEvent;
use FireflyIII\Models\Transaction;
@@ -37,14 +41,16 @@ use FireflyIII\User;
use Illuminate\Console\Command;
use Illuminate\Contracts\Encryption\DecryptException;
use Illuminate\Database\Eloquent\Builder;
use Preferences;
use Log;
use Schema;
use stdClass;
/**
* Class VerifyDatabase.
*
* @SuppressWarnings(PHPMD.ExcessiveClassComplexity)
* @SuppressWarnings(PHPMD.CouplingBetweenObjects)
* @codeCoverageIgnore
*/
class VerifyDatabase extends Command
{
@@ -61,26 +67,18 @@ class VerifyDatabase extends Command
*/
protected $signature = 'firefly:verify';
/**
* Create a new command instance.
*/
public function __construct()
{
parent::__construct();
}
/**
* Execute the console command.
*/
public function handle()
public function handle(): int
{
// if table does not exist, return false
if (!Schema::hasTable('users')) {
return;
return 1;
}
$this->reportObject('budget');
$this->reportObject('category');
$this->reportEmptyBudgets();
$this->reportEmptyCategories();
$this->reportObject('tag');
$this->reportAccounts();
$this->reportBudgetLimits();
@@ -95,21 +93,25 @@ class VerifyDatabase extends Command
$this->createLinkTypes();
$this->createAccessTokens();
$this->fixDoubleAmounts();
$this->fixBadMeta();
$this->removeBills();
return 0;
}
/**
* Create user access tokens, if not present already.
*/
private function createAccessTokens()
private function createAccessTokens(): void
{
$count = 0;
$users = User::get();
/** @var User $user */
foreach ($users as $user) {
$pref = Preferences::getForUser($user, 'access_token', null);
$pref = app('preferences')->getForUser($user, 'access_token', null);
if (null === $pref) {
$token = $user->generateAccessToken();
Preferences::setForUser($user, 'access_token', $token);
app('preferences')->setForUser($user, 'access_token', $token);
$this->line(sprintf('Generated access token for user %s', $user->email));
++$count;
}
@@ -122,7 +124,7 @@ class VerifyDatabase extends Command
/**
* Create default link types if necessary.
*/
private function createLinkTypes()
private function createLinkTypes(): void
{
$count = 0;
$set = [
@@ -148,7 +150,78 @@ class VerifyDatabase extends Command
}
}
private function fixDoubleAmounts()
/**
* Fix the situation where the matching transactions of a journal somehow have non-matching categories or budgets.
*
* @SuppressWarnings(PHPMD.CyclomaticComplexity)
* @SuppressWarnings(PHPMD.ExcessiveMethodLength)
*/
private function fixBadMeta(): void
{
// categories
$set = Transaction
::leftJoin('category_transaction', 'category_transaction.transaction_id', '=', 'transactions.id')
->whereNull('transactions.deleted_at')
->get(['transactions.id', 'transaction_journal_id', 'identifier', 'category_transaction.category_id', 'category_transaction.id as ct_id']);
$results = [];
foreach ($set as $obj) {
$key = $obj->transaction_journal_id . '-' . $obj->identifier;
$category = (int)$obj->category_id;
// value exists and is not category:
if (isset($results[$key]) && $results[$key] !== $category) {
$this->error(
sprintf(
'Transaction #%d referred to the wrong category. Was category #%d but is fixed to be category #%d.', $obj->transaction_journal_id,
$category, $results[$key]
)
);
DB::table('category_transaction')->where('id', $obj->ct_id)->update(['category_id' => $results[$key]]);
}
// value does not exist:
if ($category > 0 && !isset($results[$key])) {
$results[$key] = $category;
}
}
// budgets
$set = Transaction
::leftJoin('budget_transaction', 'budget_transaction.transaction_id', '=', 'transactions.id')
->whereNull('transactions.deleted_at')
->get(['transactions.id', 'transaction_journal_id', 'identifier', 'budget_transaction.budget_id', 'budget_transaction.id as ct_id']);
$results = [];
foreach ($set as $obj) {
$key = $obj->transaction_journal_id . '-' . $obj->identifier;
$budget = (int)$obj->budget_id;
// value exists and is not budget:
if (isset($results[$key]) && $results[$key] !== $budget) {
$this->error(
sprintf(
'Transaction #%d referred to the wrong budget. Was budget #%d but is fixed to be budget #%d.', $obj->transaction_journal_id, $budget,
$results[$key]
)
);
DB::table('budget_transaction')->where('id', $obj->ct_id)->update(['budget_id' => $results[$key]]);
}
// value does not exist:
if ($budget > 0 && !isset($results[$key])) {
$results[$key] = $budget;
}
}
}
/**
* Makes sure amounts are stored correctly.
*
* @SuppressWarnings(PHPMD.CyclomaticComplexity)
* @SuppressWarnings(PHPMD.ExcessiveMethodLength)
*/
private function fixDoubleAmounts(): void
{
$count = 0;
// get invalid journals
@@ -158,7 +231,7 @@ class VerifyDatabase extends Command
->get(['transaction_journal_id', DB::raw('SUM(amount) AS the_sum')]);
/** @var stdClass $entry */
foreach ($journals as $entry) {
if (0 !== bccomp(strval($entry->the_sum), '0')) {
if (0 !== bccomp((string)$entry->the_sum, '0')) {
$errored[] = $entry->transaction_journal_id;
}
}
@@ -171,7 +244,7 @@ class VerifyDatabase extends Command
// report about it
/** @var TransactionJournal $journal */
$journal = TransactionJournal::find($journalId);
if (is_null($journal)) {
if (null === $journal) {
continue;
}
if (TransactionType::OPENING_BALANCE === $journal->transactionType->type) {
@@ -194,8 +267,23 @@ class VerifyDatabase extends Command
if (0 === $count) {
$this->info('Amount integrity OK!');
}
}
return;
/**
* Removes bills from journals that should not have bills.
*/
private function removeBills(): void
{
/** @var TransactionType $withdrawal */
$withdrawal = TransactionType::where('type', TransactionType::WITHDRAWAL)->first();
$journals = TransactionJournal::whereNotNull('bill_id')
->where('transaction_type_id', '!=', $withdrawal->id)->get();
/** @var TransactionJournal $journal */
foreach ($journals as $journal) {
$this->line(sprintf('Transaction journal #%d should not be linked to bill #%d.', $journal->id, $journal->bill_id));
$journal->bill_id = null;
$journal->save();
}
}
/**
@@ -225,14 +313,12 @@ class VerifyDatabase extends Command
return true;
}
);
return;
}
/**
* Reports on accounts with no transactions.
*/
private function reportAccounts()
private function reportAccounts(): void
{
$set = Account::leftJoin('transactions', 'transactions.account_id', '=', 'accounts.id')
->leftJoin('users', 'accounts.user_id', '=', 'users.id')
@@ -254,7 +340,7 @@ class VerifyDatabase extends Command
/**
* Reports on budgets with no budget limits (which makes them pointless).
*/
private function reportBudgetLimits()
private function reportBudgetLimits(): void
{
$set = Budget::leftJoin('budget_limits', 'budget_limits.budget_id', '=', 'budgets.id')
->leftJoin('users', 'budgets.user_id', '=', 'users.id')
@@ -278,7 +364,7 @@ class VerifyDatabase extends Command
/**
* Reports on deleted accounts that still have not deleted transactions or journals attached to them.
*/
private function reportDeletedAccounts()
private function reportDeletedAccounts(): void
{
$set = Account::leftJoin('transactions', 'transactions.account_id', '=', 'accounts.id')
->leftJoin('transaction_journals', 'transaction_journals.id', '=', 'transactions.transaction_journal_id')
@@ -297,7 +383,7 @@ class VerifyDatabase extends Command
);
/** @var stdClass $entry */
foreach ($set as $entry) {
$date = null === $entry->transaction_deleted_at ? $entry->journal_deleted_at : $entry->transaction_deleted_at;
$date = $entry->transaction_deleted_at ?? $entry->journal_deleted_at;
$this->error(
'Error: Account #' . $entry->account_id . ' should have been deleted, but has not.' .
' Find it in the table called "accounts" and change the "deleted_at" field to: "' . $date . '"'
@@ -305,10 +391,86 @@ class VerifyDatabase extends Command
}
}
/**
* Report on budgets with no transactions or journals.
*/
private function reportEmptyBudgets(): void
{
$set = Budget::leftJoin('budget_transaction_journal', 'budgets.id', '=', 'budget_transaction_journal.budget_id')
->leftJoin('users', 'budgets.user_id', '=', 'users.id')
->distinct()
->whereNull('budget_transaction_journal.budget_id')
->whereNull('budgets.deleted_at')
->get(['budgets.id', 'budgets.name', 'budgets.user_id', 'users.email']);
/** @var stdClass $entry */
foreach ($set as $entry) {
$objName = $entry->name;
try {
$objName = Crypt::decrypt($objName);
} catch (DecryptException $e) {
// it probably was not encrypted.
Log::debug(sprintf('Not a problem: %s', $e->getMessage()));
}
// also count the transactions:
$countTransactions = DB::table('budget_transaction')->where('budget_id', $entry->id)->count();
if (0 === $countTransactions) {
$line = sprintf(
'User #%d (%s) has budget #%d ("%s") which has no transactions.',
$entry->user_id,
$entry->email,
$entry->id,
$objName
);
$this->line($line);
}
}
}
/**
* Report on categories with no transactions or journals.
*/
private function reportEmptyCategories(): void
{
$set = Category::leftJoin('category_transaction_journal', 'categories.id', '=', 'category_transaction_journal.category_id')
->leftJoin('users', 'categories.user_id', '=', 'users.id')
->distinct()
->whereNull('category_transaction_journal.category_id')
->whereNull('categories.deleted_at')
->get(['categories.id', 'categories.name', 'categories.user_id', 'users.email']);
/** @var stdClass $entry */
foreach ($set as $entry) {
$objName = $entry->name;
try {
$objName = Crypt::decrypt($objName);
} catch (DecryptException $e) {
// it probably was not encrypted.
Log::debug(sprintf('Not a problem: %s', $e->getMessage()));
}
// also count the transactions:
$countTransactions = DB::table('category_transaction')->where('category_id', $entry->id)->count();
if (0 === $countTransactions) {
$line = sprintf(
'User #%d (%s) has category #%d ("%s") which has no transactions.',
$entry->user_id,
$entry->email,
$entry->id,
$objName
);
$this->line($line);
}
}
}
/**
* Report on journals with bad account types linked to them.
*/
private function reportIncorrectJournals()
private function reportIncorrectJournals(): void
{
$configuration = [
// a withdrawal can not have revenue account:
@@ -350,7 +512,7 @@ class VerifyDatabase extends Command
/**
* Any deleted transaction journals that have transactions that are NOT deleted:.
*/
private function reportJournals()
private function reportJournals(): void
{
$count = 0;
$set = TransactionJournal::leftJoin('transactions', 'transactions.transaction_journal_id', '=', 'transaction_journals.id')
@@ -381,7 +543,7 @@ class VerifyDatabase extends Command
/**
* Report on journals without transactions.
*/
private function reportNoTransactions()
private function reportNoTransactions(): void
{
$count = 0;
$set = TransactionJournal::leftJoin('transactions', 'transactions.transaction_journal_id', '=', 'transaction_journals.id')
@@ -405,17 +567,18 @@ class VerifyDatabase extends Command
*
* @param string $name
*/
private function reportObject(string $name)
private function reportObject(string $name): void
{
$plural = str_plural($name);
$class = sprintf('FireflyIII\Models\%s', ucfirst($name));
$field = 'tag' === $name ? 'tag' : 'name';
$set = $class::leftJoin($name . '_transaction_journal', $plural . '.id', '=', $name . '_transaction_journal.' . $name . '_id')
->leftJoin('users', $plural . '.user_id', '=', 'users.id')
->distinct()
->whereNull($name . '_transaction_journal.' . $name . '_id')
->whereNull($plural . '.deleted_at')
->get([$plural . '.id', $plural . '.' . $field . ' as name', $plural . '.user_id', 'users.email']);
/** @noinspection PhpUndefinedMethodInspection */
$set = $class::leftJoin($name . '_transaction_journal', $plural . '.id', '=', $name . '_transaction_journal.' . $name . '_id')
->leftJoin('users', $plural . '.user_id', '=', 'users.id')
->distinct()
->whereNull($name . '_transaction_journal.' . $name . '_id')
->whereNull($plural . '.deleted_at')
->get([$plural . '.id', $plural . '.' . $field . ' as name', $plural . '.user_id', 'users.email']);
/** @var stdClass $entry */
foreach ($set as $entry) {
@@ -424,6 +587,7 @@ class VerifyDatabase extends Command
$objName = Crypt::decrypt($objName);
} catch (DecryptException $e) {
// it probably was not encrypted.
Log::debug(sprintf('Not a problem: %s', $e->getMessage()));
}
$line = sprintf(
@@ -441,17 +605,18 @@ class VerifyDatabase extends Command
/**
* Reports for each user when the sum of their transactions is not zero.
*/
private function reportSum()
private function reportSum(): void
{
/** @var UserRepositoryInterface $userRepository */
$userRepository = app(UserRepositoryInterface::class);
/** @var User $user */
foreach ($userRepository->all() as $user) {
$sum = strval($user->transactions()->sum('amount'));
$sum = (string)$user->transactions()->sum('amount');
if (0 !== bccomp($sum, '0')) {
$this->error('Error: Transactions for user #' . $user->id . ' (' . $user->email . ') are off by ' . $sum . '!');
} else {
}
if (0 === bccomp($sum, '0')) {
$this->info(sprintf('Amount integrity OK for user #%d', $user->id));
}
}
@@ -460,7 +625,7 @@ class VerifyDatabase extends Command
/**
* Reports on deleted transactions that are connected to a not deleted journal.
*/
private function reportTransactions()
private function reportTransactions(): void
{
$set = Transaction::leftJoin('transaction_journals', 'transactions.transaction_journal_id', '=', 'transaction_journals.id')
->whereNotNull('transactions.deleted_at')
@@ -481,7 +646,7 @@ class VerifyDatabase extends Command
/**
* Report on transfers that have budgets.
*/
private function reportTransfersBudgets()
private function reportTransfersBudgets(): void
{
$set = TransactionJournal::distinct()
->leftJoin('transaction_types', 'transaction_types.id', '=', 'transaction_journals.transaction_type_id')

View File

@@ -1,7 +1,8 @@
<?php
/**
* Kernel.php
* Copyright (c) 2017 thegrumpydictator@gmail.com
* Copyright (c) 2018 thegrumpydictator@gmail.com
*
* This file is part of Firefly III.
*
@@ -18,34 +19,29 @@
* You should have received a copy of the GNU General Public License
* along with Firefly III. If not, see <http://www.gnu.org/licenses/>.
*/
declare(strict_types=1);
namespace FireflyIII\Console;
use Illuminate\Console\Scheduling\Schedule;
use Illuminate\Foundation\Console\Kernel as ConsoleKernel;
use Log;
/**
* File to make sure commnds work.
* File to make sure commands work.
* @codeCoverageIgnore
*/
class Kernel extends ConsoleKernel
{
/**
* The Artisan commands provided by your application.
*
* @var array
*/
protected $commands
= [
];
/**
* Register the commands for the application.
*/
protected function commands()
protected function commands(): void
{
$this->load(__DIR__ . '/Commands');
/** @noinspection PhpIncludeInspection */
require base_path('routes/console.php');
}
@@ -53,10 +49,24 @@ class Kernel extends ConsoleKernel
* Define the application's command schedule.
*
* @param \Illuminate\Console\Scheduling\Schedule $schedule
*
* @SuppressWarnings(PHPMD.UnusedFormalParameter)
*/
protected function schedule(Schedule $schedule)
protected function schedule(Schedule $schedule): void
{
$schedule->call(
function () {
Log::error('Firefly III no longer users the Laravel scheduler to do cron jobs! Please read the instructions at https://firefly-iii.readthedocs.io/en/latest/');
echo "\n";
echo '------------';
echo "\n";
echo wordwrap('Firefly III no longer users the Laravel scheduler to do cron jobs! Please read the instructions here:');
echo "\n";
echo 'https://firefly-iii.readthedocs.io/en/latest/';
echo "\n\n";
echo 'Disable this cron job!';
echo "\n";
echo '------------';
echo "\n";
}
)->everyMinute();
}
}

View File

@@ -1,7 +1,8 @@
<?php
/**
* AdminRequestedTestMessage.php
* Copyright (c) 2017 thegrumpydictator@gmail.com
* Copyright (c) 2018 thegrumpydictator@gmail.com
*
* This file is part of Firefly III.
*
@@ -18,6 +19,7 @@
* You should have received a copy of the GNU General Public License
* along with Firefly III. If not, see <http://www.gnu.org/licenses/>.
*/
declare(strict_types=1);
namespace FireflyIII\Events;
@@ -28,18 +30,15 @@ use Log;
/**
* Class AdminRequestedTestMessage.
* @codeCoverageIgnore
*/
class AdminRequestedTestMessage extends Event
{
use SerializesModels;
/**
* @var string
*/
/** @var string The users IP address */
public $ipAddress;
/**
* @var User
*/
/** @var User The user */
public $user;
/**

View File

@@ -1,7 +1,8 @@
<?php
/**
* Event.php
* Copyright (c) 2017 thegrumpydictator@gmail.com
* Copyright (c) 2018 thegrumpydictator@gmail.com
*
* This file is part of Firefly III.
*
@@ -18,12 +19,14 @@
* You should have received a copy of the GNU General Public License
* along with Firefly III. If not, see <http://www.gnu.org/licenses/>.
*/
declare(strict_types=1);
namespace FireflyIII\Events;
/**
* Class Event.
* @codeCoverageIgnore
*/
abstract class Event
{

View File

@@ -1,7 +1,8 @@
<?php
/**
* RegisteredUser.php
* Copyright (c) 2017 thegrumpydictator@gmail.com
* Copyright (c) 2018 thegrumpydictator@gmail.com
*
* This file is part of Firefly III.
*
@@ -18,6 +19,7 @@
* You should have received a copy of the GNU General Public License
* along with Firefly III. If not, see <http://www.gnu.org/licenses/>.
*/
declare(strict_types=1);
namespace FireflyIII\Events;
@@ -27,18 +29,15 @@ use Illuminate\Queue\SerializesModels;
/**
* Class RegisteredUser.
* @codeCoverageIgnore
*/
class RegisteredUser extends Event
{
use SerializesModels;
/**
* @var string
*/
/** @var string The users IP address */
public $ipAddress;
/**
* @var User
*/
/** @var User The user */
public $user;
/**

View File

@@ -1,7 +1,8 @@
<?php
/**
* RequestedNewPassword.php
* Copyright (c) 2017 thegrumpydictator@gmail.com
* Copyright (c) 2018 thegrumpydictator@gmail.com
*
* This file is part of Firefly III.
*
@@ -18,6 +19,7 @@
* You should have received a copy of the GNU General Public License
* along with Firefly III. If not, see <http://www.gnu.org/licenses/>.
*/
declare(strict_types=1);
namespace FireflyIII\Events;
@@ -27,22 +29,17 @@ use Illuminate\Queue\SerializesModels;
/**
* Class RequestedNewPassword.
* @codeCoverageIgnore
*/
class RequestedNewPassword extends Event
{
use SerializesModels;
/**
* @var string
*/
/** @var string The users IP address */
public $ipAddress;
/**
* @var string
*/
/** @var string The token */
public $token;
/**
* @var User
*/
/** @var User The user */
public $user;
/**

View File

@@ -0,0 +1,68 @@
<?php
declare(strict_types=1);
/**
* RequestedReportOnJournals.php
* Copyright (c) 2018 thegrumpydictator@gmail.com
*
* This file is part of Firefly III.
*
* Firefly III is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Firefly III 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Firefly III. If not, see <http://www.gnu.org/licenses/>.
*/
namespace FireflyIII\Events;
use Illuminate\Broadcasting\InteractsWithSockets;
use Illuminate\Broadcasting\PrivateChannel;
use Illuminate\Foundation\Events\Dispatchable;
use Illuminate\Queue\SerializesModels;
use Illuminate\Support\Collection;
use Log;
/**
* Class RequestedReportOnJournals
*
* @codeCoverageIgnore
*/
class RequestedReportOnJournals
{
use Dispatchable, InteractsWithSockets, SerializesModels;
/** @var Collection The journals to report on. */
public $journals;
/** @var int The ID of the user. */
public $userId;
/**
* Create a new event instance.
*
* @param int $userId
* @param Collection $journals
*/
public function __construct(int $userId, Collection $journals)
{
Log::debug('In event RequestedReportOnJournals.');
$this->userId = $userId;
$this->journals = $journals;
}
/**
* Get the channels the event should broadcast on.
*
* @return \Illuminate\Broadcasting\Channel|array
*/
public function broadcastOn()
{
return new PrivateChannel('channel-name');
}
}

View File

@@ -1,7 +1,8 @@
<?php
/**
* RequestedVersionCheckStatus.php
* Copyright (c) 2017 thegrumpydictator@gmail.com
* Copyright (c) 2018 thegrumpydictator@gmail.com
*
* This file is part of Firefly III.
*
@@ -29,14 +30,14 @@ use Illuminate\Queue\SerializesModels;
/**
* Class RequestedVersionCheckStatus
*
* @codeCoverageIgnore
*/
class RequestedVersionCheckStatus extends Event
{
use SerializesModels;
/**
* @var User
*/
/** @var User The user */
public $user;
/**

View File

@@ -1,7 +1,8 @@
<?php
/**
* StoredTransactionJournal.php
* Copyright (c) 2017 thegrumpydictator@gmail.com
* Copyright (c) 2018 thegrumpydictator@gmail.com
*
* This file is part of Firefly III.
*
@@ -18,6 +19,7 @@
* You should have received a copy of the GNU General Public License
* along with Firefly III. If not, see <http://www.gnu.org/licenses/>.
*/
declare(strict_types=1);
namespace FireflyIII\Events;
@@ -27,14 +29,16 @@ use Illuminate\Queue\SerializesModels;
/**
* Class StoredTransactionJournal.
*
* @codeCoverageIgnore
*/
class StoredTransactionJournal extends Event
{
use SerializesModels;
/** @var TransactionJournal */
/** @var TransactionJournal The journal that was stored. */
public $journal;
/** @var int */
/** @var int The piggy bank ID. */
public $piggyBankId;
/**

View File

@@ -1,7 +1,8 @@
<?php
/**
* UpdatedTransactionJournal.php
* Copyright (c) 2017 thegrumpydictator@gmail.com
* Copyright (c) 2018 thegrumpydictator@gmail.com
*
* This file is part of Firefly III.
*
@@ -18,6 +19,7 @@
* You should have received a copy of the GNU General Public License
* along with Firefly III. If not, see <http://www.gnu.org/licenses/>.
*/
declare(strict_types=1);
namespace FireflyIII\Events;
@@ -27,12 +29,15 @@ use Illuminate\Queue\SerializesModels;
/**
* Class UpdatedTransactionJournal.
*
* @codeCoverageIgnore
*
*/
class UpdatedTransactionJournal extends Event
{
use SerializesModels;
/** @var TransactionJournal */
/** @var TransactionJournal The journal. */
public $journal;
/**

View File

@@ -1,7 +1,8 @@
<?php
/**
* UserChangedEmail.php
* Copyright (c) 2017 thegrumpydictator@gmail.com
* Copyright (c) 2018 thegrumpydictator@gmail.com
*
* This file is part of Firefly III.
*
@@ -18,6 +19,7 @@
* You should have received a copy of the GNU General Public License
* along with Firefly III. If not, see <http://www.gnu.org/licenses/>.
*/
declare(strict_types=1);
namespace FireflyIII\Events;
@@ -27,18 +29,20 @@ use Illuminate\Queue\SerializesModels;
/**
* Class UserChangedEmail.
*
* @codeCoverageIgnore
*/
class UserChangedEmail extends Event
{
use SerializesModels;
/** @var string */
/** @var string The user's IP address */
public $ipAddress;
/** @var string */
/** @var string The user's new email address */
public $newEmail;
/** @var string */
/** @var string The user's old email address */
public $oldEmail;
/** @var User */
/** @var User The user itself */
public $user;
/**

View File

@@ -1,7 +1,8 @@
<?php
/**
* FireflyException.php
* Copyright (c) 2017 thegrumpydictator@gmail.com
* Copyright (c) 2018 thegrumpydictator@gmail.com
*
* This file is part of Firefly III.
*
@@ -18,13 +19,16 @@
* You should have received a copy of the GNU General Public License
* along with Firefly III. If not, see <http://www.gnu.org/licenses/>.
*/
declare(strict_types=1);
namespace FireflyIII\Exceptions;
use Exception;
/**
* Class FireflyException.
*/
class FireflyException extends \Exception
class FireflyException extends Exception
{
}

View File

@@ -1,7 +1,8 @@
<?php
/**
* Handler.php
* Copyright (c) 2017 thegrumpydictator@gmail.com
* Copyright (c) 2018 thegrumpydictator@gmail.com
*
* This file is part of Firefly III.
*
@@ -18,6 +19,9 @@
* You should have received a copy of the GNU General Public License
* along with Firefly III. If not, see <http://www.gnu.org/licenses/>.
*/
/** @noinspection MultipleReturnStatementsInspection */
declare(strict_types=1);
namespace FireflyIII\Exceptions;
@@ -27,56 +31,48 @@ use Exception;
use FireflyIII\Jobs\MailError;
use Illuminate\Auth\AuthenticationException;
use Illuminate\Foundation\Exceptions\Handler as ExceptionHandler;
use Illuminate\Validation\ValidationException;
use Illuminate\Validation\ValidationException as LaravelValidationException;
use League\OAuth2\Server\Exception\OAuthServerException;
use Request;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
/**
* Class Handler
* @codeCoverageIgnore
*/
class Handler extends ExceptionHandler
{
/**
* A list of the inputs that are never flashed for validation exceptions.
*
* @var array
*/
protected $dontFlash
= [
'password',
'password_confirmation',
];
/**
* A list of the exception types that are not reported.
*
* @var array
*/
protected $dontReport
= [
];
/**
* Render an exception into an HTTP response.
*
* @param \Illuminate\Http\Request $request
* @param \Exception $exception
* @param Request $request
* @param Exception $exception
* @SuppressWarnings(PHPMD.CyclomaticComplexity)
* @SuppressWarnings(PHPMD.NPathComplexity)
* @SuppressWarnings(PHPMD.ExcessiveMethodLength)
*
* @return \Illuminate\Http\Response
* @return mixed
*/
public function render($request, Exception $exception)
{
if ($exception instanceof ValidationException && $request->expectsJson()) {
if ($exception instanceof LaravelValidationException && $request->expectsJson()) {
// ignore it: controller will handle it.
return parent::render($request, $exception);
}
if ($exception instanceof NotFoundHttpException && $request->expectsJson()) {
// JSON error:
return response()->json(['message' => 'Resource not found', 'exception' => 'NotFoundHttpException'], 404);
}
if ($exception instanceof AuthenticationException && $request->expectsJson()) {
// somehow Laravel handler does not catch this:
return response()->json(['message' => 'Unauthenticated', 'exception' => 'AuthenticationException'], 401);
}
if ($exception instanceof OAuthServerException && $request->expectsJson()) {
// somehow Laravel handler does not catch this:
return response()->json(['message' => $exception->getMessage(), 'exception' => 'OAuthServerException'], 401);
}
if ($request->expectsJson()) {
$isDebug = config('app.debug', false);
@@ -84,7 +80,7 @@ class Handler extends ExceptionHandler
return response()->json(
[
'message' => $exception->getMessage(),
'exception' => get_class($exception),
'exception' => \get_class($exception),
'line' => $exception->getLine(),
'file' => $exception->getFile(),
'trace' => $exception->getTrace(),
@@ -92,10 +88,10 @@ class Handler extends ExceptionHandler
);
}
return response()->json(['message' => 'Internal Firefly III Exception. See log files.', 'exception' => get_class($exception)], 500);
return response()->json(['message' => 'Internal Firefly III Exception. See log files.', 'exception' => \get_class($exception)], 500);
}
if ($exception instanceof FireflyException || $exception instanceof ErrorException) {
if ($exception instanceof FireflyException || $exception instanceof ErrorException || $exception instanceof OAuthServerException) {
$isDebug = env('APP_DEBUG', false);
return response()->view('errors.FireflyException', ['exception' => $exception, 'debug' => $isDebug], 500);
@@ -119,8 +115,12 @@ class Handler extends ExceptionHandler
*/
public function report(Exception $exception)
{
$doMailError = env('SEND_ERROR_MESSAGE', true);
if (($exception instanceof FireflyException || $exception instanceof ErrorException) && $doMailError) {
// if the user wants us to mail:
if (true === $doMailError
// and if is one of these error instances
&& ($exception instanceof FireflyException || $exception instanceof ErrorException || $exception instanceof OAuthServerException)) {
$userData = [
'id' => 0,
'email' => 'unknown@example.com',
@@ -130,7 +130,7 @@ class Handler extends ExceptionHandler
$userData['email'] = auth()->user()->email;
}
$data = [
'class' => get_class($exception),
'class' => \get_class($exception),
'errorMessage' => $exception->getMessage(),
'time' => date('r'),
'stackTrace' => $exception->getTraceAsString(),
@@ -138,6 +138,9 @@ class Handler extends ExceptionHandler
'line' => $exception->getLine(),
'code' => $exception->getCode(),
'version' => config('firefly.version'),
'url' => Request::fullUrl(),
'userAgent' => Request::userAgent(),
'json' => Request::acceptsJson(),
];
// create job that will mail.

View File

@@ -1,7 +1,8 @@
<?php
/**
* NotImplementedException.php
* Copyright (c) 2017 thegrumpydictator@gmail.com
* Copyright (c) 2018 thegrumpydictator@gmail.com
*
* This file is part of Firefly III.
*
@@ -18,6 +19,7 @@
* You should have received a copy of the GNU General Public License
* along with Firefly III. If not, see <http://www.gnu.org/licenses/>.
*/
declare(strict_types=1);
namespace FireflyIII\Exceptions;

View File

@@ -1,7 +1,8 @@
<?php
/**
* ValidationException.php
* Copyright (c) 2017 thegrumpydictator@gmail.com
* Copyright (c) 2018 thegrumpydictator@gmail.com
*
* This file is part of Firefly III.
*
@@ -18,6 +19,7 @@
* You should have received a copy of the GNU General Public License
* along with Firefly III. If not, see <http://www.gnu.org/licenses/>.
*/
declare(strict_types=1);
namespace FireflyIII\Exceptions;

View File

@@ -1,7 +1,7 @@
<?php
/**
* AttachmentCollector.php
* Copyright (c) 2017 thegrumpydictator@gmail.com
* Copyright (c) 2018 thegrumpydictator@gmail.com
*
* This file is part of Firefly III.
*
@@ -18,6 +18,7 @@
* You should have received a copy of the GNU General Public License
* along with Firefly III. If not, see <http://www.gnu.org/licenses/>.
*/
declare(strict_types=1);
namespace FireflyIII\Export\Collector;
@@ -33,18 +34,21 @@ use Storage;
/**
* Class AttachmentCollector.
*
* @deprecated
* @codeCoverageIgnore
*/
class AttachmentCollector extends BasicCollector implements CollectorInterface
{
/** @var Carbon */
/** @var Carbon The end date of the range. */
private $end;
/** @var \Illuminate\Contracts\Filesystem\Filesystem */
/** @var \Illuminate\Contracts\Filesystem\Filesystem File system */
private $exportDisk;
/** @var AttachmentRepositoryInterface */
/** @var AttachmentRepositoryInterface Attachment repository */
private $repository;
/** @var Carbon */
/** @var Carbon Start date of range */
private $start;
/** @var \Illuminate\Contracts\Filesystem\Filesystem */
/** @var \Illuminate\Contracts\Filesystem\Filesystem Disk with uploads on it */
private $uploadDisk;
/**
@@ -62,6 +66,8 @@ class AttachmentCollector extends BasicCollector implements CollectorInterface
}
/**
* Run the routine.
*
* @return bool
*/
public function run(): bool
@@ -78,6 +84,8 @@ class AttachmentCollector extends BasicCollector implements CollectorInterface
}
/**
* Set the start and end date.
*
* @param Carbon $start
* @param Carbon $end
*/
@@ -87,24 +95,33 @@ class AttachmentCollector extends BasicCollector implements CollectorInterface
$this->end = $end;
}
/** @noinspection MultipleReturnStatementsInspection */
/**
* Export attachments.
*
* @param Attachment $attachment
*
* @return bool
*/
private function exportAttachment(Attachment $attachment): bool
{
$file = $attachment->fileName();
$file = $attachment->fileName();
$decrypted = false;
if ($this->uploadDisk->exists($file)) {
try {
$decrypted = Crypt::decrypt($this->uploadDisk->get($file));
$exportFile = $this->exportFileName($attachment);
$this->exportDisk->put($exportFile, $decrypted);
$this->getEntries()->push($exportFile);
$decrypted = Crypt::decrypt($this->uploadDisk->get($file));
} catch (DecryptException $e) {
Log::error('Catchable error: could not decrypt attachment #' . $attachment->id . ' because: ' . $e->getMessage());
return false;
}
}
if (false === $decrypted) {
return false;
}
$exportFile = $this->exportFileName($attachment);
$this->exportDisk->put($exportFile, $decrypted);
$this->getEntries()->push($exportFile);
return true;
}
@@ -118,17 +135,18 @@ class AttachmentCollector extends BasicCollector implements CollectorInterface
*/
private function exportFileName($attachment): string
{
return sprintf('%s-Attachment nr. %s - %s', $this->job->key, strval($attachment->id), $attachment->filename);
return sprintf('%s-Attachment nr. %s - %s', $this->job->key, (string)$attachment->id, $attachment->filename);
}
/**
* Get the attachments.
*
* @return Collection
*/
private function getAttachments(): Collection
{
$this->repository->setUser($this->user);
$attachments = $this->repository->getBetween($this->start, $this->end);
return $attachments;
return $this->repository->getBetween($this->start, $this->end);
}
}

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