Compare commits

..

254 Commits

Author SHA1 Message Date
James Cole
fb9ac50828 Merge branch 'release/5.0.0-alpha.1' 2019-12-27 07:15:08 +01:00
James Cole
206ae5a3f3 Update composer. 2019-12-27 07:14:23 +01:00
James Cole
1120fef4d6 New translations. 2019-12-27 07:14:15 +01:00
James Cole
8bcb4432c7 Parse changelog. 2019-12-27 06:52:13 +01:00
James Cole
df01db1a51 Update changelog for next release 2019-12-27 06:51:54 +01:00
James Cole
72bf04fe54 Version update for 5.0.0 2019-12-27 06:24:41 +01:00
James Cole
d5416bad7c Final tests for #2723 2019-12-26 11:37:49 +01:00
James Cole
952c9aad23 More tests for #2723 2019-12-26 11:29:54 +01:00
James Cole
1b1d510bc0 Forgot to include method. 2019-12-26 11:22:10 +01:00
James Cole
fc8400cdf9 Fix and expand tests for #2723 2019-12-26 11:06:38 +01:00
James Cole
c23f16739c Add some debug info. 2019-12-26 11:05:58 +01:00
James Cole
ecdefab086 Update to version 5.0.0 2019-12-22 07:51:29 +01:00
James Cole
a416b682e0 Fix some tests 2019-12-22 07:50:40 +01:00
James Cole
dfca5b8722 No check if no accounts submitted. 2019-12-22 07:50:21 +01:00
James Cole
4111973a06 Add some logging 2019-12-22 07:50:10 +01:00
James Cole
af063191ab Remove SFTP config 2019-12-22 07:50:02 +01:00
James Cole
1a37d3735b Update changelog a bit 2019-12-22 07:49:28 +01:00
James Cole
01c3236fed Remove SFTP config 2019-12-22 07:49:06 +01:00
James Cole
dcd6a8d79f Remove import tests 2019-12-22 07:45:30 +01:00
James Cole
a4d3dba662 Fix #2912 2019-12-22 06:23:13 +01:00
James Cole
2a110185a1 All rules for #2723, untested. 2019-12-21 06:37:41 +01:00
James Cole
be2794406c First code for #2723 2019-12-20 21:01:27 +01:00
James Cole
b4af70421d Fix #2702 2019-12-20 20:21:31 +01:00
James Cole
7431e18e4b Fix #2776 2019-12-20 17:28:49 +01:00
James Cole
cc936e68f2 Update translations. 2019-12-20 16:42:23 +01:00
James Cole
18ed19c9d9 Fix #2907 2019-12-20 11:57:57 +01:00
James Cole
83dd170dcb Update libraries. 2019-12-20 08:25:46 +01:00
James Cole
adb32ceed8 Fix #2580 2019-12-20 07:15:40 +01:00
James Cole
91172611d4 Merge tag '4.8.3-alpha.1' into develop
4.8.3-alpha.1
2019-12-20 06:15:26 +01:00
James Cole
e2a30b3cc1 Merge branch 'release/4.8.3-alpha.1' 2019-12-20 06:15:25 +01:00
James Cole
689850c55c Update version, add changelog. 2019-12-20 06:15:00 +01:00
James Cole
6ad2021739 Fix #2901 2019-12-20 05:53:13 +01:00
James Cole
e96e96e6c9 Update composer. 2019-12-20 05:44:48 +01:00
James Cole
126dd5176e Share disclaimer in footer 2019-12-20 05:44:39 +01:00
James Cole
4abedb58aa Share disclaimer in footer 2019-12-20 05:44:33 +01:00
James Cole
94194d497f Fix #2881 2019-12-20 05:38:42 +01:00
James Cole
d29ec707b4 Add some debug info 2019-12-20 05:38:26 +01:00
James Cole
96e0357328 Fix #2878 again 2019-12-19 07:00:18 +01:00
James Cole
883acc698e Update libraries. 2019-12-17 20:13:42 +01:00
James Cole
0387d7c9a3 Merge pull request #2895 from justyns/js-add-debit
Add Debit to Generic Debit Credit indicator converter
2019-12-16 05:49:46 +01:00
Justyn Shull
c5bed5e042 Add Debit to Generic Debit Credit indicator converter
Example CSV export from Community America, a Credit Union in the US:

``` csv
12/11/19,Five Guys,Sale FIVE GUYS,14.51,Debit,Food & Dining,Fast Food,CC1,,,false
12/11/19,Interest Income,Interest Earned,0.01,Credit,Income,Interest Income,Regular Savings,,Interest Earned,false
```

"Debit" is used instead of negative values in the amount column.
2019-12-15 19:06:44 -06:00
James Cole
b6ec5073e0 Expand entrypoint feedback. 2019-12-08 07:44:57 +01:00
James Cole
969ae4c551 Update labels to see what happens. 2019-12-08 07:21:44 +01:00
James Cole
df649c5871 Some debug vars in logs. 2019-12-08 06:44:56 +01:00
James Cole
450433f12e Messed up DB config. Seems redis is working though. 2019-12-08 06:28:00 +01:00
James Cole
4bab045d6f Echo some feedback 2019-12-08 06:15:58 +01:00
James Cole
31744440e0 Updated redis config. 2019-12-08 06:14:49 +01:00
James Cole
78ccca4f58 Better text and fixed entry point 2019-12-08 05:57:36 +01:00
James Cole
53d630ef91 Expand entry point script and example .env 2019-12-08 05:48:17 +01:00
James Cole
670c4c6dc3 Expand config for redis. 2019-12-07 17:44:33 +01:00
James Cole
1e7de48f59 Fix #2876 2019-12-04 05:59:06 +01:00
James Cole
55175da316 Wait longer for DB 2019-12-03 19:38:49 +01:00
James Cole
916aff425a Clean up changelog 2019-12-03 19:38:40 +01:00
James Cole
6a7a0e2b25 Fix #2878 2019-12-03 19:38:07 +01:00
James Cole
eeb68c1cf4 Fix #2874 2019-12-02 17:32:57 +01:00
James Cole
73d56c41d6 Merge branch 'release/4.8.2' 2019-11-29 07:19:12 +01:00
James Cole
3a775627b5 Merge tag '4.8.2' into develop
4.8.2
2019-11-29 07:19:12 +01:00
James Cole
702acafc59 Updated some templates. 2019-11-28 20:52:14 +01:00
James Cole
11c04cb0d4 Update packages. 2019-11-28 20:33:55 +01:00
James Cole
47a8e28948 Support for SE. 2019-11-28 20:27:00 +01:00
James Cole
c9702fe65c New translations 2019-11-28 20:22:25 +01:00
James Cole
8ce3f8dc60 New version 2019-11-28 20:22:05 +01:00
James Cole
7daedc6c5a New changelog 2019-11-28 20:21:56 +01:00
James Cole
1ff855ce66 Fix owner of all dirs. 2019-11-27 06:14:33 +01:00
James Cole
c3f721aa9f Fix #2847 2019-11-26 06:34:32 +01:00
James Cole
575b355837 Merge branch 'release/4.8.2-beta.2' 2019-11-25 18:44:45 +01:00
James Cole
813bb6a09b Merge tag '4.8.2-beta.2' into develop
4.8.2-beta.2
2019-11-25 18:44:45 +01:00
James Cole
a4b1c9d8c5 New beta version 2019-11-25 18:43:36 +01:00
James Cole
98bd35e767 Update composer file. 2019-11-25 18:41:55 +01:00
James Cole
e485f8ca66 New strings for translation. 2019-11-25 18:41:40 +01:00
James Cole
4551dfe0e5 Merge branch 'release/4.8.2-alpha.6' 2019-11-23 06:21:39 +01:00
James Cole
709411e7b4 Merge tag '4.8.2-alpha.6' into develop
4.8.2-alpha.6
2019-11-23 06:21:39 +01:00
James Cole
420b996870 New alpha release. 2019-11-23 06:21:18 +01:00
James Cole
4304c15ffe Add support for Swedish, disable Greek. 2019-11-23 06:15:25 +01:00
James Cole
36e643e5b8 Fix #2851 2019-11-23 06:14:50 +01:00
James Cole
fcf3691b2b Fix #2852 2019-11-23 05:44:44 +01:00
James Cole
3ec15a3b7b Fix for #2843 2019-11-19 17:39:55 +01:00
James Cole
4ae7501114 Fix #2841 (again) 2019-11-18 20:41:08 +01:00
James Cole
5e348e7a40 Merge tag '4.8.2-alpha.5' into develop
4.8.2-alpha.5
2019-11-18 19:13:45 +01:00
James Cole
24fe611645 Merge branch 'release/4.8.2-alpha.5' 2019-11-18 19:13:44 +01:00
James Cole
402a6fa4c7 Fix #2841 2019-11-18 19:06:08 +01:00
James Cole
308ce15fae Fixes #2835 2019-11-18 17:39:25 +01:00
James Cole
9a639d41b4 Set default values so people know to change them. 2019-11-17 16:25:46 +01:00
James Cole
fc7cb987ff New Kubernetes deployment 2019-11-17 15:17:22 +01:00
James Cole
ba5ac35330 New scripts for Firefly III in Kubernetes 2019-11-17 15:09:31 +01:00
James Cole
e2e8ae5b28 Some command fixes. 2019-11-17 13:34:33 +01:00
James Cole
4ad0e120bc New version. 2019-11-17 13:22:57 +01:00
James Cole
cd2e74a476 Some experimental commands for DB creation. 2019-11-17 13:18:35 +01:00
James Cole
07623335f7 Fix #2832 2019-11-17 11:34:53 +01:00
James Cole
6b2b2aa1e1 Merge branch 'release/4.8.2-beta.1' 2019-11-17 07:02:36 +01:00
James Cole
414c4a742d Merge tag '4.8.2-beta.1' into develop
4.8.2-beta.1
2019-11-17 07:02:36 +01:00
James Cole
55e2f31531 Update version. 2019-11-17 05:03:20 +01:00
James Cole
99c9a0fec5 Small update in deploy script. 2019-11-17 04:41:20 +01:00
James Cole
075c06fb86 Merge branch 'release/4.8.2-alpha.4' 2019-11-16 07:50:43 +01:00
James Cole
9293674131 Merge tag '4.8.2-alpha.4' into develop
4.8.2-alpha.4
2019-11-16 07:50:43 +01:00
James Cole
e9172033bb New version. 2019-11-16 07:50:21 +01:00
James Cole
e54dc4c1b4 Also add channel. 2019-11-16 07:37:42 +01:00
James Cole
fcd6b89a43 Add header for current Firefly III version. 2019-11-16 06:59:09 +01:00
James Cole
67db25b2cf New robot config [skip ci] 2019-11-15 16:47:35 +01:00
James Cole
68863abbc7 Fix #2820 2019-11-15 16:37:23 +01:00
James Cole
26a4b6844e Fix #2826 2019-11-14 17:33:04 +01:00
James Cole
292fb3fbc8 Merge branch 'release/4.8.2-alpha.3' 2019-11-13 07:04:55 +01:00
James Cole
501efe507f Merge tag '4.8.2-alpha.3' into develop
4.8.2-alpha.3
2019-11-13 07:04:55 +01:00
James Cole
adc48ce094 Update some translations 2019-11-13 07:04:34 +01:00
James Cole
2a934edf4f Update composer file. 2019-11-13 07:01:47 +01:00
James Cole
4b9d1d23ca First steps for reconciliation edit. 2019-11-13 06:57:35 +01:00
James Cole
8a9e12c2b9 Version update. 2019-11-13 06:57:17 +01:00
James Cole
88f1adf650 Fix for issue with null amounts. 2019-11-11 18:25:35 +01:00
James Cole
8ce156cf93 Extra fix for #2807 2019-11-10 14:53:17 +01:00
James Cole
6843c81114 Merge pull request #2807 from timendum/develop
Fix account endpoint in create-edit.js
2019-11-10 14:50:10 +01:00
James Cole
f82d0dda0a Fixes for #2660 2019-11-10 07:26:49 +01:00
James Cole
d2a8f969d9 Wrong field to do int casting. 2019-11-10 07:26:10 +01:00
James Cole
c79ded2012 Always set latest version after update run. 2019-11-10 07:26:02 +01:00
James Cole
765e4e3c3b Always set latest version after update run. 2019-11-10 07:25:55 +01:00
James Cole
3c25148f3f Language fix for German UTF8 and a new Russian sentence 2019-11-09 20:14:34 +01:00
James Cole
dc0e8528c8 Catch import routines that submit integers. 2019-11-09 16:53:04 +01:00
James Cole
34e7455d67 Fix #2651 2019-11-09 16:50:13 +01:00
James Cole
9332808d7f Fix #2790 2019-11-09 15:30:52 +01:00
James Cole
16a4adcd07 Fix #2812 2019-11-09 15:01:48 +01:00
James Cole
140ccbce3f Fix #2811 2019-11-09 15:00:47 +01:00
James Cole
97c8594dc4 Fix #2796 2019-11-09 08:07:42 +01:00
James Cole
adc4b00f5d Fix #2806 2019-11-09 07:55:59 +01:00
Timendum
c1bdb629a8 Fix account endpoint in create-edit.js 2019-11-07 14:52:06 +01:00
James Cole
d8807e6ab7 Merge branch 'release/4.8.2-alpha.2' 2019-11-07 06:44:43 +01:00
James Cole
e3418b1bd2 Merge tag '4.8.2-alpha.2' into develop
4.8.2-alpha.2
2019-11-07 06:44:43 +01:00
James Cole
a7a76e32d6 New version. 2019-11-07 06:44:23 +01:00
James Cole
1294705809 Some new translations. 2019-11-07 06:43:29 +01:00
James Cole
bb449e1940 Fix alpha builds + version builds. 2019-11-07 06:14:45 +01:00
James Cole
828b9d32aa Fix #2805 2019-11-07 06:10:46 +01:00
James Cole
a67b0f78a4 Merge branch 'master' into develop 2019-11-05 18:09:28 +01:00
James Cole
5177f2bc87 Fix build script. 2019-11-05 18:09:07 +01:00
James Cole
f06e947706 Merge tag '4.8.2-alpha.1' into develop
4.8.2-alpha.1
2019-11-05 17:58:08 +01:00
James Cole
380f59dab2 Merge branch 'release/4.8.2-alpha.1' 2019-11-05 17:58:07 +01:00
James Cole
c558bc3247 Update composer file. 2019-11-05 17:56:43 +01:00
James Cole
25378b3f9a New translations. 2019-11-05 17:55:38 +01:00
James Cole
abf84e94b1 Final changelog details 2019-11-05 17:45:23 +01:00
James Cole
8baf29b835 Trigger a new build + fix a translation. 2019-11-03 13:35:34 +01:00
James Cole
d709a9489d Fix spaces in command. 2019-11-03 11:44:39 +01:00
James Cole
33ce7c0767 Release first alpha version to see how Travis responds. 2019-11-03 11:43:07 +01:00
James Cole
ec54ec22f6 Reconfigure build. 2019-11-03 11:38:21 +01:00
James Cole
706e722c6f Fix environment variables. 2019-11-03 07:20:32 +01:00
James Cole
58ec0c4add Change some environment variables for easier handling. 2019-11-03 07:19:12 +01:00
James Cole
88692f0058 Update metadata for new release. 2019-11-03 07:15:33 +01:00
James Cole
a8af0fa678 Remove "v" markers from translations. 2019-11-03 07:00:18 +01:00
James Cole
0bdd48ffec Add some debug info. 2019-11-02 08:28:49 +01:00
James Cole
766a82a983 Update translations. 2019-11-02 08:20:54 +01:00
James Cole
d749d550ee Error codes in Firefly III API 2019-11-02 08:19:50 +01:00
James Cole
2ea1852a94 Config out. 2019-11-02 07:21:40 +01:00
James Cole
4f44a42655 Add login for manifest. 2019-11-02 07:12:25 +01:00
James Cole
26ed00e7b5 Add correct path. 2019-11-02 07:04:11 +01:00
James Cole
51f25b2dce First triple arch build 2019-11-02 07:01:11 +01:00
James Cole
3fc653687c Fix files. 2019-11-01 06:15:02 +01:00
James Cole
4cd824f3b7 Fix Docker files. 2019-11-01 06:03:08 +01:00
James Cole
a6af263b50 Fix build and manifest. 2019-11-01 06:00:15 +01:00
James Cole
0844278eca Experimental setup with 3 jobs. 2019-11-01 05:57:41 +01:00
James Cole
1b63bfc3db Use central docker script. 2019-11-01 05:56:19 +01:00
James Cole
a4906a2d21 Fix version verify. 2019-11-01 05:51:25 +01:00
James Cole
c4256dd25b Let's see what ARM 64 will do. 2019-10-31 21:14:21 +01:00
James Cole
091ab17fdb Test 2019-10-31 21:11:57 +01:00
James Cole
02ddb95cf2 Second attempt. 2019-10-31 21:10:15 +01:00
James Cole
f2d43d71ad Test script that does nothing. 2019-10-31 21:07:58 +01:00
James Cole
af611b78de Make script executable. 2019-10-31 21:01:47 +01:00
James Cole
724a1b8b08 Script things. 2019-10-31 20:56:36 +01:00
James Cole
34e70c7446 Merge branch 'develop' of github.com:firefly-iii/firefly-iii into develop 2019-10-31 20:56:14 +01:00
James Cole
01f869f1b6 Let's see what happens. 2019-10-31 20:54:52 +01:00
James Cole
73a6db8eda Merge pull request #2786 from nicosomb/patch-1
Fixed documentation links
2019-10-31 19:40:24 +00:00
Nicolas Lœuillet
0bbc008848 Fixed documentation links 2019-10-31 15:37:12 +01:00
James Cole
5e61fa785e Fix #2771 2019-10-31 07:45:55 +01:00
James Cole
c131e6ad9b Fix #2780 2019-10-31 07:37:10 +01:00
James Cole
cbc92d89e1 Improve version handling. 2019-10-30 20:02:38 +01:00
James Cole
9a028d5002 Improve error handling in API. 2019-10-30 20:02:21 +01:00
James Cole
bed182cf13 Fix #2783 2019-10-29 18:36:03 +01:00
James Cole
d5afba6137 Fix order account. 2019-10-27 18:12:30 +01:00
James Cole
6b4b69b695 Fix #2774 2019-10-26 17:06:46 +02:00
James Cole
b528fa2e5d Merge tag '4.8.1.8' into develop
4.8.1.8
2019-10-26 16:56:43 +02:00
James Cole
f4b9f81e71 Merge branch 'hotfix/4.8.1.8' 2019-10-26 16:56:42 +02:00
James Cole
ca37d782ed Fix #2773 2019-10-26 16:56:30 +02:00
James Cole
f7c34db39b New translations. 2019-10-26 16:54:26 +02:00
James Cole
0d072b4ed9 Merge pull request #2772 from dguhl/2695-localise-api-errors
Fix issue #2695
2019-10-26 14:33:07 +00:00
Dominic Guhl
13a29a66c8 worked in feedback by JC5 2019-10-26 16:29:04 +02:00
James Cole
cfd9828438 Fix #2773 2019-10-26 16:21:12 +02:00
Dominic Guhl
b4d565400e Issue 2695
Introduces localisation for API errors
2019-10-26 15:07:54 +02:00
James Cole
be0e2bf6a7 Firefly III can now handle "channels" in its releases. 2019-10-26 14:42:51 +02:00
James Cole
64a2f22b13 Merge branch 'release/4.8.1.7' 2019-10-26 08:07:10 +02:00
James Cole
778e0bcbae Merge tag '4.8.1.7' into develop
4.8.1.7
2019-10-26 08:07:10 +02:00
James Cole
92a1f12f6c Version fix in changelog. 2019-10-26 08:02:05 +02:00
James Cole
ea0a440de0 New version. 2019-10-26 07:57:40 +02:00
James Cole
92271ffe66 New translations 2019-10-26 07:54:59 +02:00
James Cole
0499433cea Update composer file. 2019-10-26 07:49:59 +02:00
James Cole
dcdecfbc64 Fixed an issue with creating and editing transactions. 2019-10-26 07:49:51 +02:00
James Cole
8b11afb83f A new endpoint that allows you to search for transfers. 2019-10-26 07:49:36 +02:00
James Cole
6823adc976 Firefly III can automatically stop duplicate transactions from being created. 2019-10-26 07:49:12 +02:00
James Cole
7cfa916c61 Merge branch 'release/4.8.1.6' 2019-10-24 18:38:20 +02:00
James Cole
2cf000a9fd Merge tag '4.8.1.6' into develop
4.8.1.6
2019-10-24 18:38:20 +02:00
James Cole
b7862b7d69 Update readme thing. [skip ci] 2019-10-24 18:32:57 +02:00
James Cole
4a11d65589 Update libraries. 2019-10-24 18:26:43 +02:00
James Cole
67ff88b24c New translations. 2019-10-24 18:24:00 +02:00
James Cole
d963ba0a2e Fix #2758 2019-10-24 18:13:43 +02:00
James Cole
b8c8aabbf4 Empty foreign amount should not be a problem. 2019-10-24 10:14:08 +02:00
James Cole
a39bdc9cb0 Fix routes. 2019-10-24 10:13:52 +02:00
James Cole
18310641aa Update version. 2019-10-22 07:10:14 +02:00
James Cole
8386ab79f6 Fix issue with double question marks in URI 2019-10-22 07:09:40 +02:00
James Cole
ffdeae91d7 Fix issue with double question marks in URI 2019-10-22 07:03:18 +02:00
James Cole
73e3b9fe67 Add debug for #2701 2019-10-22 06:09:34 +02:00
James Cole
6a981fb691 Fix #2758 2019-10-22 05:59:56 +02:00
James Cole
576f2f2530 Fix #2757 2019-10-22 05:58:35 +02:00
James Cole
27668769cb Fix #2756 2019-10-22 05:56:37 +02:00
James Cole
def6ae6167 Merge tag '4.8.1.5' into develop
4.8.1.5
2019-10-21 20:09:56 +02:00
James Cole
9f1fc0c2b8 Merge branch 'release/4.8.1.5' 2019-10-21 20:09:54 +02:00
James Cole
5456a64d9f More readme updates. 2019-10-21 20:08:38 +02:00
James Cole
0e636e1ec1 New readme. 2019-10-21 20:03:14 +02:00
James Cole
bc469e8d52 Update composer (again) 2019-10-21 19:54:37 +02:00
James Cole
4ba650afd7 Update composer file because of a bug in the 2FA package. 2019-10-21 19:08:51 +02:00
James Cole
54b42f0e46 Update changelog and composer file. 2019-10-21 18:51:01 +02:00
James Cole
516f2a1232 Updated translations. 2019-10-21 18:48:04 +02:00
James Cole
4b10cff5c2 Fix meta data for new release. 2019-10-21 18:42:04 +02:00
James Cole
50d3c36b6a Fix #2752 2019-10-21 18:32:13 +02:00
James Cole
3e40a6cf3d Fix #2755 2019-10-21 18:23:07 +02:00
James Cole
004d4a2d22 Fix #2746 2019-10-21 18:22:47 +02:00
James Cole
516ef79130 Fixes for #2753 2019-10-20 16:17:43 +02:00
James Cole
0135ae425f Fix #2754 2019-10-20 16:02:30 +02:00
James Cole
6c8a6e6823 Fix #2734 2019-10-19 19:18:57 +02:00
James Cole
6efe5cfd4d Fix #2694 2019-10-19 19:17:14 +02:00
James Cole
2d720f72bd Fix #2728 2019-10-19 19:00:16 +02:00
James Cole
0708ea875a Always verify keys, should also help with Heroku instances. 2019-10-19 09:37:35 +02:00
James Cole
0d924990c8 iOS compatible fix #2734 2019-10-14 19:45:04 +02:00
James Cole
4d67b4d118 iOS compatible fix #2734 2019-10-14 19:22:54 +02:00
James Cole
d57c5d3a20 Add copy button. Fixes #2734 2019-10-14 19:08:08 +02:00
James Cole
8ee1b08c57 Possible fix for issue reported over email. 2019-10-14 16:34:52 +02:00
James Cole
ee625a9c3f Update language and meta files. 2019-10-13 11:58:40 +02:00
James Cole
3e3729982b Add some debug info 2019-10-13 11:50:40 +02:00
James Cole
49933dae17 Restore some comments for easier debugging 2019-10-13 11:50:28 +02:00
James Cole
05a5782d5d Remove API throttle. 2019-10-13 11:50:17 +02:00
James Cole
4ad601f29d Expand API so you can also submit IBAN, BIC or number for new accounts 2019-10-13 11:50:04 +02:00
James Cole
79debe4941 Issue in experimental search 2019-10-13 11:47:38 +02:00
James Cole
98ca25ebea Fix #2731 2019-10-13 11:45:31 +02:00
James Cole
004f725993 Fix too strict CSP headers #2727 2019-10-12 04:04:03 +02:00
James Cole
9ed32ad227 Merge pull request #2724 from danger89/clean_files_only
Clean-up only
2019-10-12 03:53:27 +02:00
Melroy van den Berg
1ac5c4f670 clean-up only 2019-10-11 16:29:08 +00:00
James Cole
24e7260fe7 Temp fix for #2701 2019-10-10 21:02:56 +02:00
James Cole
5e9e749179 Fix #2716 2019-10-10 20:58:13 +02:00
James Cole
460906fdfe Fix search query. #2713 2019-10-10 20:50:40 +02:00
James Cole
22f63fd951 Remove references to unused Docker variable 2019-10-10 20:36:55 +02:00
James Cole
de19bfe448 Link to base image #2655 2019-10-09 05:46:21 +02:00
James Cole
378bbf20de Fix #2699 2019-10-06 20:09:27 +02:00
James Cole
32ecac3b1f Fix #2698 2019-10-06 07:03:34 +02:00
James Cole
fee0eb68d5 Fix translation things. 2019-10-05 16:43:24 +02:00
James Cole
bb6aa568ba Fix #2540 2019-10-05 13:11:12 +02:00
James Cole
2580927439 Fall back to English if the string does not exist. #2540 2019-10-05 13:05:02 +02:00
James Cole
46afdc5418 Continued attempt to translate form #2540 2019-10-05 12:44:05 +02:00
James Cole
9d82e3cfac Broken, to be fixed. 2019-10-05 11:29:57 +02:00
James Cole
2e265edec6 First attempt to translate form #2540 2019-10-05 11:17:44 +02:00
James Cole
9ef1af176d Restore the correct copyright owners. 2019-10-05 10:10:11 +02:00
James Cole
c7d918499d Merge tag '4.8.1.4' into develop
4.8.1.4
2019-10-05 06:59:32 +02:00
428 changed files with 14100 additions and 13045 deletions

View File

@@ -1,20 +0,0 @@
#!/usr/bin/env bash
# build image
echo "$DOCKER_PASSWORD" | docker login -u "$DOCKER_USERNAME" --password-stdin
if [ "$TRAVIS_BRANCH" == "develop" ]; then
echo "Build develop amd64"
docker build -t jc5x/firefly-iii:develop-amd64 -f Dockerfile.amd64 .
docker tag jc5x/firefly-iii:develop-amd64 jc5x/firefly-iii:develop-$VERSION-amd64
docker push jc5x/firefly-iii:develop-amd64
docker push jc5x/firefly-iii:develop-$VERSION-amd64
fi
if [ "$TRAVIS_BRANCH" == "master" ]; then
echo "Build master amd64"
docker build -t jc5x/firefly-iii:latest-amd64 -f Dockerfile.amd64 .
docker tag jc5x/firefly-iii:latest-amd64 jc5x/firefly-iii:release-$VERSION-amd64
docker push jc5x/firefly-iii:latest-amd64
docker push jc5x/firefly-iii:release-$VERSION-amd64
fi

View File

@@ -1,29 +0,0 @@
#!/usr/bin/env bash
docker run --rm --privileged multiarch/qemu-user-static:register --reset
# get qemu-arm-static binary
mkdir tmp
pushd tmp && \
curl -L -o qemu-arm-static.tar.gz https://github.com/multiarch/qemu-user-static/releases/download/v2.6.0/qemu-arm-static.tar.gz && \
tar xzf qemu-arm-static.tar.gz && \
popd
# build image
echo "$DOCKER_PASSWORD" | docker login -u "$DOCKER_USERNAME" --password-stdin
if [ "$TRAVIS_BRANCH" == "develop" ]; then
echo "Build develop arm"
docker build --tag jc5x/firefly-iii:develop-arm --file Dockerfile.arm .
docker tag jc5x/firefly-iii:develop-arm jc5x/firefly-iii:develop-$VERSION-arm
docker push jc5x/firefly-iii:develop-arm
docker push jc5x/firefly-iii:develop-$VERSION-arm
fi
if [ "$TRAVIS_BRANCH" == "master" ]; then
echo "Build master arm"
docker build --tag jc5x/firefly-iii:latest-arm --file Dockerfile.arm .
docker tag jc5x/firefly-iii:latest-arm jc5x/firefly-iii:release-$VERSION-arm
docker push jc5x/firefly-iii:latest-arm
docker push jc5x/firefly-iii:release-$VERSION-arm
fi

View File

@@ -18,12 +18,12 @@ mkdir -p $FIREFLY_PATH/storage/framework/views/v2
mkdir -p $FIREFLY_PATH/storage/logs
mkdir -p $FIREFLY_PATH/storage/upload
echo "Touch DB file (if SQLlite)..."
if [[ $DB_CONNECTION == "sqlite" ]]
then
if [[ $DKR_CHECK_SQLITE != "false" ]]; then
echo "Touch DB file (if SQLlite)..."
if [[ $DB_CONNECTION == "sqlite" ]]; then
touch $FIREFLY_PATH/storage/database/database.sqlite
echo "Touched!"
fi
fi
# make sure we own the volumes:
@@ -41,7 +41,7 @@ composer dump-autoload
echo "Discover packages..."
php artisan package:discover
echo "Run various artisan commands..."
echo "Wait for the database."
if [[ -z "$DB_PORT" ]]; then
if [[ $DB_CONNECTION == "pgsql" ]]; then
DB_PORT=5432
@@ -50,54 +50,108 @@ if [[ -z "$DB_PORT" ]]; then
fi
fi
if [[ ! -z "$DB_PORT" ]]; then
$FIREFLY_PATH/.deploy/docker/wait-for-it.sh "${DB_HOST}:${DB_PORT}" -- echo "db is up. Time to execute artisan commands"
$FIREFLY_PATH/.deploy/docker/wait-for-it.sh "${DB_HOST}:${DB_PORT}" -t 60 -- echo "DB is up. Time to execute artisan commands."
fi
#env $(grep -v "^\#" .env | xargs)
echo "Run various artisan commands..."
php artisan cache:clear
php artisan migrate --seed
php artisan firefly-iii:decrypt-all
if [[ $DKR_RUN_MIGRATION == "false" ]]; then
echo "Will NOT run migration commands."
fi
if [[ $DKR_RUN_MIGRATION != "false" ]]; then
echo "Running migration commands..."
php artisan firefly-iii:create-database
php artisan migrate --seed --no-interaction --force
php artisan firefly-iii:decrypt-all
fi
# there are 13 upgrade commands
php artisan firefly-iii:transaction-identifiers
php artisan firefly-iii:migrate-to-groups
php artisan firefly-iii:account-currencies
php artisan firefly-iii:transfer-currencies
php artisan firefly-iii:other-currencies
php artisan firefly-iii:migrate-notes
php artisan firefly-iii:migrate-attachments
php artisan firefly-iii:bills-to-rules
php artisan firefly-iii:bl-currency
php artisan firefly-iii:cc-liabilities
php artisan firefly-iii:back-to-journals
php artisan firefly-iii:rename-account-meta
php artisan firefly-iii:migrate-recurrence-meta
if [[ $DKR_RUN_UPGRADE == "false" ]]; then
echo 'Will NOT run upgrade commands.'
fi
if [[ $DKR_RUN_UPGRADE != "false" ]]; then
echo 'Running upgrade commands...'
php artisan firefly-iii:transaction-identifiers
php artisan firefly-iii:migrate-to-groups
php artisan firefly-iii:account-currencies
php artisan firefly-iii:transfer-currencies
php artisan firefly-iii:other-currencies
php artisan firefly-iii:migrate-notes
php artisan firefly-iii:migrate-attachments
php artisan firefly-iii:bills-to-rules
php artisan firefly-iii:bl-currency
php artisan firefly-iii:cc-liabilities
php artisan firefly-iii:back-to-journals
php artisan firefly-iii:rename-account-meta
php artisan firefly-iii:migrate-recurrence-meta
fi
# there are 15 verify commands
php artisan firefly-iii:fix-piggies
php artisan firefly-iii:create-link-types
php artisan firefly-iii:create-access-tokens
php artisan firefly-iii:remove-bills
php artisan firefly-iii:enable-currencies
php artisan firefly-iii:fix-transfer-budgets
php artisan firefly-iii:fix-uneven-amount
php artisan firefly-iii:delete-zero-amount
php artisan firefly-iii:delete-orphaned-transactions
php artisan firefly-iii:delete-empty-journals
php artisan firefly-iii:delete-empty-groups
php artisan firefly-iii:fix-account-types
php artisan firefly-iii:rename-meta-fields
php artisan firefly-iii:fix-ob-currencies
php artisan firefly-iii:fix-long-descriptions
if [[ $DKR_RUN_VERIFY == "false" ]]; then
echo 'Will NOT run verification commands.'
fi
if [[ $DKR_RUN_VERIFY != "false" ]]; then
echo 'Running verification commands...'
php artisan firefly-iii:fix-piggies
php artisan firefly-iii:create-link-types
php artisan firefly-iii:create-access-tokens
php artisan firefly-iii:remove-bills
php artisan firefly-iii:enable-currencies
php artisan firefly-iii:fix-transfer-budgets
php artisan firefly-iii:fix-uneven-amount
php artisan firefly-iii:delete-zero-amount
php artisan firefly-iii:delete-orphaned-transactions
php artisan firefly-iii:delete-empty-journals
php artisan firefly-iii:delete-empty-groups
php artisan firefly-iii:fix-account-types
php artisan firefly-iii:rename-meta-fields
php artisan firefly-iii:fix-ob-currencies
php artisan firefly-iii:fix-long-descriptions
fi
# report commands
php artisan firefly-iii:report-empty-objects
php artisan firefly-iii:report-sum
if [[ $DKR_RUN_REPORT == "false" ]]; then
echo 'Will NOT run report commands.'
fi
if [[ $DKR_RUN_REPORT != "false" ]]; then
echo 'Running report commands...'
php artisan firefly-iii:report-empty-objects
php artisan firefly-iii:report-sum
fi
php artisan firefly-iii:restore-oauth-keys
php artisan passport:install
if [[ $DKR_RUN_REPORT == "false" ]]; then
echo 'Will NOT generate new OAuth keys.'
fi
if [[ $DKR_RUN_PASSPORT_INSTALL != "false" ]]; then
echo 'Generating new OAuth keys...'
php artisan passport:install
fi
php artisan firefly-iii:set-latest-version --james-is-cool
php artisan cache:clear
# make sure we own everything
echo "Run chown on ${FIREFLY_PATH}"
chown -R www-data:www-data -R $FIREFLY_PATH
php artisan firefly:instructions install
echo "DKR_CHECK_SQLITE '$DKR_CHECK_SQLITE'"
echo "DKR_RUN_MIGRATION '$DKR_RUN_MIGRATION'"
echo "DKR_RUN_UPGRADE '$DKR_RUN_UPGRADE'"
echo "DKR_RUN_VERIFY '$DKR_RUN_VERIFY'"
echo "DKR_RUN_REPORT '$DKR_RUN_REPORT'"
echo "DKR_RUN_PASSPORT_INSTALL '$DKR_RUN_PASSPORT_INSTALL'"
echo "Go!"
exec apache2-foreground

View File

@@ -1,35 +1,162 @@
#!/usr/bin/env bash
if [ "$TRAVIS_BRANCH" == "develop" ]; then
echo '{"experimental":true}' | sudo tee /etc/docker/daemon.json
mkdir $HOME/.docker
touch $HOME/.docker/config.json
echo '{"experimental":"enabled"}' | sudo tee $HOME/.docker/config.json
sudo service docker restart
echo "$DOCKER_PASSWORD" | docker login -u "$DOCKER_USERNAME" --password-stdin
VERSION_TARGET=jc5x/firefly-iii:release-$VERSION
# if the github branch is develop, only push the 'develop' tag
if [ $TRAVIS_BRANCH == "develop" ]; then
TARGET=jc5x/firefly-iii:develop
ARM=jc5x/firefly-iii:develop-arm
AMD=jc5x/firefly-iii:develop-amd64
ARM32=jc5x/firefly-iii:develop-arm
ARM64=jc5x/firefly-iii:develop-arm64
AMD64=jc5x/firefly-iii:develop-amd64
docker manifest create $TARGET $AMD $ARM
docker manifest annotate $TARGET $ARM --arch arm --os linux
docker manifest annotate $TARGET $AMD --arch amd64 --os linux
echo "GitHub branch is $TRAVIS_BRANCH."
echo "Push develop-* builds to $TARGET"
docker manifest create $TARGET $ARM32 $ARM64 $AMD64
docker manifest annotate $TARGET $ARM32 --arch arm --os linux
docker manifest annotate $TARGET $ARM64 --arch arm64 --os linux
docker manifest annotate $TARGET $AMD64 --arch amd64 --os linux
docker manifest push $TARGET
fi
echo "The version is $VERSION"
# if branch = master AND channel = alpha, push 'alpha'
if [ $TRAVIS_BRANCH == "master" ] && [ $CHANNEL == "alpha" ]; then
TARGET=jc5x/firefly-iii:alpha
ARM32=jc5x/firefly-iii:alpha-arm
ARM64=jc5x/firefly-iii:alpha-arm64
AMD64=jc5x/firefly-iii:alpha-amd64
echo "GitHub branch is $TRAVIS_BRANCH."
echo "Channel is $CHANNEL."
echo "Push alpha-* builds to $TARGET"
docker manifest create $TARGET $ARM32 $ARM64 $AMD64
docker manifest annotate $TARGET $ARM32 --arch arm --os linux
docker manifest annotate $TARGET $ARM64 --arch arm64 --os linux
docker manifest annotate $TARGET $AMD64 --arch amd64 --os linux
docker manifest push $TARGET
echo "Push alpha-* builds to $VERSION_TARGET"
docker manifest create $VERSION_TARGET $ARM32 $ARM64 $AMD64
docker manifest annotate $VERSION_TARGET $ARM32 --arch arm --os linux
docker manifest annotate $VERSION_TARGET $ARM64 --arch arm64 --os linux
docker manifest annotate $VERSION_TARGET $AMD64 --arch amd64 --os linux
docker manifest push $VERSION_TARGET
fi
# if branch is master and channel is alpha, push 'alpha' and 'beta'.
if [ $TRAVIS_BRANCH == "master" ] && [ $CHANNEL == "beta" ]; then
TARGET=jc5x/firefly-iii:alpha
ARM32=jc5x/firefly-iii:beta-arm
ARM64=jc5x/firefly-iii:beta-arm64
AMD64=jc5x/firefly-iii:beta-amd64
echo "GitHub branch is $TRAVIS_BRANCH."
echo "Channel is $CHANNEL."
echo "Push beta-* builds to $TARGET"
docker manifest create $TARGET $ARM32 $ARM64 $AMD64
docker manifest annotate $TARGET $ARM32 --arch arm --os linux
docker manifest annotate $TARGET $ARM64 --arch arm64 --os linux
docker manifest annotate $TARGET $AMD64 --arch amd64 --os linux
docker manifest push $TARGET
TARGET=jc5x/firefly-iii:beta
ARM32=jc5x/firefly-iii:beta-arm
ARM64=jc5x/firefly-iii:beta-arm64
AMD64=jc5x/firefly-iii:beta-amd64
echo "Push beta-* builds to $TARGET"
docker manifest create $TARGET $ARM32 $ARM64 $AMD64
docker manifest annotate $TARGET $ARM32 --arch arm --os linux
docker manifest annotate $TARGET $ARM64 --arch arm64 --os linux
docker manifest annotate $TARGET $AMD64 --arch amd64 --os linux
docker manifest push $TARGET
echo "Push beta-* builds to $VERSION_TARGET"
docker manifest create $VERSION_TARGET $ARM32 $ARM64 $AMD64
docker manifest annotate $VERSION_TARGET $ARM32 --arch arm --os linux
docker manifest annotate $VERSION_TARGET $ARM64 --arch arm64 --os linux
docker manifest annotate $VERSION_TARGET $AMD64 --arch amd64 --os linux
docker manifest push $VERSION_TARGET
fi
# if branch is master and channel is stable, push 'alpha' and 'beta' and 'stable'.
if [ $TRAVIS_BRANCH == "master" ] && [ $CHANNEL == "stable" ]; then
TARGET=jc5x/firefly-iii:alpha
ARM32=jc5x/firefly-iii:stable-arm
ARM64=jc5x/firefly-iii:stable-arm64
AMD64=jc5x/firefly-iii:stable-amd64
echo "GitHub branch is $TRAVIS_BRANCH."
echo "Channel is $CHANNEL."
echo "Push stable-* builds to $TARGET"
docker manifest create $TARGET $ARM32 $ARM64 $AMD64
docker manifest annotate $TARGET $ARM32 --arch arm --os linux
docker manifest annotate $TARGET $ARM64 --arch arm64 --os linux
docker manifest annotate $TARGET $AMD64 --arch amd64 --os linux
docker manifest push $TARGET
TARGET=jc5x/firefly-iii:beta
ARM32=jc5x/firefly-iii:stable-arm
ARM64=jc5x/firefly-iii:stable-arm64
AMD64=jc5x/firefly-iii:stable-amd64
echo "Push stable-* builds to $TARGET"
docker manifest create $TARGET $ARM32 $ARM64 $AMD64
docker manifest annotate $TARGET $ARM32 --arch arm --os linux
docker manifest annotate $TARGET $ARM64 --arch arm64 --os linux
docker manifest annotate $TARGET $AMD64 --arch amd64 --os linux
docker manifest push $TARGET
TARGET=jc5x/firefly-iii:stable
ARM32=jc5x/firefly-iii:stable-arm
ARM64=jc5x/firefly-iii:stable-arm64
AMD64=jc5x/firefly-iii:stable-amd64
echo "Push stable-* builds to $TARGET"
docker manifest create $TARGET $ARM32 $ARM64 $AMD64
docker manifest annotate $TARGET $ARM32 --arch arm --os linux
docker manifest annotate $TARGET $ARM64 --arch arm64 --os linux
docker manifest annotate $TARGET $AMD64 --arch amd64 --os linux
docker manifest push $TARGET
if [ "$TRAVIS_BRANCH" == "master" ]; then
TARGET=jc5x/firefly-iii:latest
ARM=jc5x/firefly-iii:latest-arm
AMD=jc5x/firefly-iii:latest-amd64
ARM32=jc5x/firefly-iii:stable-arm
ARM64=jc5x/firefly-iii:stable-arm64
AMD64=jc5x/firefly-iii:stable-amd64
docker manifest create $TARGET $AMD $ARM
docker manifest annotate $TARGET $ARM --arch arm --os linux
docker manifest annotate $TARGET $AMD --arch amd64 --os linux
echo "Push stable-* builds to $TARGET"
docker manifest create $TARGET $ARM32 $ARM64 $AMD64
docker manifest annotate $TARGET $ARM32 --arch arm --os linux
docker manifest annotate $TARGET $ARM64 --arch arm64 --os linux
docker manifest annotate $TARGET $AMD64 --arch amd64 --os linux
docker manifest push $TARGET
# and another one for version specific:
TARGET=jc5x/firefly-iii:release-$VERSION
ARM=jc5x/firefly-iii:release-$VERSION-arm
AMD=jc5x/firefly-iii:release-$VERSION-amd64
echo "Push stable-* builds to $VERSION_TARGET"
docker manifest create $TARGET $AMD $ARM
docker manifest annotate $TARGET $ARM --arch arm --os linux
docker manifest annotate $TARGET $AMD --arch amd64 --os linux
docker manifest push $TARGET
docker manifest create $VERSION_TARGET $ARM32 $ARM64 $AMD64
docker manifest annotate $VERSION_TARGET $ARM32 --arch arm --os linux
docker manifest annotate $VERSION_TARGET $ARM64 --arch arm64 --os linux
docker manifest annotate $VERSION_TARGET $AMD64 --arch amd64 --os linux
docker manifest push $VERSION_TARGET
fi
echo 'Done!'
# done!

103
.deploy/docker/travis.sh Executable file
View File

@@ -0,0 +1,103 @@
#!/usr/bin/env bash
echo "travis.sh: I am building channel ${CHANNEL} for version ${VERSION} on architecture ${ARCH}, branch $TRAVIS_BRANCH."
echo '{"experimental":true}' | sudo tee /etc/docker/daemon.json
mkdir $HOME/.docker
touch $HOME/.docker/config.json
echo '{"experimental":"enabled"}' | sudo tee $HOME/.docker/config.json
sudo service docker restart
# First build amd64 image:
echo "$DOCKER_PASSWORD" | docker login -u "$DOCKER_USERNAME" --password-stdin
if [ $ARCH == "arm" ]; then
echo "Because architecture is $ARCH running some extra commands."
docker run --rm --privileged multiarch/qemu-user-static:register --reset
# get qemu-arm-static binary
mkdir tmp
pushd tmp && \
curl -L -o qemu-arm-static.tar.gz https://github.com/multiarch/qemu-user-static/releases/download/v2.6.0/qemu-arm-static.tar.gz && \
tar xzf qemu-arm-static.tar.gz && \
popd
fi
# if the github branch is develop, build and push develop. Don't push a version tag anymore.
if [ $TRAVIS_BRANCH == "develop" ]; then
LABEL=jc5x/firefly-iii:develop-$ARCH
echo "GitHub branch is $TRAVIS_BRANCH. Will build and push $LABEL"
docker build -t $LABEL -f Dockerfile.$ARCH .
docker push $LABEL
fi
# if branch = master AND channel = alpha, build and push 'alpha'
if [ $TRAVIS_BRANCH == "master" ] && [ $CHANNEL == "alpha" ]; then
LABEL=jc5x/firefly-iii:alpha-$ARCH
echo "GitHub branch is $TRAVIS_BRANCH and channel is $CHANNEL. Will build and push $LABEL"
docker build -t $LABEL -f Dockerfile.$ARCH .
docker push $LABEL
fi
# if branch is master and channel is alpha, build and push 'alpha' and 'beta'.
if [ $TRAVIS_BRANCH == "master" ] && [ $CHANNEL == "beta" ]; then
LABEL=jc5x/firefly-iii:beta-$ARCH
echo "GitHub branch is $TRAVIS_BRANCH and channel is $CHANNEL. Will build and push $LABEL"
docker build -t $LABEL -f Dockerfile.$ARCH .
docker push $LABEL
# then tag as alpha and push:
docker tag $LABEL jc5x/firefly-iii:alpha-$ARCH
docker push jc5x/firefly-iii:alpha-$ARCH
echo "Also tagged $LABEL as jc5x/firefly-iii:alpha-$ARCH and pushed"
fi
# if branch is master and channel is stable, push 'alpha' and 'beta' and 'stable'.
if [ $TRAVIS_BRANCH == "master" ] && [ $CHANNEL == "stable" ]; then
# first build stable
LABEL=jc5x/firefly-iii:stable-$ARCH
echo "GitHub branch is $TRAVIS_BRANCH and channel is $CHANNEL. Will build and push $LABEL"
docker build -t $LABEL -f Dockerfile.$ARCH .
docker push $LABEL
# then tag as beta and push:
docker tag $LABEL jc5x/firefly-iii:beta-$ARCH
docker push jc5x/firefly-iii:beta-$ARCH
echo "Also tagged $LABEL as jc5x/firefly-iii:beta-$ARCH and pushed"
# then tag as alpha and push:
docker tag $LABEL jc5x/firefly-iii:alpha-$ARCH
docker push jc5x/firefly-iii:alpha-$ARCH
echo "Also tagged $LABEL as jc5x/firefly-iii:alpha-$ARCH and pushed"
# then tag as latest and push:
docker tag $LABEL jc5x/firefly-iii:latest-$ARCH
docker push jc5x/firefly-iii:latest-$ARCH
echo "Also tagged $LABEL as jc5x/firefly-iii:latest-$ARCH and pushed"
fi
# push to channel 'version' if master + alpha
if [ $TRAVIS_BRANCH == "master" ] && [ $CHANNEL == "alpha"]; then
LABEL=jc5x/firefly-iii:version-$VERSION-$ARCH
echo "GitHub branch is $TRAVIS_BRANCH and channel is $CHANNEL. Will also push alpha as $LABEL"
docker tag jc5x/firefly-iii:alpha-$ARCH $LABEL
docker push $LABEL
fi
# push to channel 'version' if master + beta
if [ $TRAVIS_BRANCH == "master" ] && [ $CHANNEL == "beta"]; then
LABEL=jc5x/firefly-iii:version-$VERSION-$ARCH
echo "GitHub branch is $TRAVIS_BRANCH and channel is $CHANNEL. Will also push beta as $LABEL"
docker tag jc5x/firefly-iii:beta-$ARCH $LABEL
docker push $LABEL
fi
# push to channel 'version' if master + stable
if [ $TRAVIS_BRANCH == "master" ] && [ $CHANNEL == "stable"]; then
LABEL=jc5x/firefly-iii:version-$VERSION-$ARCH
echo "GitHub branch is $TRAVIS_BRANCH and channel is $CHANNEL. Will also push beta as $LABEL"
docker tag jc5x/firefly-iii:stable-$ARCH $LABEL
docker push $LABEL
fi
echo "Done!"

View File

@@ -1,26 +0,0 @@
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

@@ -176,7 +176,6 @@ PUSHER_SECRET=
PUSHER_ID=
DEMO_USERNAME=
DEMO_PASSWORD=
IS_DOCKER=false
IS_SANDSTORM=false
IS_HEROKU=true
BUNQ_USE_SANDBOX=false

View File

@@ -11,4 +11,5 @@ pt_BR
ro_RO
ru_RU
hu_HU
el_GR
el_GR
sv_SE

View File

@@ -0,0 +1,99 @@
apiVersion: v1
kind: Service
metadata:
name: firefly-iii
labels:
app: firefly-iii
spec:
ports:
- port: 80
selector:
app: firefly-iii
tier: frontend
type: LoadBalancer
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: firefly-iii-export-claim
labels:
app: firefly-iii
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 20Gi
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: firefly-iii-upload-claim
labels:
app: firefly-iii
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 20Gi
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: firefly-iii
labels:
app: firefly-iii
spec:
selector:
matchLabels:
app: firefly-iii
tier: frontend
strategy:
type: Recreate
template:
metadata:
labels:
app: firefly-iii
tier: frontend
spec:
containers:
- image: jc5x/firefly-iii
name: firefly-iii
env:
- name: APP_ENV
value: "local"
- name: APP_KEY
valueFrom:
secretKeyRef:
name: firefly-iii-secrets
key: app_key
- name: DB_HOST
value: firefly-iii-mysql
- name: DB_CONNECTION
value: mysql
- name: DB_DATABASE
value: "fireflyiii"
- name: DB_USERNAME
value: "root"
- name: DB_PASSWORD
valueFrom:
secretKeyRef:
name: firefly-iii-secrets
key: db_password
ports:
- containerPort: 80
name: firefly-iii
volumeMounts:
- mountPath: "/var/www/firefly-iii/storage/export"
name: firefly-iii-export
- mountPath: "/var/www/firefly-iii/storage/upload"
name: firefly-iii-upload
imagePullPolicy: Always
volumes:
- name: firefly-iii-export
persistentVolumeClaim:
claimName: firefly-iii-export-claim
- name: firefly-iii-upload
persistentVolumeClaim:
claimName: firefly-iii-upload-claim

View File

@@ -1,82 +0,0 @@
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: APP_ENV
value: "local"
- name: APP_KEY
value: "S0m3R@nd0mString0f32Ch@rsEx@ct1y"
- name: DB_HOST
value: "172.17.0.9"
- name: DB_NAME
value: "firefly_db"
- name: DB_USER
value: "firefly_db"
- name: 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,8 @@
resources:
- mysql.yaml
- firefly-iii.yaml
secretGenerator:
- name: firefly-iii-secrets
literals:
- db_password=CHANGEMECHANGEME
- app_key=CHANGEMECHANGEMECHANGEMECHANGEME

View File

@@ -0,0 +1,65 @@
apiVersion: v1
kind: Service
metadata:
name: firefly-iii-mysql
labels:
app: firefly-iii
spec:
ports:
- port: 3306
selector:
app: firefly-iii
tier: mysql
clusterIP: None
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: mysql-pv-claim
labels:
app: firefly-iii
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 20Gi
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: firefly-iii-mysql
labels:
app: firefly-iii
spec:
selector:
matchLabels:
app: firefly-iii
tier: mysql
strategy:
type: Recreate
template:
metadata:
labels:
app: firefly-iii
tier: mysql
spec:
containers:
- image: mysql:5.6
name: mysql
env:
- name: MYSQL_ROOT_PASSWORD
valueFrom:
secretKeyRef:
name: firefly-iii-secrets
key: db_password
ports:
- containerPort: 3306
name: mysql
volumeMounts:
- name: mysql-persistent-storage
mountPath: /var/lib/mysql
volumes:
- name: mysql-persistent-storage
persistentVolumeClaim:
claimName: mysql-pv-claim

View File

@@ -1,49 +0,0 @@
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

@@ -171,7 +171,6 @@ PUSHER_SECRET=
PUSHER_ID=
DEMO_USERNAME=
DEMO_PASSWORD=
IS_DOCKER=false
IS_SANDSTORM=true
IS_HEROKU=false
BUNQ_USE_SANDBOX=false

View File

@@ -26,10 +26,13 @@ APP_URL=http://localhost
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/.
# - Docker + versions <= 4.8.1.8 and before: use "stdout"
# - Docker + versions > 4.8.1.8: use "docker_out"
# - For everything else, use 'daily'
# Several other options exist. You can use 'single' for one big fat error log (not recommended).
# Also available are 'syslog', 'errorlog' and 'stdout' which will log to the system itself.
LOG_CHANNEL=daily
LOG_CHANNEL=stdout
# Log level. You can set this from least severe to most severe:
# debug, info, notice, warning, error, critical, alert, emergency
@@ -38,7 +41,7 @@ LOG_CHANNEL=daily
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
# For other database types, please see the FAQ: https://docs.firefly-iii.org/support/faq
DB_CONNECTION=pgsql
DB_HOST=firefly_iii_db
DB_PORT=5432
@@ -57,18 +60,12 @@ PGSQL_SSL_CRL_FILE=null
CACHE_DRIVER=file
SESSION_DRIVER=file
# You can configure another file storage backend if you cannot use the local storage option.
# To set this up, fill in the following variables. The upload path is used to store uploaded
# files and the export path is to store exported data (before download).
SFTP_HOST=
SFTP_PORT=
SFTP_UPLOAD_PATH=
SFTP_EXPORT_PATH=
# SFTP uses either the username/password combination or the private key to authenticate.
SFTP_USERNAME=
SFTP_PASSWORD=
SFTP_PRIV_KEY=
# If you set either of these to 'redis', you might want to update these settings too
REDIS_HOST=127.0.0.1
REDIS_PASSWORD=null
REDIS_PORT=6379
REDIS_DB="0" # always use quotes
REDIS_CACHE_DB="1"
# Cookie settings. Should not be necessary to change these.
COOKIE_PATH="/"
@@ -76,7 +73,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
# For instructions, see: https://docs.firefly-iii.org/advanced-installation/email
MAIL_DRIVER=log
MAIL_HOST=smtp.mailtrap.io
MAIL_PORT=2525
@@ -121,7 +118,7 @@ ANALYTICS_ID=
# Firefly III has two options for user authentication. "eloquent" is the default,
# and "ldap" for LDAP servers.
# For full instructions on these settings please visit:
# https://firefly-iii.readthedocs.io/en/latest/installation/authentication.html
# https://docs.firefly-iii.org/advanced-installation/authentication
LOGIN_PROVIDER=eloquent
# LDAP connection configuration
@@ -162,15 +159,42 @@ ADLDAP_SYNC_FIELD=userprincipalname
# Organizr. This is at your own risk.
DISABLE_FRAME_HEADER=false
# You can fine tune the start-up of a Docker container by editing these environment variables.
# Use this at your own risk. Disabling certain checks and features may result in lost of inconsistent data.
# However if you know what you're doing you can significantly speed up container start times.
# Set each value to true to enable, or false to disable.
# Check if the SQLite database exists. Can be skipped if you're not using SQLite.
# Won't significantly speed up things.
DKR_CHECK_SQLITE=true
# Run database creation and migration commands. Disable this only if you're 100% sure the DB exists
# and is up to date.
DKR_RUN_MIGRATION=true
# Run database upgrade commands. Disable this only when you're 100% sure your DB is up-to-date
# with the latest fixes (outside of migrations!)
DKR_RUN_UPGRADE=true
# Verify database integrity. Includes all data checks and verifications.
# Disabling this makes Firefly III assume your DB is intact.
DKR_RUN_VERIFY=true
# Run database reporting commands. When disabled, Firefly III won't go over your data to report current state.
# Disabling this should have no impact on data integrity or safety but it won't warn you of possible issues.
DKR_RUN_REPORT=true
# Generate OAuth2 keys.
# When disabled, Firefly III won't attempt to generate OAuth2 Passport keys. This won't be an issue, IFF (if and only if)
# you had previously generated keys already and they're stored in your database for restauration.
DKR_RUN_PASSPORT_INSTALL=true
# Leave the following configuration vars as is.
# Unless you like to tinker and know what you're doing.
APP_NAME=FireflyIII
ADLDAP_CONNECTION=default
BROADCAST_DRIVER=log
QUEUE_DRIVER=sync
REDIS_HOST=127.0.0.1
REDIS_PASSWORD=null
REDIS_PORT=6379
CACHE_PREFIX=firefly
SEARCH_RESULT_LIMIT=50
PUSHER_KEY=
@@ -178,9 +202,9 @@ PUSHER_SECRET=
PUSHER_ID=
DEMO_USERNAME=
DEMO_PASSWORD=
IS_DOCKER=false
USE_ENCRYPTION=false
IS_SANDSTORM=false
IS_DOCKER=false
IS_HEROKU=false
BUNQ_USE_SANDBOX=false
FFIII_LAYOUT=v1

View File

@@ -7,7 +7,7 @@ about: Create a report to help Firefly III improve
**Bug description**
I am running Firefly III version x.x.x, and my problem is:
<!-- Replace the version and describe your problem or your issue will be closed. -->
<!-- Replace the version and describe your problem or your issue may be closed. -->
**Steps to reproduce**
<!-- What do you need to do to trigger this bug? -->
@@ -20,4 +20,7 @@ I am running Firefly III version x.x.x, and my problem is:
- Post a stacktrace from your log files
- Add a screenshot
- Make a drawing
- Donate money (just kidding ;)
- Replicate the problem on the demo site https://demo.firefly-iii.org/
-->

View File

@@ -28,5 +28,4 @@ Please describe your feature request:
- Make a drawing
- Donate money (just kidding ;)
- Remember the human
-->

2
.github/funding.yml vendored
View File

@@ -1,5 +1,5 @@
# These are supported funding model platforms
#github: # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2]
github: jc5
patreon: JC5
custom: https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=44UKUT455HUFA

8
.github/ranger.yml vendored
View File

@@ -1,8 +0,0 @@
# in .github/ranger.yml
comments:
-
action: delete_comment
pattern: 1
-
action: delete_comment
pattern: ":+1:"

2
.github/stale.yml vendored
View File

@@ -13,8 +13,6 @@ exemptLabels:
- enhancement
- feature
- bug
- possible-bug
- "possible bug"
- announcement
# Set to true to ignore issues in a project (defaults to false)

View File

@@ -1,9 +1,5 @@
sudo: required
language: bash
env:
- VERSION=4.8.1.4
dist: xenial
# safelist
branches:
@@ -14,16 +10,25 @@ branches:
services:
- docker
script:
# enable experimental features.
- echo '{"experimental":true}' | sudo tee /etc/docker/daemon.json
- mkdir $HOME/.docker
- touch $HOME/.docker/config.json
- echo '{"experimental":"enabled"}' | sudo tee $HOME/.docker/config.json
- sudo service docker restart
- docker version -f '{{.Server.Experimental}}'
- docker version
# build everything
- .deploy/docker/build-amd64.sh
- .deploy/docker/build-arm.sh
- .deploy/docker/manifest.sh
jobs:
include:
- dist: xenial
arch: amd64
env: ARCH=amd64 CHANNEL=alpha VERSION=5.0.0-alpha.1
stage: build
script: ./.deploy/docker/travis.sh
- dist: xenial
arch: amd64
env: ARCH=arm CHANNEL=alpha VERSION=5.0.0-alpha.1
stage: build
script: ./.deploy/docker/travis.sh
- dist: xenial
arch: arm64
env: ARCH=arm64 CHANNEL=alpha VERSION=5.0.0-alpha.1
stage: build
script: ./.deploy/docker/travis.sh
- dist: xenial
arch: amd64
env: CHANNEL=alpha VERSION=5.0.0-alpha.1
stage: manifest
script: ./.deploy/docker/manifest.sh

View File

@@ -1,6 +1,9 @@
FROM jc5x/firefly-iii-base-image:latest
# See also: https://github.com/JC5/firefly-iii-base-image
ENV FIREFLY_PATH=/var/www/firefly-iii COMPOSER_ALLOW_SUPERUSER=1
LABEL version="1.5" maintainer="thegrumpydictator@gmail.com"
LABEL version="1.6" maintainer="thegrumpydictator@gmail.com"
# Create volumes
VOLUME $FIREFLY_PATH/storage/export $FIREFLY_PATH/storage/upload

View File

@@ -1,6 +1,9 @@
FROM jc5x/firefly-iii-base-image:latest
# See also: https://github.com/JC5/firefly-iii-base-image
ENV FIREFLY_PATH=/var/www/firefly-iii COMPOSER_ALLOW_SUPERUSER=1
LABEL version="1.5" maintainer="thegrumpydictator@gmail.com"
LABEL version="1.6" maintainer="thegrumpydictator@gmail.com"
# Create volumes
VOLUME $FIREFLY_PATH/storage/export $FIREFLY_PATH/storage/upload

View File

@@ -1,6 +1,9 @@
FROM jc5x/firefly-iii-base-image:latest-arm
# See also: https://github.com/JC5/firefly-iii-base-image
ENV FIREFLY_PATH=/var/www/firefly-iii COMPOSER_ALLOW_SUPERUSER=1
LABEL version="1.5" maintainer="thegrumpydictator@gmail.com"
LABEL version="1.6" maintainer="thegrumpydictator@gmail.com"
# Create volumes
VOLUME $FIREFLY_PATH/storage/export $FIREFLY_PATH/storage/upload

View File

@@ -1,25 +1,13 @@
FROM arm32v7/php:7.2-apache-stretch
ARG ARCH
COPY tmp/qemu-arm-static /usr/bin/qemu-arm-static
FROM jc5x/firefly-iii-base-image:latest-arm
# See also: https://github.com/JC5/firefly-iii-base-image
ENV FIREFLY_PATH=/var/www/firefly-iii COMPOSER_ALLOW_SUPERUSER=1
LABEL version="1.5" maintainer="thegrumpydictator@gmail.com"
LABEL version="1.6" maintainer="thegrumpydictator@gmail.com"
# Create volumes
VOLUME $FIREFLY_PATH/storage/export $FIREFLY_PATH/storage/upload
# Install stuff Firefly III runs with & depends on: php extensions, locales, dev headers and composer
RUN apt-get update && apt-get install -y locales unzip && apt-get clean && rm -rf /var/lib/apt/lists/*
ADD https://raw.githubusercontent.com/mlocati/docker-php-extension-installer/master/install-php-extensions /usr/local/bin/
RUN chmod uga+x /usr/local/bin/install-php-extensions && sync && \
install-php-extensions --cleanup bcmath ldap gd pdo_pgsql pdo_sqlite pdo_mysql intl opcache memcached
RUN a2enmod rewrite && a2enmod ssl
RUN echo "hu_HU.UTF-8 UTF-8\nro_RO.UTF-8 UTF-8\nnb_NO.UTF-8 UTF-8\nde_DE.UTF-8 UTF-8\ncs_CZ.UTF-8 UTF-8\nen_US.UTF-8 UTF-8\nes_ES.UTF-8 UTF-8\nfr_FR.UTF-8 UTF-8\nid_ID.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\nzh_TW.UTF-8 UTF-8\nzh_CN.UTF-8 UTF-8\n\n" > /etc/locale.gen
RUN locale-gen
RUN curl -sS https://getcomposer.org/installer | php -- --install-dir=/usr/local/bin --filename=composer
# Copy in Firefly III source
WORKDIR $FIREFLY_PATH
ADD . $FIREFLY_PATH
@@ -29,15 +17,6 @@ RUN chown -R www-data:www-data /var/www && \
chmod -R 775 $FIREFLY_PATH/storage && \
composer install --prefer-dist --no-dev --no-scripts --no-suggest
# copy ca certs to correct location
COPY ./.deploy/docker/cacert.pem /usr/local/ssl/cert.pem
# copy Apache config to correct spot.
COPY ./.deploy/docker/apache2.conf /etc/apache2/apache2.conf
# Enable default site (Firefly III)
COPY ./.deploy/docker/apache-firefly.conf /etc/apache2/sites-available/000-default.conf
# Expose port 80
EXPOSE 80

View File

@@ -38,6 +38,7 @@ use Illuminate\Pagination\LengthAwarePaginator;
use League\Fractal\Pagination\IlluminatePaginatorAdapter;
use League\Fractal\Resource\Collection as FractalCollection;
use League\Fractal\Resource\Item;
use Log;
use function strlen;
/**
@@ -97,10 +98,16 @@ class AttachmentController extends Controller
public function download(Attachment $attachment): LaravelResponse
{
if (false === $attachment->uploaded) {
throw new FireflyException('No file has been uploaded for this attachment (yet).');
throw new FireflyException('200000: File has not been uploaded (yet).');
}
if (0 === $attachment->size) {
throw new FireflyException('200000: File has not been uploaded (yet).');
}
if ($this->repository->exists($attachment)) {
$content = $this->repository->getContent($attachment);
if ('' === $content) {
throw new FireflyException('200002: File is empty (zero bytes).');
}
$quoted = sprintf('"%s"', addcslashes(basename($attachment->filename), '"\\'));
/** @var LaravelResponse $response */
@@ -118,7 +125,7 @@ class AttachmentController extends Controller
return $response;
}
throw new FireflyException('Could not find the indicated attachment. The file is no longer there.');
throw new FireflyException('200003: File does not exist.');
}
/**
@@ -233,6 +240,11 @@ class AttachmentController extends Controller
/** @var AttachmentHelperInterface $helper */
$helper = app(AttachmentHelperInterface::class);
$body = $request->getContent();
if ('' === $body) {
Log::error('Body of attachment is empty.');
return response()->json([], 422);
}
$helper->saveAttachmentFromApi($attachment, $body);
return response()->json([], 204);

View File

@@ -211,20 +211,16 @@ class BillController extends Controller
*/
public function store(BillRequest $request): JsonResponse
{
$bill = $this->repository->store($request->getAll());
if (null !== $bill) {
$manager = $this->getManager();
$bill = $this->repository->store($request->getAll());
$manager = $this->getManager();
/** @var BillTransformer $transformer */
$transformer = app(BillTransformer::class);
$transformer->setParameters($this->parameters);
/** @var BillTransformer $transformer */
$transformer = app(BillTransformer::class);
$transformer->setParameters($this->parameters);
$resource = new Item($bill, $transformer, 'bills');
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', 'application/vnd.api+json');
}
throw new FireflyException('Could not store new bill.'); // @codeCoverageIgnore
$resource = new Item($bill, $transformer, 'bills');
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', 'application/vnd.api+json');
}
/**

View File

@@ -187,19 +187,16 @@ class BudgetController extends Controller
*/
public function store(BudgetRequest $request): JsonResponse
{
$budget = $this->repository->store($request->getAll());
if (null !== $budget) {
$manager = $this->getManager();
$budget = $this->repository->store($request->getAll());
$manager = $this->getManager();
/** @var BudgetTransformer $transformer */
$transformer = app(BudgetTransformer::class);
$transformer->setParameters($this->parameters);
/** @var BudgetTransformer $transformer */
$transformer = app(BudgetTransformer::class);
$transformer->setParameters($this->parameters);
$resource = new Item($budget, $transformer, 'budgets');
$resource = new Item($budget, $transformer, 'budgets');
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', 'application/vnd.api+json');
}
throw new FireflyException('Could not store new budget.'); // @codeCoverageIgnore
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', 'application/vnd.api+json');
}
/**

View File

@@ -165,7 +165,7 @@ class BudgetLimitController extends Controller
$data = $request->getAll();
$budget = $this->repository->findNull($data['budget_id']);
if (null === $budget) {
throw new FireflyException('Unknown budget.');
throw new FireflyException('200004: Budget does not exist.');
}
$data['budget'] = $budget;
$budgetLimit = $this->blRepository->storeBudgetLimit($data);

View File

@@ -152,18 +152,15 @@ class CategoryController extends Controller
public function store(CategoryRequest $request): JsonResponse
{
$category = $this->repository->store($request->getAll());
if (null !== $category) {
$manager = $this->getManager();
$manager = $this->getManager();
/** @var CategoryTransformer $transformer */
$transformer = app(CategoryTransformer::class);
$transformer->setParameters($this->parameters);
/** @var CategoryTransformer $transformer */
$transformer = app(CategoryTransformer::class);
$transformer->setParameters($this->parameters);
$resource = new Item($category, $transformer, 'categories');
$resource = new Item($category, $transformer, 'categories');
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', 'application/vnd.api+json');
}
throw new FireflyException('Could not store new category.'); // @codeCoverageIgnore
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', 'application/vnd.api+json');
}
/**

View File

@@ -57,7 +57,7 @@ class ConfigurationController extends Controller
$admin = auth()->user();
if (!$this->repository->hasRole($admin, 'owner')) {
throw new FireflyException('No access to method.'); // @codeCoverageIgnore
throw new FireflyException('200005: You need the "owner" role to do this.'); // @codeCoverageIgnore
}
return $next($request);

View File

@@ -313,10 +313,10 @@ class CurrencyController extends Controller
if (!$this->userRepository->hasRole($admin, 'owner')) {
// access denied:
throw new FireflyException('No access to method, user is not owner.'); // @codeCoverageIgnore
throw new FireflyException('200005: You need the "owner" role to do this.'); // @codeCoverageIgnore
}
if ($this->repository->currencyInUse($currency)) {
throw new FireflyException('No access to method, currency is in use.'); // @codeCoverageIgnore
throw new FireflyException('200006: Currency in use.'); // @codeCoverageIgnore
}
$this->repository->destroy($currency);
@@ -574,26 +574,21 @@ class CurrencyController extends Controller
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 = $this->getManager();
$defaultCurrency = app('amount')->getDefaultCurrencyByUser(auth()->user());
$this->parameters->set('defaultCurrency', $defaultCurrency);
/** @var CurrencyTransformer $transformer */
$transformer = app(CurrencyTransformer::class);
$transformer->setParameters($this->parameters);
$resource = new Item($currency, $transformer, 'currencies');
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', 'application/vnd.api+json');
if (true === $request->boolean('default')) {
app('preferences')->set('currencyPreference', $currency->code);
app('preferences')->mark();
}
throw new FireflyException('Could not store new currency.'); // @codeCoverageIgnore
$manager = $this->getManager();
$defaultCurrency = app('amount')->getDefaultCurrencyByUser(auth()->user());
$this->parameters->set('defaultCurrency', $defaultCurrency);
/** @var CurrencyTransformer $transformer */
$transformer = app(CurrencyTransformer::class);
$transformer->setParameters($this->parameters);
$resource = new Item($currency, $transformer, 'currencies');
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', 'application/vnd.api+json');
}
/**

View File

@@ -79,10 +79,10 @@ class CurrencyExchangeRateController extends Controller
$toCurrency = $this->repository->findByCodeNull($request->get('to') ?? 'USD');
if (null === $fromCurrency) {
throw new FireflyException('Unknown source currency.');
throw new FireflyException('200007: Unknown source currency');
}
if (null === $toCurrency) {
throw new FireflyException('Unknown destination currency.');
throw new FireflyException('200007: Unknown destination currency');
}
/** @var Carbon $dateObj */

View File

@@ -86,7 +86,7 @@ class LinkTypeController extends Controller
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));
throw new FireflyException('200020: Link type cannot be changed.');
}
$this->repository->destroy($linkType);
@@ -160,7 +160,7 @@ class LinkTypeController extends Controller
$admin = auth()->user();
if (!$this->userRepository->hasRole($admin, 'owner')) {
throw new FireflyException('You need the "owner"-role to do this.');
throw new FireflyException('200005: You need the "owner" role to do this.'); // @codeCoverageIgnore
}
$data = $request->getAll();
// if currency ID is 0, find the currency by the code:
@@ -247,14 +247,14 @@ class LinkTypeController extends Controller
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));
throw new FireflyException('200020: Link type cannot be changed.');
}
/** @var User $admin */
$admin = auth()->user();
if (!$this->userRepository->hasRole($admin, 'owner')) {
throw new FireflyException('You need the "owner"-role to do this.');
throw new FireflyException('200005: You need the "owner" role to do this.'); // @codeCoverageIgnore
}
$data = $request->getAll();

View File

@@ -181,19 +181,15 @@ class PiggyBankController extends Controller
public function store(PiggyBankRequest $request): JsonResponse
{
$piggyBank = $this->repository->store($request->getAll());
if (null !== $piggyBank) {
$manager = $this->getManager();
$manager = $this->getManager();
/** @var PiggyBankTransformer $transformer */
$transformer = app(PiggyBankTransformer::class);
$transformer->setParameters($this->parameters);
/** @var PiggyBankTransformer $transformer */
$transformer = app(PiggyBankTransformer::class);
$transformer->setParameters($this->parameters);
$resource = new Item($piggyBank, $transformer, '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.');
$resource = new Item($piggyBank, $transformer, 'piggy_banks');
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', 'application/vnd.api+json');
}
/**

View File

@@ -236,7 +236,7 @@ class RecurrenceController extends Controller
$result = $recurring->fire();
} catch (FireflyException $e) {
Log::error($e->getMessage());
throw new FireflyException('Could not fire recurring cron job.');
throw new FireflyException('200022: Error in cron job.');
}
if (false === $result) {
return response()->json([], 204);

View File

@@ -257,7 +257,7 @@ class RuleGroupController extends Controller
/** @var Collection $rules */
$rules = $this->ruleGroupRepository->getActiveRules($group);
if (0 === $rules->count()) {
throw new FireflyException('No rules in this rule group.');
throw new FireflyException('200023: No rules in this rule group.');
}
$parameters = $request->getTestParameters();
$matchingTransactions = [];

View File

@@ -83,7 +83,8 @@ class AccountController extends Controller
$transformer = app(AccountTransformer::class);
$transformer->setParameters($this->parameters);
$count = $accounts->count();
$paginator = new LengthAwarePaginator($accounts, $count, $count, 1);
$perPage = 0 === $count ? 1 : $count;
$paginator = new LengthAwarePaginator($accounts, $count, $perPage, 1);
$resource = new FractalCollection($accounts, $transformer, 'accounts');
$resource->setPaginator(new IlluminatePaginatorAdapter($paginator));

View File

@@ -0,0 +1,116 @@
<?php
/**
* TransferController.php
* Copyright (c) 2019 thegrumpydictator@gmail.com
*
* This file is part of Firefly III (https://github.com/firefly-iii).
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
namespace FireflyIII\Api\V1\Controllers\Search;
use FireflyIII\Api\V1\Controllers\Controller;
use FireflyIII\Api\V1\Requests\Search\TransferRequest;
use FireflyIII\Exceptions\FireflyException;
use FireflyIII\Helpers\Collector\GroupCollectorInterface;
use FireflyIII\Support\Search\TransferSearch;
use FireflyIII\Transformers\TransactionGroupTransformer;
use FireflyIII\User;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Http\Response;
use League\Fractal\Pagination\IlluminatePaginatorAdapter;
use League\Fractal\Resource\Collection as FractalCollection;
/**
* Class TransferController
*/
class TransferController extends Controller
{
/**
* @param Request $request
*
* @return JsonResponse|Response
* @throws FireflyException
*/
public function search(TransferRequest $request)
{
// configure transfer search to search for a > b
$search = app(TransferSearch::class);
$search->setSource($request->get('source'));
$search->setDestination($request->get('destination'));
$search->setAmount($request->get('amount'));
$search->setDescription($request->get('description'));
$search->setDate($request->get('date'));
$left = $search->search();
// configure transfer search to search for b > a
$search->setSource($request->get('destination'));
$search->setDestination($request->get('source'));
$search->setAmount($request->get('amount'));
$search->setDescription($request->get('description'));
$search->setDate($request->get('date'));
$right = $search->search();
// add parameters to URL:
$this->parameters->set('source', $request->get('source'));
$this->parameters->set('destination', $request->get('destination'));
$this->parameters->set('amount', $request->get('amount'));
$this->parameters->set('description', $request->get('description'));
$this->parameters->set('date', $request->get('date'));
// get all journal ID's.
$total = $left->merge($right)->unique('id')->pluck('id')->toArray();
if (0 === count($total)) {
// forces search to be empty.
$total = [-1];
}
// collector to return results.
$pageSize = (int)app('preferences')->getForUser(auth()->user(), 'listPageSize', 50)->data;
$manager = $this->getManager();
/** @var User $admin */
$admin = auth()->user();
// use new group collector:
/** @var GroupCollectorInterface $collector */
$collector = app(GroupCollectorInterface::class);
$collector
->setUser($admin)
// all info needed for the API:
->withAPIInformation()
// set page size:
->setLimit($pageSize)
// set page to retrieve
->setPage(1)
->setJournalIds($total);
$paginator = $collector->getPaginatedGroups();
$paginator->setPath(route('api.v1.search.transfers') . $this->buildParams());
$transactions = $paginator->getCollection();
/** @var TransactionGroupTransformer $transformer */
$transformer = app(TransactionGroupTransformer::class);
$transformer->setParameters($this->parameters);
$resource = new FractalCollection($transactions, $transformer, 'transactions');
$resource->setPaginator(new IlluminatePaginatorAdapter($paginator));
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', 'application/vnd.api+json');
}
}

View File

@@ -28,6 +28,7 @@ use FireflyIII\Api\V1\Requests\TransactionStoreRequest;
use FireflyIII\Api\V1\Requests\TransactionUpdateRequest;
use FireflyIII\Events\StoredTransactionGroup;
use FireflyIII\Events\UpdatedTransactionGroup;
use FireflyIII\Exceptions\DuplicateTransactionException;
use FireflyIII\Helpers\Collector\GroupCollectorInterface;
use FireflyIII\Models\TransactionGroup;
use FireflyIII\Models\TransactionJournal;
@@ -251,6 +252,19 @@ class TransactionController extends Controller
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', 'application/vnd.api+json');
}
/**
* Show a single transaction, by transaction journal.
*
* @param TransactionJournal $transactionJournal
*
* @return JsonResponse
* @codeCoverageIgnore
*/
public function showByJournal(TransactionJournal $transactionJournal): JsonResponse
{
return $this->show($transactionJournal->transactionGroup);
}
/**
* Store a new transaction.
*
@@ -266,7 +280,20 @@ class TransactionController extends Controller
Log::channel('audit')
->info('Store new transaction over API.', $data);
$transactionGroup = $this->groupRepository->store($data);
try {
$transactionGroup = $this->groupRepository->store($data);
} catch (DuplicateTransactionException $e) {
// return bad validation message.
// TODO use Laravel's internal validation thing to do this.
$response = [
'message' => 'The given data was invalid.',
'errors' => [
'transactions.0.description' => [$e->getMessage()],
],
];
return response()->json($response, 422);
}
event(new StoredTransactionGroup($transactionGroup));

View File

@@ -165,7 +165,7 @@ class TransactionLinkController extends Controller
$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.');
throw new FireflyException('200024: Source or destination does not exist.');
}
$data['direction'] = 'inward';
@@ -196,7 +196,7 @@ class TransactionLinkController extends Controller
$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.');
throw new FireflyException('200024: Source or destination does not exist.');
}
$data['direction'] = 'inward';
$journalLink = $this->repository->updateLink($journalLink, $data);

View File

@@ -83,7 +83,7 @@ class UserController extends Controller
return response()->json([], 204);
}
throw new FireflyException('No access to method.'); // @codeCoverageIgnore
throw new FireflyException('200025: No access to function.'); // @codeCoverageIgnore
}
/**

View File

@@ -1,6 +1,6 @@
<?php
/**
* TagsSpaceTest.php
* TransferRequest.php
* Copyright (c) 2019 thegrumpydictator@gmail.com
*
* This file is part of Firefly III (https://github.com/firefly-iii).
@@ -19,43 +19,40 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
declare(strict_types=1);
namespace FireflyIII\Api\V1\Requests\Search;
namespace Tests\Unit\Import\MapperPreProcess;
use FireflyIII\Import\MapperPreProcess\TagsSpace;
use Log;
use Tests\TestCase;
use FireflyIII\Api\V1\Requests\Request;
use FireflyIII\Rules\IsTransferAccount;
/**
* Class TagsSpaceTest
* @SuppressWarnings(PHPMD.CouplingBetweenObjects)
* @SuppressWarnings(PHPMD.ExcessiveMethodLength)
* @SuppressWarnings(PHPMD.TooManyPublicMethods)
* Class TransferRequest
*/
class TagsSpaceTest extends TestCase
class TransferRequest extends Request
{
/**
* Authorize logged in users.
*
* @return bool
*/
public function setUp(): void
public function authorize(): bool
{
parent::setUp();
Log::info(sprintf('Now in %s.', get_class($this)));
// Only allow authenticated users
return auth()->check();
}
/**
* \FireflyIII\Import\MapperPreProcess\TagsSpace
* @return array
*/
public function testBasic(): void
public function rules(): array
{
$input = 'some tags with spaces,and without ';
$output = ['some', 'tags', 'with', 'spaces,and', 'without'];
$mapper = new TagsSpace();
$result = $mapper->run($input);
$this->assertEquals($output, $result);
return [
'source' => ['required', new IsTransferAccount],
'destination' => ['required', new IsTransferAccount],
'amount' => 'required|numeric|more:0',
'description' => 'required|min:1',
'date' => 'required|date',
];
}
}
}

View File

@@ -58,8 +58,9 @@ class TransactionStoreRequest extends Request
public function getAll(): array
{
$data = [
'group_title' => $this->string('group_title'),
'transactions' => $this->getTransactionData(),
'group_title' => $this->string('group_title'),
'error_if_duplicate_hash' => $this->boolean('error_if_duplicate_hash'),
'transactions' => $this->getTransactionData(),
];
return $data;
@@ -74,7 +75,8 @@ class TransactionStoreRequest extends Request
{
$rules = [
// basic fields for group:
'group_title' => 'between:1,1000',
'group_title' => 'between:1,1000|nullable',
'error_if_duplicate_hash' => [new IsBoolean],
// transaction rules (in array for splits):
'transactions.*.type' => 'required|in:withdrawal,deposit,transfer,opening-balance,reconciliation',
@@ -82,14 +84,14 @@ class TransactionStoreRequest extends Request
'transactions.*.order' => 'numeric|min:0',
// currency info
'transactions.*.currency_id' => 'numeric|exists:transaction_currencies,id',
'transactions.*.currency_code' => 'min:3|max:3|exists:transaction_currencies,code',
'transactions.*.foreign_currency_id' => 'numeric|exists:transaction_currencies,id',
'transactions.*.foreign_currency_code' => 'min:3|max:3|exists:transaction_currencies,code',
'transactions.*.currency_id' => 'numeric|exists:transaction_currencies,id|nullable',
'transactions.*.currency_code' => 'min:3|max:3|exists:transaction_currencies,code|nullable',
'transactions.*.foreign_currency_id' => 'numeric|exists:transaction_currencies,id|nullable',
'transactions.*.foreign_currency_code' => 'min:3|max:3|exists:transaction_currencies,code|nullable',
// amount
'transactions.*.amount' => 'required|numeric|more:0',
'transactions.*.foreign_amount' => 'numeric|more:0',
'transactions.*.foreign_amount' => 'numeric',
// description
'transactions.*.description' => 'nullable|between:1,1000',
@@ -97,10 +99,16 @@ class TransactionStoreRequest extends Request
// source of transaction
'transactions.*.source_id' => ['numeric', 'nullable', new BelongsUser],
'transactions.*.source_name' => 'between:1,255|nullable',
'transactions.*.source_iban' => 'between:1,255|nullable|iban',
'transactions.*.source_number' => 'between:1,255|nullable',
'transactions.*.source_bic' => 'between:1,255|nullable|bic',
// destination of transaction
'transactions.*.destination_id' => ['numeric', 'nullable', new BelongsUser],
'transactions.*.destination_name' => 'between:1,255|nullable',
'transactions.*.destination_iban' => 'between:1,255|nullable|iban',
'transactions.*.destination_number' => 'between:1,255|nullable',
'transactions.*.destination_bic' => 'between:1,255|nullable|bic',
// budget, category, bill and piggy
'transactions.*.budget_id' => ['mustExist:budgets,id', new BelongsUser],
@@ -202,7 +210,7 @@ class TransactionStoreRequest extends Request
'date' => $this->dateFromValue($object['date']),
'order' => $this->integerFromValue((string)$object['order']),
'currency_id' => $this->integerFromValue($object['currency_id']),
'currency_id' => $this->integerFromValue((string)$object['currency_id']),
'currency_code' => $this->stringFromValue($object['currency_code']),
// foreign currency info:
@@ -219,10 +227,16 @@ class TransactionStoreRequest extends Request
// source of transaction. If everything is null, assume cash account.
'source_id' => $this->integerFromValue((string)$object['source_id']),
'source_name' => $this->stringFromValue($object['source_name']),
'source_iban' => $this->stringFromValue($object['source_iban']),
'source_number' => $this->stringFromValue($object['source_number']),
'source_bic' => $this->stringFromValue($object['source_bic']),
// destination of transaction. If everything is null, assume cash account.
'destination_id' => $this->integerFromValue((string)$object['destination_id']),
'destination_name' => $this->stringFromValue($object['destination_name']),
'destination_iban' => $this->stringFromValue($object['destination_iban']),
'destination_number' => $this->stringFromValue($object['destination_number']),
'destination_bic' => $this->stringFromValue($object['destination_bic']),
// budget info
'budget_id' => $this->integerFromValue((string)$object['budget_id']),

View File

@@ -105,7 +105,13 @@ class TransactionUpdateRequest extends Request
'foreign_amount',
'description',
'source_name',
'source_iban',
'source_number',
'source_bic',
'destination_name',
'destination_iban',
'destination_number',
'destination_bic',
'budget_name',
'category_name',
'bill_name',

View File

@@ -27,6 +27,7 @@ use Exception;
use FireflyIII\Models\TransactionGroup;
use FireflyIII\Models\TransactionJournal;
use Illuminate\Console\Command;
use Log;
/**
* Class DeleteEmptyGroups
@@ -54,6 +55,7 @@ class DeleteEmptyGroups extends Command
*/
public function handle(): int
{
Log::debug(sprintf('Now in %s', __METHOD__));
$start = microtime(true);
$groupIds =
TransactionGroup
@@ -61,6 +63,7 @@ class DeleteEmptyGroups extends Command
->whereNull('transaction_journals.id')->get(['transaction_groups.id'])->pluck('id')->toArray();
$total = count($groupIds);
Log::debug(sprintf('Count is %d', $total));
if ($total > 0) {
$this->info(sprintf('Deleted %d empty transaction group(s).', $total));

View File

@@ -30,6 +30,7 @@ use FireflyIII\Models\Transaction;
use FireflyIII\Models\TransactionJournal;
use FireflyIII\Models\TransactionType;
use Illuminate\Console\Command;
use Log;
/**
* Class FixAccountTypes
@@ -66,6 +67,7 @@ class FixAccountTypes extends Command
public function handle(): int
{
$this->stupidLaravel();
Log::debug('Now in fix-account-types');
$start = microtime(true);
$this->factory = app(AccountFactory::class);
// some combinations can be fixed by this script:
@@ -88,13 +90,16 @@ class FixAccountTypes extends Command
$this->expected = config('firefly.source_dests');
$journals = TransactionJournal::with(['TransactionType', 'transactions', 'transactions.account', 'transactions.account.accounttype'])->get();
Log::debug(sprintf('Found %d journals to fix.', $journals->count()));
foreach ($journals as $journal) {
$this->inspectJournal($journal);
}
if (0 === $this->count) {
Log::debug('No journals had to be fixed.');
$this->info('All account types are OK!');
}
if (0 !== $this->count) {
Log::debug(sprintf('%d journals had to be fixed.', $this->count));
$this->info(sprintf('Acted on %d transaction(s)!', $this->count));
}
@@ -223,21 +228,36 @@ class FixAccountTypes extends Command
*/
private function inspectJournal(TransactionJournal $journal): void
{
Log::debug(sprintf('Now trying to fix journal #%d', $journal->id));
$count = $journal->transactions()->count();
if (2 !== $count) {
Log::debug(sprintf('Journal has %d transactions, so cant fix.', $count));
$this->info(sprintf('Cannot inspect transaction journal #%d because it has %d transaction(s) instead of 2.', $journal->id, $count));
return;
}
$type = $journal->transactionType->type;
$sourceTransaction = $this->getSourceTransaction($journal);
$destTransaction = $this->getDestinationTransaction($journal);
if (null === $sourceTransaction) {
Log::error('Source transaction is unexpectedly NULL. Wont fix this journal.');
return;
}
if (null === $destTransaction) {
Log::error('Destination transaction is unexpectedly NULL. Wont fix this journal.');
return;
}
$sourceAccount = $sourceTransaction->account;
$sourceAccountType = $sourceAccount->accountType->type;
$destTransaction = $this->getDestinationTransaction($journal);
$destAccount = $destTransaction->account;
$destAccountType = $destAccount->accountType->type;
if (!isset($this->expected[$type])) {
// @codeCoverageIgnoreStart
Log::info(sprintf('No source/destination info for transaction type %s.', $type));
$this->info(sprintf('No source/destination info for transaction type %s.', $type));
return;

View File

@@ -0,0 +1,75 @@
<?php
namespace FireflyIII\Console\Commands;
use Illuminate\Console\Command;
use PDO;
use PDOException;
/**
* Class CreateDatabase
*/
class CreateDatabase extends Command
{
/**
* The console command description.
*
* @var string
*/
protected $description = 'Tries to create the database if it doesn\'t exist yet.';
/**
* The name and signature of the console command.
*
* @var string
*/
protected $signature = 'firefly-iii:create-database';
/**
* Execute the console command.
*
* @return mixed
*/
public function handle()
{
if ('mysql' !== env('DB_CONNECTION')) {
$this->info('This command currently applies to MySQL connections only.');
}
// try to set up a raw connection:
$dsn = sprintf('mysql:host=%s;charset=utf8mb4', env('DB_HOST'));
$options = [
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
PDO::ATTR_EMULATE_PREPARES => false,
];
try {
$pdo = new PDO($dsn, env('DB_USERNAME'), env('DB_PASSWORD'), $options);
} catch (PDOException $e) {
$this->error(sprintf('Error when connecting to DB: %s', $e->getMessage()));
return 1;
}
// with PDO, try to list DB's (
$stmt = $pdo->query('SHOW DATABASES;');
$exists = false;
// slightly more complex but less error prone.
foreach ($stmt as $row) {
$name = $row['Database'] ?? false;
if ($name === env('DB_DATABASE')) {
$exists = true;
}
}
if (false === $exists) {
$this->error(sprintf('Database "%s" does not exist.', env('DB_DATABASE')));
// try to create it.
$pdo->exec(sprintf('CREATE DATABASE `%s` CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;', env('DB_DATABASE')));
$this->info(sprintf('Created database "%s"', env('DB_DATABASE')));
return 0;
}
$this->info(sprintf('Database "%s" exists.', env('DB_DATABASE')));
return 0;
}
}

View File

@@ -23,6 +23,7 @@ namespace FireflyIII\Console\Commands\Integrity;
use Artisan;
use Crypt;
use FireflyIII\Support\System\OAuthKeys;
use Illuminate\Console\Command;
/**
@@ -30,8 +31,6 @@ use Illuminate\Console\Command;
*/
class RestoreOAuthKeys extends Command
{
private const PRIVATE_KEY = 'oauth_private_key';
private const PUBLIC_KEY = 'oauth_public_key';
/**
* The console command description.
*
@@ -62,7 +61,7 @@ class RestoreOAuthKeys extends Command
*/
private function generateKeys(): void
{
Artisan::call('passport:keys');
OAuthKeys::generateKeys();
}
/**
@@ -70,7 +69,7 @@ class RestoreOAuthKeys extends Command
*/
private function keysInDatabase(): bool
{
return app('fireflyconfig')->has(self::PRIVATE_KEY) && app('fireflyconfig')->has(self::PUBLIC_KEY);
return OAuthKeys::keysInDatabase();
}
/**
@@ -78,10 +77,7 @@ class RestoreOAuthKeys extends Command
*/
private function keysOnDrive(): bool
{
$private = storage_path('oauth-private.key');
$public = storage_path('oauth-public.key');
return file_exists($private) && file_exists($public);
return OAuthKeys::hasKeyFiles();
}
/**
@@ -89,12 +85,7 @@ class RestoreOAuthKeys extends Command
*/
private function restoreKeysFromDB(): void
{
$privateContent = Crypt::decrypt(app('fireflyconfig')->get(self::PRIVATE_KEY)->data);
$publicContent = Crypt::decrypt(app('fireflyconfig')->get(self::PUBLIC_KEY)->data);
$private = storage_path('oauth-private.key');
$public = storage_path('oauth-public.key');
file_put_contents($private, $privateContent);
file_put_contents($public, $publicContent);
OAuthKeys::restoreKeysFromDB();
}
/**
@@ -129,9 +120,6 @@ class RestoreOAuthKeys extends Command
*/
private function storeKeysInDB(): void
{
$private = storage_path('oauth-private.key');
$public = storage_path('oauth-public.key');
app('fireflyconfig')->set(self::PRIVATE_KEY, Crypt::encrypt(file_get_contents($private)));
app('fireflyconfig')->set(self::PUBLIC_KEY, Crypt::encrypt(file_get_contents($public)));
OAuthKeys::storeKeysInDB();
}
}

View File

@@ -0,0 +1,50 @@
<?php
namespace FireflyIII\Console\Commands;
use Illuminate\Console\Command;
class SetLatestVersion extends Command
{
/**
* The console command description.
*
* @var string
*/
protected $description = 'Command description';
/**
* The name and signature of the console command.
*
* @var string
*/
protected $signature = 'firefly-iii:set-latest-version {--james-is-cool}';
/**
* Create a new command instance.
*
* @return void
*/
public function __construct()
{
parent::__construct();
}
/**
* Execute the console command.
*
* @return mixed
*/
public function handle()
{
if (!$this->option('james-is-cool')) {
$this->error('Am too!');
return;
}
app('fireflyconfig')->set('db_version', config('firefly.db_version'));
app('fireflyconfig')->set('ff3_version', config('firefly.version'));
$this->line('Updated version.');
return 0;
}
}

View File

@@ -0,0 +1,31 @@
<?php
/**
* DuplicateTransactionException.php
* Copyright (c) 2019 thegrumpydictator@gmail.com
*
* This file is part of Firefly III (https://github.com/firefly-iii).
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
namespace FireflyIII\Exceptions;
use Exception;
/**
* Class DuplicateTransactionException
*/
class DuplicateTransactionException extends Exception
{
}

View File

@@ -101,6 +101,7 @@ class GracefulNotFoundHandler extends ExceptionHandler
break;
case 'tags.show.all':
case 'tags.show':
case 'tags.edit':
$request->session()->reflash();
return redirect(route('tags.index'));

View File

@@ -68,7 +68,6 @@ class AccountMetaFactory
{
/** @var AccountMeta $entry */
$entry = $account->accountMeta()->where('name', $field)->first();
// must not be an empty string:
if ('' !== $value) {

View File

@@ -24,10 +24,12 @@ declare(strict_types=1);
namespace FireflyIII\Factory;
use FireflyIII\Exceptions\FireflyException;
use FireflyIII\Models\Bill;
use FireflyIII\Models\TransactionCurrency;
use FireflyIII\Services\Internal\Support\BillServiceTrait;
use FireflyIII\User;
use Illuminate\Database\QueryException;
use Log;
/**
@@ -55,6 +57,7 @@ class BillFactory
* @param array $data
*
* @return Bill|null
* @throws FireflyException
*/
public function create(array $data): ?Bill
{
@@ -64,28 +67,31 @@ class BillFactory
$currency = $factory->find((int)($data['currency_id'] ?? null), (string)($data['currency_code'] ?? null));
if (null === $currency) {
// use default currency:
$currency = app('amount')->getDefaultCurrencyByUser($this->user);
}
try {
/** @var Bill $bill */
$bill = Bill::create(
[
'name' => $data['name'],
'match' => 'MIGRATED_TO_RULES',
'amount_min' => $data['amount_min'],
'user_id' => $this->user->id,
'transaction_currency_id' => $currency->id,
'amount_max' => $data['amount_max'],
'date' => $data['date'],
'repeat_freq' => $data['repeat_freq'],
'skip' => $data['skip'],
'automatch' => true,
'active' => $data['active'] ?? true,
]
);
} catch(QueryException $e) {
Log::error($e->getMessage());
Log::error($e->getTraceAsString());
throw new FireflyException('400000: Could not store bill.');
}
/** @var Bill $bill */
$bill = Bill::create(
[
'name' => $data['name'],
'match' => 'MIGRATED_TO_RULES',
'amount_min' => $data['amount_min'],
'user_id' => $this->user->id,
'transaction_currency_id' => $currency->id,
'amount_max' => $data['amount_max'],
'date' => $data['date'],
'repeat_freq' => $data['repeat_freq'],
'skip' => $data['skip'],
'automatch' => true,
'active' => $data['active'] ?? true,
]
);
// update note:
if (isset($data['notes'])) {
$this->updateNote($bill, $data['notes']);
}

View File

@@ -24,8 +24,10 @@ declare(strict_types=1);
namespace FireflyIII\Factory;
use FireflyIII\Exceptions\FireflyException;
use FireflyIII\Models\Category;
use FireflyIII\User;
use Illuminate\Database\QueryException;
use Log;
/**
@@ -62,7 +64,7 @@ class CategoryFactory
* @param null|string $categoryName
*
* @return Category|null
*
* @throws FireflyException
*/
public function findOrCreate(?int $categoryId, ?string $categoryName): ?Category
{
@@ -88,13 +90,17 @@ class CategoryFactory
if (null !== $category) {
return $category;
}
return Category::create(
[
'user_id' => $this->user->id,
'name' => $categoryName,
]
);
try {
return Category::create(
[
'user_id' => $this->user->id,
'name' => $categoryName,
]
);
} catch (QueryException $e) {
Log::error($e->getMessage());
throw new FireflyException('400003: Could not store new category.');
}
}
return null;

View File

@@ -27,6 +27,7 @@ declare(strict_types=1);
namespace FireflyIII\Factory;
use FireflyIII\Exceptions\FireflyException;
use FireflyIII\Models\TransactionCurrency;
use Illuminate\Database\QueryException;
use Log;
@@ -51,9 +52,10 @@ class TransactionCurrencyFactory
/**
* @param array $data
*
* @return TransactionCurrency|null
* @return TransactionCurrency
* @throws FireflyException
*/
public function create(array $data): ?TransactionCurrency
public function create(array $data): TransactionCurrency
{
try {
/** @var TransactionCurrency $currency */
@@ -69,6 +71,7 @@ class TransactionCurrencyFactory
} catch (QueryException $e) {
$result = null;
Log::error(sprintf('Could not create new currency: %s', $e->getMessage()));
throw new FireflyException('400004: Could not store new currency.');
}
return $result;

View File

@@ -23,6 +23,7 @@ declare(strict_types=1);
namespace FireflyIII\Factory;
use FireflyIII\Exceptions\DuplicateTransactionException;
use FireflyIII\Models\TransactionGroup;
use FireflyIII\User;
@@ -52,10 +53,13 @@ class TransactionGroupFactory
* @param array $data
*
* @return TransactionGroup
* @throws DuplicateTransactionException
*/
public function create(array $data): TransactionGroup
{
$this->journalFactory->setUser($this->user);
$this->journalFactory->setErrorOnHash($data['error_if_duplicate_hash'] ?? false);
$collection = $this->journalFactory->create($data);
$title = $data['group_title'] ?? null;
$title = '' === $title ? null : $title;

View File

@@ -26,10 +26,12 @@ namespace FireflyIII\Factory;
use Carbon\Carbon;
use Exception;
use FireflyIII\Exceptions\DuplicateTransactionException;
use FireflyIII\Exceptions\FireflyException;
use FireflyIII\Models\Account;
use FireflyIII\Models\TransactionCurrency;
use FireflyIII\Models\TransactionJournal;
use FireflyIII\Models\TransactionJournalMeta;
use FireflyIII\Models\TransactionType;
use FireflyIII\Repositories\Account\AccountRepositoryInterface;
use FireflyIII\Repositories\Bill\BillRepositoryInterface;
@@ -72,6 +74,8 @@ class TransactionJournalFactory
private $typeRepository;
/** @var User The user */
private $user;
/** @var bool */
private $errorOnHash;
/**
* Constructor.
@@ -81,7 +85,8 @@ class TransactionJournalFactory
*/
public function __construct()
{
$this->fields = [
$this->errorOnHash = false;
$this->fields = [
// sepa
'sepa_cc', 'sepa_ct_op', 'sepa_ct_id',
'sepa_db', 'sepa_country', 'sepa_ep',
@@ -119,6 +124,7 @@ class TransactionJournalFactory
* @param array $data
*
* @return Collection
* @throws DuplicateTransactionException
*/
public function create(array $data): Collection
{
@@ -193,11 +199,15 @@ class TransactionJournalFactory
* @param NullArrayObject $row
*
* @return TransactionJournal|null
* @throws Exception
* @throws DuplicateTransactionException
*/
private function createJournal(NullArrayObject $row): ?TransactionJournal
{
$row['import_hash_v2'] = $this->hashArray($row);
$this->errorIfDuplicate($row['import_hash_v2']);
/** Some basic fields */
$type = $this->typeRepository->findTransactionType(null, $row['type']);
$carbon = $row['date'] ?? new Carbon;
@@ -212,16 +222,33 @@ class TransactionJournalFactory
$carbon->setTimezone(config('app.timezone'));
/** Get source + destination account */
Log::debug(sprintf('Source info: ID #%d, name "%s"', $row['source_id'], $row['source_name']));
Log::debug(sprintf('Destination info: ID #%d, name "%s"', $row['destination_id'], $row['destination_name']));
Log::debug(sprintf('Currency is #%d (%s)', $currency->id, $currency->code));
try {
// validate source and destination using a new Validator.
$this->validateAccounts($row);
/** create or get source and destination accounts */
$sourceAccount = $this->getAccount($type->type, 'source', (int)$row['source_id'], $row['source_name']);
$destinationAccount = $this->getAccount($type->type, 'destination', (int)$row['destination_id'], $row['destination_name']);
$sourceInfo = [
'id' => (int)$row['source_id'],
'name' => $row['source_name'],
'iban' => $row['source_iban'],
'number' => $row['source_number'],
'bic' => $row['source_bic'],
];
$destInfo = [
'id' => (int)$row['destination_id'],
'name' => $row['destination_name'],
'iban' => $row['destination_iban'],
'number' => $row['destination_number'],
'bic' => $row['destination_bic'],
];
Log::debug('Source info:', $sourceInfo);
Log::debug('Destination info:', $destInfo);
$sourceAccount = $this->getAccount($type->type, 'source', $sourceInfo);
$destinationAccount = $this->getAccount($type->type, 'destination', $destInfo);
// @codeCoverageIgnoreStart
} catch (FireflyException $e) {
Log::error('Could not validate source or destination.');
@@ -305,7 +332,7 @@ class TransactionJournalFactory
$transactionFactory->setCurrency($sourceCurrency);
$transactionFactory->setForeignCurrency($sourceForeignCurrency);
$transactionFactory->setReconciled($row['reconciled'] ?? false);
$transactionFactory->createNegative((string)$row['amount'], $row['foreign_amount']);
$transactionFactory->createNegative((string)$row['amount'], (string)$row['foreign_amount']);
// and the destination one:
/** @var TransactionFactory $transactionFactory */
@@ -316,7 +343,7 @@ class TransactionJournalFactory
$transactionFactory->setCurrency($destCurrency);
$transactionFactory->setForeignCurrency($destForeignCurrency);
$transactionFactory->setReconciled($row['reconciled'] ?? false);
$transactionFactory->createPositive((string)$row['amount'], $row['foreign_amount']);
$transactionFactory->createPositive((string)$row['amount'], (string)$row['foreign_amount']);
// verify that journal has two transactions. Otherwise, delete and cancel.
// TODO this can't be faked so it can't be tested.
@@ -359,6 +386,30 @@ class TransactionJournalFactory
return $journal;
}
/**
* If this transaction already exists, throw an error.
*
* @param string $hash
*
* @throws DuplicateTransactionException
*/
private function errorIfDuplicate(string $hash): void
{
if (false === $this->errorOnHash) {
return;
}
$result = null;
if ($this->errorOnHash) {
/** @var TransactionJournalMeta $result */
$result = TransactionJournalMeta::where('data', json_encode($hash, JSON_THROW_ON_ERROR))
->with(['transactionJournal', 'transactionJournal.transactionGroup'])
->first();
}
if (null !== $result) {
throw new DuplicateTransactionException(sprintf('Duplicate of transaction #%d.', $result->transactionJournal->transaction_group_id));
}
}
/**
* @param TransactionCurrency|null $currency
* @param Account $account
@@ -372,8 +423,10 @@ class TransactionJournalFactory
// return user's default:
return app('amount')->getDefaultCurrencyByUser($this->user);
}
$result = $preference ?? $currency;
Log::debug(sprintf('Currency is now #%d (%s) because of account #%d (%s)', $result->id, $result->code, $account->id, $account->name));
return $preference ?? $currency;
return $result;
}
/**
@@ -466,4 +519,14 @@ class TransactionJournalFactory
throw new FireflyException(sprintf('Destination: %s', $this->accountValidator->destError)); // @codeCoverageIgnore
}
}
/**
* @param bool $errorOnHash
*/
public function setErrorOnHash(bool $errorOnHash): void
{
$this->errorOnHash = $errorOnHash;
}
}

View File

@@ -26,6 +26,7 @@ namespace FireflyIII\Handlers\Events;
use FireflyIII\Events\RequestedVersionCheckStatus;
use FireflyIII\Exceptions\FireflyException;
use FireflyIII\Helpers\Update\UpdateTrait;
use FireflyIII\Models\Configuration;
use FireflyIII\Repositories\User\UserRepositoryInterface;
@@ -78,8 +79,15 @@ class VersionCheckEventHandler
}
// last check time was more than a week ago.
Log::debug('Have not checked for a new version in a week!');
try {
$latestRelease = $this->getLatestRelease();
} catch (FireflyException $e) {
Log::error($e);
session()->flash('error', (string)trans('firefly.update_check_error'));
$latestRelease = $this->getLatestRelease();
// softfail.
return;
}
$versionCheck = $this->versionCheck($latestRelease);
$resultString = $this->parseResult($versionCheck, $latestRelease);
if (0 !== $versionCheck && '' !== $resultString) {

View File

@@ -162,6 +162,13 @@ class AttachmentHelper implements AttachmentHelperInterface
return false;
// @codeCoverageIgnoreEnd
}
if ('' === $content) {
Log::error('Cannot upload empty file.');
return false;
}
$path = stream_get_meta_data($resource)['uri'];
fwrite($resource, $content);
$finfo = finfo_open(FILEINFO_MIME_TYPE);
@@ -199,6 +206,7 @@ class AttachmentHelper implements AttachmentHelperInterface
if (!($model instanceof Model)) {
return false; // @codeCoverageIgnore
}
Log::debug(sprintf('Now in saveAttachmentsForModel for model %s', get_class($model)));
if (is_array($files)) {
Log::debug('$files is an array.');
@@ -362,6 +370,11 @@ class AttachmentHelper implements AttachmentHelperInterface
if (!$this->validMime($file)) {
$result = false;
}
if (0 === $file->getSize()) {
Log::error('Cannot upload empty file.');
$result = false;
}
// @codeCoverageIgnoreStart
// can't seem to reach this point.
if (true === $result && !$this->validSize($file)) {

View File

@@ -70,6 +70,8 @@ class GroupCollector implements GroupCollectorInterface
private $total;
/** @var User The user object. */
private $user;
/** @var array */
private $integerFields;
/**
* Group collector constructor.
@@ -84,7 +86,23 @@ class GroupCollector implements GroupCollectorInterface
$this->hasBudgetInformation = false;
$this->hasBillInformation = false;
$this->hasJoinedTagTables = false;
$this->integerFields = [
'transaction_group_id',
'user_id',
'transaction_journal_id',
'transaction_type_id',
'order',
'source_transaction_id',
'source_account_id',
'currency_id',
'currency_decimal_places',
'foreign_currency_id',
'foreign_currency_decimal_places',
'destination_transaction_id',
'destination_account_id',
'category_id',
'budget_id'
];
$this->total = 0;
$this->fields = [
# group
@@ -903,6 +921,22 @@ class GroupCollector implements GroupCollectorInterface
return $this;
}
/**
* Convert a selected set of fields to arrays.
*
* @param array $array
*
* @return array
*/
private function convertToInteger(array $array): array
{
foreach ($this->integerFields as $field) {
$array[$field] = isset($array[$field]) ? (int)$array[$field] : null;
}
return $array;
}
/**
* Join table to get tag information.
*/
@@ -965,8 +999,8 @@ class GroupCollector implements GroupCollectorInterface
// make new array
$parsedGroup = $this->parseAugmentedGroup($augumentedJournal);
$groupArray = [
'id' => $augumentedJournal->transaction_group_id,
'user_id' => $augumentedJournal->user_id,
'id' => (int)$augumentedJournal->transaction_group_id,
'user_id' => (int)$augumentedJournal->user_id,
'title' => $augumentedJournal->transaction_group_title,
'transaction_type' => $parsedGroup['transaction_type_type'],
'count' => 1,
@@ -1014,6 +1048,10 @@ class GroupCollector implements GroupCollectorInterface
} catch (Exception $e) {
Log::error($e->getMessage());
}
// convert values to integers:
$result = $this->convertToInteger($result);
$result['reconciled'] = 1 === (int)$result['reconciled'];
if (isset($augumentedJournal['tag_id'])) { // assume the other fields are present as well.
$tagId = (int)$augumentedJournal['tag_id'];

View File

@@ -25,8 +25,7 @@ namespace FireflyIII\Helpers\Update;
use Carbon\Carbon;
use FireflyIII\Exceptions\FireflyException;
use FireflyIII\Services\Github\Object\Release;
use FireflyIII\Services\Github\Request\UpdateRequest;
use FireflyIII\Services\FireflyIIIOrg\Update\UpdateRequestInterface;
use Log;
/**
@@ -38,75 +37,54 @@ trait UpdateTrait
/**
* Get object for the latest release from GitHub.
*
* @return Release|null
* @return array
* @throws FireflyException
*/
public function getLatestRelease(): ?Release
public function getLatestRelease(): array
{
Log::debug('Now in getLatestRelease()');
$return = null;
/** @var UpdateRequest $request */
$request = app(UpdateRequest::class);
try {
$request->call();
} catch (FireflyException $e) {
Log::error(sprintf('Could not check for updates: %s', $e->getMessage()));
/** @var UpdateRequestInterface $checker */
$checker = app(UpdateRequestInterface::class);
$channel = app('fireflyconfig')->get('update_channel', 'stable')->data;
return null;
}
// get releases from array.
$releases = $request->getReleases();
Log::debug(sprintf('Found %d releases', count($releases)));
if (count($releases) > 0) {
// first entry should be the latest entry:
/** @var Release $first */
$first = reset($releases);
$return = $first;
Log::debug(sprintf('Number of releases found is larger than zero. Return %s ', $first->getTitle()));
}
return $return;
return $checker->getVersion($channel);
}
/**
* Parses the version check result in a human readable sentence.
*
* @param int $versionCheck
* @param Release|null $release
* @param int $versionCheck
* @param array $information
*
* @return string
*/
public function parseResult(int $versionCheck, Release $release = null): string
public function parseResult(int $versionCheck, array $information): string
{
Log::debug(sprintf('Now in parseResult(%d)', $versionCheck));
$current = (string)config('firefly.version');
$return = '';
$triggered = false;
if ($versionCheck === -2) {
Log::debug('-2, so give error.');
$return = (string)trans('firefly.update_check_error');
$triggered = true;
}
if ($versionCheck === -1 && null !== $release) {
$triggered = true;
Log::debug('New version!');
// there is a new FF version!
// has it been released for at least three days?
$today = new Carbon;
$releaseDate = $release->getUpdated();
if ($today->diffInDays($releaseDate) > 3) {
Log::debug('New version is older than 3 days!');
$monthAndDayFormat = (string)trans('config.month_and_day');
$return = (string)trans(
'firefly.update_new_version_alert',
[
'your_version' => $current,
'new_version' => $release->getTitle(),
'date' => $release->getUpdated()->formatLocalized($monthAndDayFormat),
]
);
if (-1 === $versionCheck) {
$triggered = true;
$monthAndDayFormat = (string)trans('config.month_and_day');
$carbon = Carbon::createFromFormat('Y-m-d', $information['date']);
$return = (string)trans(
'firefly.update_new_version_alert',
[
'your_version' => $current,
'new_version' => $information['version'],
'date' => $carbon->formatLocalized($monthAndDayFormat),
]
);
// append warning if beta or alpha.
$isBeta = $information['is_beta'] ?? false;
if (true === $isBeta) {
$return = sprintf('%s %s', $return, trans('firefly.update_version_beta'));
}
$isAlpha = $information['is_alpha'] ?? false;
if (true === $isAlpha) {
$return = sprintf('%s %s', $return, trans('firefly.update_version_alpha'));
}
}
@@ -116,19 +94,16 @@ trait UpdateTrait
// you are running the current version!
$return = (string)trans('firefly.update_current_version_alert', ['version' => $current]);
}
if (1 === $versionCheck && null !== $release) {
if (1 === $versionCheck) {
$triggered = true;
Log::debug('User is running NEWER version.');
// you are running a newer version!
$return = (string)trans('firefly.update_newer_version_alert', ['your_version' => $current, 'new_version' => $release->getTitle()]);
$return = (string)trans('firefly.update_newer_version_alert', ['your_version' => $current, 'new_version' => $information['version']]);
}
// @codeCoverageIgnoreStart
if (false === $triggered) {
Log::debug('No option was triggered.');
$return = (string)trans('firefly.update_check_error');
}
// @codeCoverageIgnoreEnd
return $return;
}
@@ -136,22 +111,16 @@ trait UpdateTrait
/**
* Compare version and store result.
*
* @param Release|null $release
* @param array $information
*
* @return int
*/
public function versionCheck(Release $release = null): int
public function versionCheck(array $information): int
{
Log::debug('Now in versionCheck()');
if (null === $release) {
Log::debug('Release is null, return -2.');
return -2;
}
$current = (string)config('firefly.version');
$latest = $release->getTitle();
$check = version_compare($current, $latest);
Log::debug(sprintf('Comparing %s with %s, result is %s', $current, $latest, $check));
$check = version_compare($current, $information['version']);
Log::debug(sprintf('Comparing %s with %s, result is %s', $current, $information['version'], $check), $information);
return $check;
}

View File

@@ -63,20 +63,19 @@ class IndexController extends Controller
}
/**
* Show list of accounts.
*
* @param Request $request
* @param string $objectType
* @param string $objectType
*
* @return \Illuminate\Contracts\View\Factory|\Illuminate\View\View
*/
public function index(Request $request, string $objectType)
public function inactive(Request $request, string $objectType)
{
$objectType = $objectType ?? 'asset';
$subTitle = (string)trans(sprintf('firefly.%s_accounts', $objectType));
$inactivePage = true;
$subTitle = (string)trans(sprintf('firefly.%s_accounts_inactive', $objectType));
$subTitleIcon = config(sprintf('firefly.subIconsByIdentifier.%s', $objectType));
$types = config(sprintf('firefly.accountTypesByIdentifier.%s', $objectType));
$collection = $this->repository->getAccountsByType($types);
$collection = $this->repository->getInactiveAccountsByType($types);
$total = $collection->count();
$page = 0 === (int)$request->get('page') ? 1 : (int)$request->get('page');
$pageSize = (int)app('preferences')->get('listPageSize', 50)->data;
@@ -105,11 +104,65 @@ class IndexController extends Controller
}
);
// make paginator:
$accounts = new LengthAwarePaginator($accounts, $total, $pageSize, $page);
$accounts->setPath(route('accounts.inactive.index', [$objectType]));
return view('accounts.index', compact('objectType','inactivePage', 'subTitleIcon', 'subTitle', 'page', 'accounts'));
}
/**
* Show list of accounts.
*
* @param Request $request
* @param string $objectType
*
* @return \Illuminate\Contracts\View\Factory|\Illuminate\View\View
*/
public function index(Request $request, string $objectType)
{
$objectType = $objectType ?? 'asset';
$subTitle = (string)trans(sprintf('firefly.%s_accounts', $objectType));
$subTitleIcon = config(sprintf('firefly.subIconsByIdentifier.%s', $objectType));
$types = config(sprintf('firefly.accountTypesByIdentifier.%s', $objectType));
$collection = $this->repository->getActiveAccountsByType($types);
$total = $collection->count();
$page = 0 === (int)$request->get('page') ? 1 : (int)$request->get('page');
$pageSize = (int)app('preferences')->get('listPageSize', 50)->data;
$accounts = $collection->slice(($page - 1) * $pageSize, $pageSize);
$inactiveCount = $this->repository->getInactiveAccountsByType($types)->count();
unset($collection);
/** @var Carbon $start */
$start = clone session('start', Carbon::now()->startOfMonth());
/** @var Carbon $end */
$end = clone session('end', Carbon::now()->endOfMonth());
$start->subDay();
$ids = $accounts->pluck('id')->toArray();
$startBalances = app('steam')->balancesByAccounts($accounts, $start);
$endBalances = app('steam')->balancesByAccounts($accounts, $end);
$activities = app('steam')->getLastActivities($ids);
$accounts->each(
function (Account $account) use ($activities, $startBalances, $endBalances) {
$account->lastActivityDate = $this->isInArray($activities, $account->id);
$account->startBalance = $this->isInArray($startBalances, $account->id);
$account->endBalance = $this->isInArray($endBalances, $account->id);
$account->difference = bcsub($account->endBalance, $account->startBalance);
$account->interest = round($this->repository->getMetaValue($account, 'interest'), 6);
$account->interestPeriod = (string)trans(sprintf('firefly.interest_calc_%s', $this->repository->getMetaValue($account, 'interest_period')));
$account->accountTypeString = (string)trans(sprintf('firefly.account_type_%s', $account->accountType->type));
}
);
// make paginator:
$accounts = new LengthAwarePaginator($accounts, $total, $pageSize, $page);
$accounts->setPath(route('accounts.index', [$objectType]));
return view('accounts.index', compact('objectType', 'subTitleIcon', 'subTitle', 'page', 'accounts'));
return view('accounts.index', compact('objectType', 'inactiveCount', 'subTitleIcon', 'subTitle', 'page', 'accounts'));
}

View File

@@ -23,10 +23,12 @@ declare(strict_types=1);
namespace FireflyIII\Http\Controllers\Admin;
use FireflyIII\Exceptions\FireflyException;
use FireflyIII\Helpers\Update\UpdateTrait;
use FireflyIII\Http\Controllers\Controller;
use FireflyIII\Http\Middleware\IsDemoUser;
use FireflyIII\Http\Middleware\IsSandStormUser;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Log;
@@ -44,7 +46,7 @@ class UpdateController extends Controller
{
parent::__construct();
$this->middleware(
function ($request, $next) {
static function ($request, $next) {
app('view')->share('title', (string)trans('firefly.administration'));
app('view')->share('mainTitleIcon', 'fa-hand-spock-o');
@@ -64,17 +66,25 @@ class UpdateController extends Controller
*/
public function index()
{
$subTitle = (string)trans('firefly.update_check_title');
$subTitleIcon = 'fa-star';
$permission = app('fireflyconfig')->get('permission_update_check', -1);
$selected = $permission->data;
$options = [
$subTitle = (string)trans('firefly.update_check_title');
$subTitleIcon = 'fa-star';
$permission = app('fireflyconfig')->get('permission_update_check', -1);
$channel = app('fireflyconfig')->get('update_channel', 'stable');
$selected = $permission->data;
$channelSelected = $channel->data;
$options = [
-1 => (string)trans('firefly.updates_ask_me_later'),
0 => (string)trans('firefly.updates_do_not_check'),
1 => (string)trans('firefly.updates_enable_check'),
];
return view('admin.update.index', compact('subTitle', 'subTitleIcon', 'selected', 'options'));
$channelOptions = [
'stable' => (string)trans('firefly.update_channel_stable'),
'beta' => (string)trans('firefly.update_channel_beta'),
'alpha' => (string)trans('firefly.update_channel_alpha'),
];
return view('admin.update.index', compact('subTitle', 'subTitleIcon', 'selected', 'options', 'channelSelected', 'channelOptions'));
}
/**
@@ -87,8 +97,11 @@ class UpdateController extends Controller
public function post(Request $request)
{
$checkForUpdates = (int)$request->get('check_for_updates');
$channel = $request->get('update_channel');
$channel = in_array($channel, ['stable', 'beta', 'alpha'], true) ? $channel : 'stable';
app('fireflyconfig')->set('permission_update_check', $checkForUpdates);
app('fireflyconfig')->set('last_update_check', time());
app('fireflyconfig')->set('update_channel', $channel);
session()->flash('success', (string)trans('firefly.configuration_updated'));
return redirect(route('admin.update-check'));
@@ -97,11 +110,33 @@ class UpdateController extends Controller
/**
* Does a manual update check.
*/
public function updateCheck()
public function updateCheck(): JsonResponse
{
$latestRelease = $this->getLatestRelease();
$versionCheck = $this->versionCheck($latestRelease);
$resultString = $this->parseResult($versionCheck, $latestRelease);
$success = true;
$latestRelease = '1.0';
$resultString = '';
$versionCheck = -2;
$channel = app('fireflyconfig')->get('update_channel', 'stable')->data;
try {
$latestRelease = $this->getLatestRelease();
} catch (FireflyException $e) {
Log::error($e->getMessage());
$success = false;
}
// if error, tell the user.
if (false === $success) {
$resultString = (string)trans('firefly.update_check_error');
session()->flash('error', $resultString);
}
// if not, compare and tell the user.
if (true === $success) {
$versionCheck = $this->versionCheck($latestRelease);
$resultString = $this->parseResult($versionCheck, $latestRelease);
}
Log::debug(sprintf('Result string is: "%s"', $resultString));
if (0 !== $versionCheck && '' !== $resultString) {
@@ -110,6 +145,11 @@ class UpdateController extends Controller
}
app('fireflyconfig')->set('last_update_check', time());
return response()->json(['result' => $resultString]);
return response()->json(
[
'result' => $resultString,
'channel' => $channel,
]
);
}
}

View File

@@ -222,11 +222,11 @@ class AttachmentController extends Controller
"default-src 'none'",
"object-src 'none'",
"script-src 'none'",
"style-src 'none'",
"style-src 'self' 'unsafe-inline'",
"base-uri 'none'",
"font-src 'none'",
"connect-src 'none'",
"img-src 'none'",
"img-src 'self'",
"manifest-src 'none'",
];

View File

@@ -127,7 +127,7 @@ class IndexController extends Controller
$array['spent'] = $spentArr[$entry->transaction_currency_id]['sum'] ?? '0';
// budgeted in period:
$budgeted = $this->blRepository->budgeted($entry->start_date, $entry->end_date, $entry->transactionCurrency,);
$budgeted = $this->blRepository->budgeted($entry->start_date, $entry->end_date, $entry->transactionCurrency, );
$array['budgeted'] = $budgeted;
$availableBudgets[] = $array;
unset($spentArr);
@@ -135,7 +135,7 @@ class IndexController extends Controller
if (0 === count($availableBudgets)) {
// get budgeted for default currency:
$budgeted = $this->blRepository->budgeted($start, $end, $defaultCurrency,);
$budgeted = $this->blRepository->budgeted($start, $end, $defaultCurrency, );
$spentArr = $this->opsRepository->sumExpenses($start, $end, null, null, $defaultCurrency);
$spent = $spentArr[$defaultCurrency->id]['sum'] ?? '0';
unset($spentArr);

View File

@@ -144,17 +144,25 @@ class ShowController extends Controller
public function show(Request $request, Budget $budget)
{
/** @var Carbon $start */
$start = session('first', Carbon::now()->startOfYear());
$end = new Carbon;
$allStart = session('first', Carbon::now()->startOfYear());
$allEnd = new Carbon;
// use session range:
$start = session('start');
$end = session('end');
$page = (int)$request->get('page');
$pageSize = (int)app('preferences')->get('listPageSize', 50)->data;
$limits = $this->getLimits($budget, $start, $end);
$limits = $this->getLimits($budget, $allStart, $allEnd);
$repetition = null;
// collector:
/** @var GroupCollectorInterface $collector */
$collector = app(GroupCollectorInterface::class);
$collector->setRange($start, $end)->setBudget($budget)->setLimit($pageSize)->setPage($page)->withBudgetInformation()->withCategoryInformation();
$collector->setRange($start, $end)->setBudget($budget)
->withAccountInformation()
->setLimit($pageSize)->setPage($page)->withBudgetInformation()->withCategoryInformation();
$groups = $collector->getPaginatedGroups();
$groups->setPath(route('budgets.show', [$budget->id]));

View File

@@ -56,7 +56,6 @@ class BudgetController extends Controller
protected $repository;
/** @var BudgetLimitRepositoryInterface */
private $blRepository;
/** @var NoBudgetRepositoryInterface */
private $nbRepository;
@@ -86,8 +85,6 @@ class BudgetController extends Controller
/**
* Shows overview of a single budget.
*
* TODO this chart is not multi-currency aware.
*
* @param Budget $budget
*
* @return JsonResponse
@@ -107,27 +104,47 @@ class BudgetController extends Controller
if ($cache->has()) {
return response()->json($cache->get()); // @codeCoverageIgnore
}
$step = $this->calculateStep($start, $end); // depending on diff, do something with range of chart.
$budgetCollection = new Collection([$budget]);
$chartData = [];
$current = clone $start;
$current = app('navigation')->startOfPeriod($current, $step);
while ($end >= $current) {
$step = $this->calculateStep($start, $end); // depending on diff, do something with range of chart.
$collection = new Collection([$budget]);
$chartData = [];
$loopStart = clone $start;
$loopStart = app('navigation')->startOfPeriod($loopStart, $step);
$currencies = [];
$defaultEntries = [];
// echo '<hr>';
while ($end >= $loopStart) {
/** @var Carbon $currentEnd */
$currentEnd = app('navigation')->endOfPeriod($current, $step);
$loopEnd = app('navigation')->endOfPeriod($loopStart, $step);
if ('1Y' === $step) {
$currentEnd->subDay(); // @codeCoverageIgnore
$loopEnd->subDay(); // @codeCoverageIgnore
}
$spent = $this->opsRepository->spentInPeriod($budgetCollection, new Collection, $current, $currentEnd);
$label = app('navigation')->periodShow($current, $step);
$chartData[$label] = (float)bcmul($spent, '-1');
$current = clone $currentEnd;
$current->addDay();
$spent = $this->opsRepository->sumExpenses($loopStart, $loopEnd, null, $collection);
$label = trim(app('navigation')->periodShow($loopStart, $step));
foreach ($spent as $row) {
$currencyId = $row['currency_id'];
$currencies[$currencyId] = $currencies[$currencyId] ?? $row; // don't mind the field 'sum'
// also store this day's sum:
$currencies[$currencyId]['spent'][$label] = $row['sum'];
}
$defaultEntries[$label] = 0;
// set loop start to the next period:
$loopStart = clone $loopEnd;
$loopStart->addSecond();
}
$data = $this->generator->singleSet((string)trans('firefly.spent'), $chartData);
// loop all currencies:
foreach ($currencies as $currencyId => $currency) {
$chartData[$currencyId] = [
'label' => count($currencies) > 1 ? sprintf('%s (%s)', $budget->name, $currency['currency_name']) : $budget->name,
'type' => 'bar',
'currency_symbol' => $currency['currency_symbol'],
'entries' => $defaultEntries,
];
foreach ($currency['spent'] as $label => $spent) {
$chartData[$currencyId]['entries'][$label] = round(bcmul($spent, '-1'), $currency['currency_decimal_places']);
}
}
$data = $this->generator->multiSet(array_values($chartData));
$cache->store($data);
return response()->json($data);
@@ -379,7 +396,7 @@ class BudgetController extends Controller
$cache->addProperty($end);
$cache->addProperty('chart.budget.frontpage');
if ($cache->has()) {
return response()->json($cache->get()); // @codeCoverageIgnore
//return response()->json($cache->get()); // @codeCoverageIgnore
}
$budgets = $this->repository->getActiveBudgets();
$chartData = [
@@ -390,23 +407,42 @@ class BudgetController extends Controller
/** @var Budget $budget */
foreach ($budgets as $budget) {
// get relevant repetitions:
$limits = $this->blRepository->getBudgetLimits($budget, $start, $end);
$expenses = $this->getExpensesForBudget($limits, $budget, $start, $end);
foreach ($expenses as $name => $row) {
$chartData[0]['entries'][$name] = $row['spent'];
$chartData[1]['entries'][$name] = $row['left'];
$chartData[2]['entries'][$name] = $row['overspent'];
$limits = $this->blRepository->getBudgetLimits($budget, $start, $end);
if (0 === $limits->count()) {
$spent = $this->opsRepository->sumExpenses($start, $end, null, new Collection([$budget]), null);
/** @var array $entry */
foreach ($spent as $entry) {
$title = sprintf('%s (%s)', $budget->name, $entry['currency_name']);
$chartData[0]['entries'][$title] = bcmul($entry['sum'], '-1'); // spent
$chartData[1]['entries'][$title] = 0; // left to spend
$chartData[2]['entries'][$title] = 0; // overspent
}
}
if (0 !== $limits->count()) {
/** @var BudgetLimit $limit */
foreach ($limits as $limit) {
$spent = $this->opsRepository->sumExpenses(
$limit->start_date, $limit->end_date, null, new Collection([$budget]), $limit->transactionCurrency
);
/** @var array $entry */
foreach ($spent as $entry) {
$title = sprintf('%s (%s)', $budget->name, $entry['currency_name']);
if ($limit->start_date->startOfDay()->ne($start->startOfDay()) || $limit->end_date->startOfDay()->ne($end->startOfDay())) {
$title = sprintf(
'%s (%s) (%s - %s)', $budget->name, $entry['currency_name'],
$limit->start_date->formatLocalized($this->monthAndDayFormat),
$limit->end_date->formatLocalized($this->monthAndDayFormat)
);
}
$chartData[0]['entries'][$title] = bcmul($entry['sum'], '-1'); // spent
$chartData[1]['entries'][$title] = 1 === bccomp($limit->amount, bcmul($entry['sum'], '-1')) ? bcadd($entry['sum'], $limit->amount)
: '0';
$chartData[2]['entries'][$title] = 1 === bccomp($limit->amount, bcmul($entry['sum'], '-1')) ?
'0' : bcmul(bcadd($entry['sum'], $limit->amount), '-1');
}
}
}
}
// for no budget:
$spent = $this->spentInPeriodWithout($start, $end);
$name = (string)trans('firefly.no_budget');
if (0 !== bccomp($spent, '0')) {
$chartData[0]['entries'][$name] = bcmul($spent, '-1');
$chartData[1]['entries'][$name] = '0';
$chartData[2]['entries'][$name] = '0';
}
$data = $this->generator->multiSet($chartData);

View File

@@ -174,9 +174,9 @@ class ReportController extends Controller
$data[$currencyId] = $data[$currencyId] ?? [
'currency_id' => $currencyId,
'currency_symbol' => $journal['currency_symbol'],
'currency_code' => $journal['currency_symbol'],
'currency_code' => $journal['currency_code'],
'currency_name' => $journal['currency_name'],
'currency_decimal_places' => $journal['currency_decimal_places'],
'currency_decimal_places' => (int)$journal['currency_decimal_places'],
];
$data[$currencyId][$period] = $data[$currencyId][$period] ?? [
'period' => $period,
@@ -218,7 +218,6 @@ class ReportController extends Controller
// loop all possible periods between $start and $end
$currentStart = clone $start;
while ($currentStart <= $end) {
$currentEnd = app('navigation')->endOfPeriod($currentStart, $preferredRange);
$key = $currentStart->format($format);
$title = $currentStart->formatLocalized($titleFormat);
$income['entries'][$title] = round($currency[$key]['earned'] ?? '0', $currency['currency_decimal_places']);

View File

@@ -55,12 +55,26 @@ class Controller extends BaseController
public function __construct()
{
// is site a demo site?
$isDemoSite = app('fireflyconfig')->get('is_demo_site', config('firefly.configuration.is_demo_site', ), )->data;
app('view')->share('IS_DEMO_SITE', $isDemoSite, );
$isDemoSite = app('fireflyconfig')->get('is_demo_site', config('firefly.configuration.is_demo_site',),)->data;
app('view')->share('IS_DEMO_SITE', $isDemoSite,);
app('view')->share('DEMO_USERNAME', config('firefly.demo_username'));
app('view')->share('DEMO_PASSWORD', config('firefly.demo_password'));
app('view')->share('FF_VERSION', config('firefly.version'));
// share is alpha, is beta
$isAlpha = false;
if (false !== strpos(config('firefly.version'), 'alpha')) {
$isAlpha = true;
}
$isBeta = false;
if (false !== strpos(config('firefly.version'), 'beta')) {
$isBeta = true;
}
app('view')->share('FF_IS_ALPHA', $isAlpha);
app('view')->share('FF_IS_BETA', $isBeta);
$this->middleware(
function ($request, $next) {
// translations for specific strings:

View File

@@ -127,7 +127,6 @@ class DebugController extends Controller
$currentDriver = DB::getDriverName();
$userAgent = $request->header('user-agent');
$isSandstorm = var_export(config('firefly.is_sandstorm'), true);
$isDocker = var_export(config('firefly.is_docker'), true);
$toSandbox = var_export(config('firefly.bunq_use_sandbox'), true);
$trustedProxies = config('firefly.trusted_proxies');
$displayErrors = ini_get('display_errors');
@@ -178,7 +177,7 @@ class DebugController extends Controller
'debug', compact(
'phpVersion', 'extensions', 'localeAttempts', 'appEnv', 'appDebug', 'logChannel', 'appLogLevel', 'now', 'drivers',
'currentDriver', 'loginProvider', 'storageDisks',
'userAgent', 'displayErrors', 'errorReporting', 'phpOs', 'interface', 'logContent', 'cacheDriver', 'isDocker', 'isSandstorm',
'userAgent', 'displayErrors', 'errorReporting', 'phpOs', 'interface', 'logContent', 'cacheDriver', 'isSandstorm',
'trustedProxies',
'toSandbox'
)

View File

@@ -129,7 +129,9 @@ class HomeController extends Controller
foreach ($accounts as $account) {
/** @var GroupCollectorInterface $collector */
$collector = app(GroupCollectorInterface::class);
$collector->setAccounts(new Collection([$account]))->setRange($start, $end)->setLimit(10)->setPage(1);
$collector->setAccounts(new Collection([$account]))
->withAccountInformation()
->setRange($start, $end)->setLimit(10)->setPage(1);
$set = $collector->getGroups();
$transactions[] = [$set, $account];
}

View File

@@ -26,6 +26,7 @@ use Carbon\Carbon;
use FireflyIII\Http\Controllers\Controller;
use FireflyIII\Models\Account;
use FireflyIII\Models\AccountType;
use FireflyIII\Models\PiggyBank;
use FireflyIII\Models\TransactionCurrency;
use FireflyIII\Repositories\Account\AccountRepositoryInterface;
use FireflyIII\Repositories\Budget\BudgetRepositoryInterface;
@@ -282,6 +283,39 @@ class AutoCompleteController extends Controller
return response()->json($return);
}
/**
* An auto-complete specifically for asset accounts and liabilities, used when mass updating and for rules mostly.
*
* @param Request $request
*
* @return JsonResponse
*/
public function assetAccounts(Request $request): JsonResponse
{
$search = $request->get('search');
/** @var AccountRepositoryInterface $repository */
$repository = app(AccountRepositoryInterface::class);
// filter the account types:
$allowedAccountTypes = [AccountType::ASSET, AccountType::LOAN, AccountType::DEBT, AccountType::MORTGAGE];
Log::debug(sprintf('Now in expenseAccounts(%s). Filtering results.', $search), $allowedAccountTypes);
$return = [];
$result = $repository->searchAccount((string)$search, $allowedAccountTypes);
/** @var Account $account */
foreach ($result as $account) {
$return[] = [
'id' => $account->id,
'name' => $account->name,
'type' => $account->accountType->type,
];
}
return response()->json($return);
}
/**
* @return JsonResponse
* @codeCoverageIgnore
@@ -291,7 +325,26 @@ class AutoCompleteController extends Controller
/** @var PiggyBankRepositoryInterface $repository */
$repository = app(PiggyBankRepositoryInterface::class);
return response()->json($repository->getPiggyBanks()->toArray());
/** @var AccountRepositoryInterface $accountRepos */
$accountRepos = app(AccountRepositoryInterface::class);
$piggies = $repository->getPiggyBanks();
$defaultCurrency = \Amount::getDefaultCurrency();
$response = [];
/** @var PiggyBank $piggy */
foreach ($piggies as $piggy) {
$currency = $accountRepos->getAccountCurrency($piggy->account) ?? $defaultCurrency;
$currentAmount = $repository->getRepetition($piggy)->currentamount ?? '0';
$piggy->name_with_amount = sprintf(
'%s (%s / %s)',
$piggy->name,
app('amount')->formatAnything($currency, $currentAmount, false),
app('amount')->formatAnything($currency, $piggy->targetamount, false),
);
$response[] = $piggy->toArray();
}
return response()->json($response);
}
/**

View File

@@ -113,6 +113,7 @@ class IntroController
}
Log::debug(sprintf('Going to mark the following route as NOT done: %s with special "%s" (%s)', $route, $specialPage, $key));
app('preferences')->set($key, false);
app('preferences')->mark();
return response()->json(['message' => (string)trans('firefly.intro_boxes_after_refresh')]);
}

View File

@@ -82,9 +82,6 @@ class IndexController extends Controller
$page = 0 === (int)$request->get('page') ? 1 : (int)$request->get('page');
$pageSize = (int)app('preferences')->get('listPageSize', 50)->data;
$collection = $this->recurring->get();
$today = new Carbon;
$year = new Carbon;
$year->addYear();
// split collection
$total = $collection->count();
@@ -98,6 +95,14 @@ class IndexController extends Controller
$recurring = [];
/** @var Recurrence $recurrence */
foreach ($recurrences as $recurrence) {
$today = new Carbon;
$year = new Carbon;
$year->addYear();
if($recurrence->first_date > $today) {
$today =clone $recurrence->first_date;
$year = clone $today;
$year->addYear();
}
$array = $transformer->transform($recurrence);
$array['first_date'] = new Carbon($array['first_date']);
$array['repeat_until'] = null === $array['repeat_until'] ? null : new Carbon($array['repeat_until']);

View File

@@ -289,8 +289,8 @@ class BudgetController extends Controller
// loop again to get percentages.
foreach ($report as $budgetId => $data) {
foreach ($data['currencies'] as $currencyId => $data) {
$sum = $data['sum'] ?? '0';
foreach ($data['currencies'] as $currencyId => $dataX) {
$sum = $dataX['sum'] ?? '0';
$total = $sums[$currencyId]['sum'] ?? '0';
$pct = '0';
if (0 !== bccomp($sum, '0') && 0 !== bccomp($total, '9')) {
@@ -361,7 +361,8 @@ class BudgetController extends Controller
];
// make sum information:
$report['sums'][$currency->id] = $report['sums'][$currency->id] ?? [
$report['sums'][$currency->id]
= $report['sums'][$currency->id] ?? [
'budgeted' => '0',
'spent' => '0',
'left' => '0',
@@ -411,15 +412,13 @@ class BudgetController extends Controller
// make percentages based on total amount.
foreach ($report['budgets'] as $budgetId => $data) {
foreach ($data['budget_limits'] as $limitId => $entry) {
$currencyId = $entry['currency_id'];
$spent = $entry['spent'];
$totalSpent = $report['sums'][$currencyId]['spent'] ?? '0';
$spentPct = '0';
$currencyId = $entry['currency_id'];
$spent = $entry['spent'];
$totalSpent = $report['sums'][$currencyId]['spent'] ?? '0';
$spentPct = '0';
$budgeted = $entry['budgeted'];
$totalBudgeted = $report['sums'][$currencyId]['budgeted'] ?? '0';;
$budgetedPct = '0';
$totalBudgeted = $report['sums'][$currencyId]['budgeted'] ?? '0';
$budgetedPct = '0';
if (0 !== bccomp($spent, '0') && 0 !== bccomp($totalSpent, '0')) {
$spentPct = round(bcmul(bcdiv($spent, $totalSpent), '100'));
@@ -427,28 +426,13 @@ class BudgetController extends Controller
if (0 !== bccomp($budgeted, '0') && 0 !== bccomp($totalBudgeted, '0')) {
$budgetedPct = round(bcmul(bcdiv($budgeted, $totalBudgeted), '100'));
}
$report['sums'][$currencyId]['budgeted'] = $report['sums'][$currencyId]['budgeted'] ?? '0';
$report['budgets'][$budgetId]['budget_limits'][$limitId]['spent_pct'] = $spentPct;
$report['budgets'][$budgetId]['budget_limits'][$limitId]['budgeted_pct'] = $budgetedPct;
}
}
// var_dump($noBudget);
//
//
// echo '<pre>';
// print_r($report);
// exit;
// try {
$result = view('reports.partials.budgets', compact('report'))->render();
// @codeCoverageIgnoreStart
// } catch (Throwable $e) {
// Log::debug(sprintf('Could not render reports.partials.budgets: %s', $e->getMessage()));
// $result = 'Could not render view.';
// }
// @codeCoverageIgnoreEnd
return $result;
return view('reports.partials.budgets', compact('report'))->render();
}
/**

View File

@@ -714,7 +714,6 @@ class CategoryController extends Controller
/** @var NoCategoryRepositoryInterface $noCatRepository */
$noCatRepository = app(NoCategoryRepositoryInterface::class);
$categories = $repository->getCategories();
$earnedWith = $opsRepository->listIncome($start, $end, $accounts);
$spentWith = $opsRepository->listExpenses($start, $end, $accounts);
$earnedWithout = $noCatRepository->listIncome($start, $end, $accounts);
@@ -745,7 +744,7 @@ class CategoryController extends Controller
$key = sprintf('%s-%s', $currencyId, $categoryId);
$report['categories'][$key] = $report['categories'][$key] ?? [
'id' => $categoryId,
'title' => sprintf('%s (%s)', $categoryRow['name'], $currencyRow['currency_name']),
'title' => $categoryRow['name'],
'currency_id' => $currencyRow['currency_id'],
'currency_symbol' => $currencyRow['currency_symbol'],
'currency_name' => $currencyRow['currency_name'],

View File

@@ -102,6 +102,9 @@ class InstallController extends Controller
'firefly-iii:rename-meta-fields' => [],
'firefly-iii:fix-ob-currencies' => [],
'firefly-iii:fix-long-descriptions' => [],
// final command to set latest version in DB
'firefly-iii:set-latest-version' => ['--james-is-cool' => true],
];
}

View File

@@ -25,7 +25,6 @@ namespace FireflyIII\Http\Controllers\Transaction;
use FireflyIII\Http\Controllers\Controller;
use FireflyIII\Models\TransactionType;
use FireflyIII\Repositories\Account\AccountRepositoryInterface;
/**
@@ -75,9 +74,12 @@ class CreateController extends Controller
$subTitleIcon = 'fa-plus';
$optionalFields = app('preferences')->get('transaction_journal_optional_fields', [])->data;
$allowedOpposingTypes = config('firefly.allowed_opposing_types');
$accountToTypes = config('firefly.account_to_transaction');
$defaultCurrency = app('amount')->getDefaultCurrency();
$previousUri = $this->rememberPreviousUri('transactions.create.uri');
$accountToTypes = config('firefly.account_to_transaction');
$defaultCurrency = app('amount')->getDefaultCurrency();
$previousUri = $this->rememberPreviousUri('transactions.create.uri');
$parts = parse_url($previousUri);
$search = sprintf('?%s', $parts['query'] ?? '');
$previousUri = str_replace($search, '', $previousUri);
session()->put('preFilled', $preFilled);

View File

@@ -69,6 +69,8 @@ class EditController extends Controller
*/
public function edit(TransactionGroup $transactionGroup)
{
app('preferences')->mark();
if (!$this->isEditableGroup($transactionGroup)) {
return $this->redirectGroupToAccount($transactionGroup); // @codeCoverageIgnore
}
@@ -80,6 +82,10 @@ class EditController extends Controller
$defaultCurrency = app('amount')->getDefaultCurrency();
$cash = $repository->getCashAccount();
$previousUri = $this->rememberPreviousUri('transactions.edit.uri');
$parts = parse_url($previousUri);
$search = sprintf('?%s', $parts['query'] ?? '');
$previousUri = str_replace($search, '', $previousUri);
return view('transactions.edit', compact('cash', 'transactionGroup', 'allowedOpposingTypes', 'accountToTypes', 'defaultCurrency', 'previousUri'));
}

View File

@@ -182,7 +182,7 @@ class Kernel extends HttpKernel
'apiX' => [
'auth:api',
'throttle:60,1',
//'throttle:60,1',
'bindings',
],
];

View File

@@ -27,6 +27,7 @@ namespace FireflyIII\Http\Middleware;
use Closure;
use DB;
use FireflyIII\Exceptions\FireflyException;
use FireflyIII\Support\System\OAuthKeys;
use Illuminate\Database\QueryException;
use Log;
@@ -71,6 +72,7 @@ class Installer
if ($this->hasNoTables() || $this->oldDBVersion() || $this->oldVersion()) {
return response()->redirectTo(route('installer.index'));
}
OAuthKeys::verifyKeysRoutine();
// update scheme version
// update firefly version
@@ -182,4 +184,5 @@ class Installer
return false;
}
}

View File

@@ -53,8 +53,6 @@ class Range
// set more view variables:
$this->configureList();
// flash a big fat warning when users use SQLite in Docker
$this->loseItAll($request);
}
return $next($request);
@@ -104,22 +102,6 @@ class Range
app('view')->share('defaultCurrency', $defaultCurrency);
}
/**
* Error when sqlite in docker.
*
* @param Request $request
*/
private function loseItAll(Request $request): void
{
if ('sqlite' === config('database.default') && true === config('firefly.is_docker')) {
// @codeCoverageIgnoreStart
$request->session()->flash(
'error', 'You seem to be using SQLite in a Docker container. Don\'t do this. If the container restarts all your data will be gone.'
);
// @codeCoverageIgnoreEnd
}
}
/**
* Set the range for the current view.
*/

View File

@@ -89,7 +89,7 @@ class RuleFormRequest extends Request
'triggers.*.type' => 'required|in:' . implode(',', $validTriggers),
'triggers.*.value' => sprintf('required_if:triggers.*.type,%s|min:1|ruleTriggerValue', $contextTriggers),
'actions.*.type' => 'required|in:' . implode(',', $validActions),
'actions.*.value' => sprintf('required_if:actions.*.type,%s|min:1|ruleActionValue', $contextActions),
'actions.*.value' => sprintf('required_if:actions.*.type,%s|min:0|max:255|ruleActionValue', $contextActions),
'strict' => 'in:0,1',
];

View File

@@ -49,6 +49,8 @@ class BankDebitCredit implements ConverterInterface
'DR', // https://old.reddit.com/r/FireflyIII/comments/bn2edf/generic_debitcredit_indicator/
'Af', // ING (NL).
'Debet', // Triodos (NL)
'S', // "Soll", German term for debit
'Debit', // Community America (US)
];
if (in_array(trim($value), $negative, true)) {
return -1;

View File

@@ -1,7 +1,7 @@
<?php
/**
* FinTSConfigurationSteps.php
* Copyright (c) 2019 thegrumpydictator@gmail.com
* Copyright (c) 2019 https://github.com/bnw
*
* This file is part of Firefly III (https://github.com/firefly-iii).
*

View File

@@ -1,7 +1,7 @@
<?php
/**
* FinTSJobConfiguration.php
* Copyright (c) 2019 thegrumpydictator@gmail.com
* Copyright (c) 2019 https://github.com/bnw
*
* This file is part of Firefly III (https://github.com/firefly-iii).
*

View File

@@ -1,7 +1,7 @@
<?php
/**
* FinTSRoutine.php
* Copyright (c) 2019 thegrumpydictator@gmail.com
* Copyright (c) 2019 https://github.com/bnw
*
* This file is part of Firefly III (https://github.com/firefly-iii).
*

View File

@@ -1,7 +1,7 @@
<?php
/**
* AbnAmroDescription.php
* Copyright (c) 2019 thegrumpydictator@gmail.com
* Copyright (c) 2019 Robert Horlings
*
* This file is part of Firefly III (https://github.com/firefly-iii).
*

View File

@@ -1,7 +1,7 @@
<?php
/**
* Belfius.php
* Copyright (c) 2019 thegrumpydictator@gmail.com
* Copyright (c) 2019 Sander Kleykens <sander@kleykens.com>
*
* This file is part of Firefly III (https://github.com/firefly-iii).
*

View File

@@ -1,7 +1,7 @@
<?php
/**
* IngBelgium.php
* Copyright (c) 2019 thegrumpydictator@gmail.com
* Copyright (c) 2019 Sander Kleykens <sander@kleykens.com>
*
* This file is part of Firefly III (https://github.com/firefly-iii).
*

View File

@@ -1,7 +1,7 @@
<?php
/**
* IngDescription.php
* Copyright (c) 2019 thegrumpydictator@gmail.com
* Copyright (c) 2019 https://github.com/tomwerf
*
* This file is part of Firefly III (https://github.com/firefly-iii).
*

View File

@@ -1,7 +1,7 @@
<?php
/**
* SnsDescription.php
* Copyright (c) 2019 thegrumpydictator@gmail.com
* Copyright (c) 2019 hugovanduijn@gmail.com.
*
* This file is part of Firefly III (https://github.com/firefly-iii).
*

View File

@@ -319,7 +319,7 @@ class ImportArrayStorage
private function getHash(array $transaction): string
{
unset($transaction['import_hash_v2'], $transaction['original_source']);
$json = json_encode($transaction);
$json = json_encode($transaction, JSON_THROW_ON_ERROR);
if (false === $json) {
// @codeCoverageIgnoreStart
/** @noinspection ForgottenDebugOutputInspection */
@@ -332,8 +332,9 @@ class ImportArrayStorage
}
// @codeCoverageIgnoreEnd
}
$hash = hash('sha256', $json);
Log::debug(sprintf('The hash is: %s', $hash));
Log::debug(sprintf('The hash is: %s', $hash), $transaction);
return $hash;
}
@@ -442,7 +443,8 @@ class ImportArrayStorage
Log::debug(sprintf('Comparison is a hit! (%s)', $hits));
// compare description:
$comparison = '(empty description)' === $transfer['description'] ? '' : $transfer['description'];
// $comparison = '(empty description)' === $transfer['description'] ? '' : $transfer['description'];
$comparison = $transfer['description'];
Log::debug(sprintf('Comparing "%s" to "%s" (original: "%s")', $description, $transfer['description'], $comparison));
if ($description !== $comparison) {
Log::debug('Description is not a match, continue with next transfer.');
@@ -483,7 +485,7 @@ class ImportArrayStorage
/** @noinspection DisconnectedForeachInstructionInspection */
Log::debug('Comparing current transaction source+dest names', $transactionSourceNames);
Log::debug('.. with current transfer source+dest names', $transferSource);
if ($transactionSourceNames === $transferSource) {
if ($transactionSourceNames === $transferSource && $transferSource !== ['', '']) {
// @codeCoverageIgnoreStart
++$hits;
Log::debug(sprintf('Source names are the same! (%d)', $hits));

View File

@@ -134,6 +134,10 @@ class CreateRecurringTransactions implements ShouldQueue
$this->repository->setUser($recurrence->user);
$this->journalRepository->setUser($recurrence->user);
$this->groupRepository->setUser($recurrence->user);
// clear cache for user
app('preferences')->setForUser($recurrence->user, 'lastActivity', microtime());
Log::debug(sprintf('Now at recurrence #%d', $recurrence->id));
$created = $this->handleRepetitions($recurrence);
Log::debug(sprintf('Done with recurrence #%d', $recurrence->id));
@@ -238,8 +242,8 @@ class CreateRecurringTransactions implements ShouldQueue
'recurrence_id' => (int)$recurrence->id,
'order' => $index,
'notes' => (string)trans('firefly.created_from_recurrence', ['id' => $recurrence->id, 'title' => $recurrence->title]),
'tags' => $this->repository->getTags($recurrence),
'piggy_bank_id' => null,
'tags' => $this->repository->getTags($transaction),
'piggy_bank_id' => $this->repository->getPiggyBank($transaction),
'piggy_bank_name' => null,
'bill_id' => null,
'bill_name' => null,
@@ -320,7 +324,7 @@ class CreateRecurringTransactions implements ShouldQueue
Log::info(sprintf('Created new transaction group #%d', $group->id));
// link to piggy:
$this->linkGroupToPiggies($recurrence, $group);
//$this->linkGroupToPiggies($recurrence, $group);
// trigger event:
event(new StoredTransactionGroup($group, $recurrence->apply_rules));

View File

@@ -150,6 +150,21 @@ class Account extends Model
return $this->belongsTo(AccountType::class);
}
/**
* Get the account number.
*
* @return string
*/
public function getAccountNumberAttribute(): string
{
/** @var AccountMeta $metaValue */
$metaValue = $this->accountMeta()
->where('name', 'account_number')
->first();
return $metaValue ? $metaValue->data : '';
}
/**
* @return string
* @codeCoverageIgnore

View File

@@ -42,6 +42,8 @@ use FireflyIII\Repositories\TransactionType\TransactionTypeRepositoryInterface;
use FireflyIII\Repositories\User\UserRepository;
use FireflyIII\Repositories\User\UserRepositoryInterface;
use FireflyIII\Services\Currency\ExchangeRateInterface;
use FireflyIII\Services\FireflyIIIOrg\Update\UpdateRequest;
use FireflyIII\Services\FireflyIIIOrg\Update\UpdateRequestInterface;
use FireflyIII\Services\IP\IpifyOrg;
use FireflyIII\Services\IP\IPRetrievalInterface;
use FireflyIII\Services\Password\PwndVerifierV3;
@@ -64,7 +66,7 @@ use FireflyIII\Support\Twig\Translation;
use FireflyIII\Validation\FireflyValidator;
use Illuminate\Support\ServiceProvider;
use Twig;
use Twig_Extension_Debug;
use Twig\Extension\DebugExtension;
use TwigBridge\Extension\Loader\Functions;
use Validator;
@@ -88,14 +90,14 @@ class FireflyServiceProvider extends ServiceProvider
return new FireflyValidator($translator, $data, $rules, $messages);
}
);
$config = app('config');
Twig::addExtension(new Functions($config));
//$config = app('config');
//Twig::addExtension(new Functions($config));
Twig::addExtension(new General);
Twig::addExtension(new TransactionGroupTwig);
Twig::addExtension(new Translation);
Twig::addExtension(new Rule);
Twig::addExtension(new AmountFormat);
Twig::addExtension(new Twig_Extension_Debug);
//Twig::addExtension(new DebugExtension);
}
/**
@@ -184,6 +186,8 @@ class FireflyServiceProvider extends ServiceProvider
$this->app->bind(HelpInterface::class, Help::class);
$this->app->bind(ReportHelperInterface::class, ReportHelper::class);
$this->app->bind(FiscalHelperInterface::class, FiscalHelper::class);
$this->app->bind(UpdateRequestInterface::class, UpdateRequest::class);
$class = (string)config(sprintf('firefly.cer_providers.%s', (string)config('firefly.cer_provider')));
if ('' === $class) {
throw new FireflyException('Invalid currency exchange rate provider. Cannot continue.');

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