mirror of
https://github.com/firefly-iii/firefly-iii.git
synced 2025-08-17 11:16:39 +00:00
Compare commits
362 Commits
Author | SHA1 | Date | |
---|---|---|---|
|
fabd7b1bfd | ||
|
e57cd13145 | ||
|
515ee0a503 | ||
|
cacbef4f75 | ||
|
2772275e62 | ||
|
34fd66c835 | ||
|
45f5a38512 | ||
|
6874d6469d | ||
|
979c1ad305 | ||
|
80de6c78dc | ||
|
5009cb5d55 | ||
|
0c90171a49 | ||
|
d282cb4e34 | ||
|
976f79b5a6 | ||
|
6693a5166f | ||
|
7b9906d493 | ||
|
f927e61b37 | ||
|
430b498caf | ||
|
983508e291 | ||
|
104a2379f3 | ||
|
e337bcf8bd | ||
|
029774687c | ||
|
be58545999 | ||
|
d774b4e2e3 | ||
|
cb65999124 | ||
|
77e7af75dc | ||
|
714184867c | ||
|
fad2331d80 | ||
|
bb5de8bf7e | ||
|
6f78c96cee | ||
|
883342b2c8 | ||
|
6232858b85 | ||
|
4e4b44d41d | ||
|
daf74e11ed | ||
|
3e2c2e6395 | ||
|
bc5b2085b9 | ||
|
ebcd751145 | ||
|
cdfde3dca8 | ||
|
4e3378451c | ||
|
415fb7294c | ||
|
1e35f0e7e3 | ||
|
b83d06294d | ||
|
7945220825 | ||
|
3e8a4d55ef | ||
|
e1fbdca5c1 | ||
|
1b31d20877 | ||
|
aaaab03995 | ||
|
affa8a317a | ||
|
5a03f3395c | ||
|
8da6ec3f5b | ||
|
a0402ac742 | ||
|
654e0fc74f | ||
|
d3bd1f4124 | ||
|
2aa6067437 | ||
|
356c87da49 | ||
|
0d76fcd564 | ||
|
963c3b2a68 | ||
|
7617fe3510 | ||
|
88724be3aa | ||
|
f845c97955 | ||
|
2c69a2eda2 | ||
|
dcce747e92 | ||
|
c251ca5daf | ||
|
bcb9794315 | ||
|
1a043e35c2 | ||
|
4fef316ddd | ||
|
7196ac3ec9 | ||
|
1c74db30ed | ||
|
00440f282b | ||
|
dfe099f9c6 | ||
|
0dbee47182 | ||
|
46796a8c10 | ||
|
c381067364 | ||
|
19573de5df | ||
|
77359fbc55 | ||
|
45eb758583 | ||
|
1a154a8d45 | ||
|
c40f6f2864 | ||
|
c036c5a2bc | ||
|
5b29e78c4b | ||
|
b54ef9f5e5 | ||
|
b7f48a19e8 | ||
|
c8f1e4bbd7 | ||
|
5cc1369191 | ||
|
16a511cf79 | ||
|
7c78708865 | ||
|
0449430ec3 | ||
|
dd5a179ba1 | ||
|
7c1139e42b | ||
|
caddf3d1c6 | ||
|
54d5778bf3 | ||
|
b1732d0de8 | ||
|
48b5f749a1 | ||
|
a63b8322db | ||
|
2130eef971 | ||
|
5b829b514f | ||
|
1bac3258da | ||
|
d7181100ee | ||
|
ccc82858ad | ||
|
5dd6b23b09 | ||
|
6a08f52fa5 | ||
|
18172b7fdb | ||
|
3eccc56c7a | ||
|
f7545af17a | ||
|
aa4da1e2e1 | ||
|
b4aafefc2b | ||
|
8304ee21f3 | ||
|
ca6479ede6 | ||
|
471cdefcff | ||
|
16b0307b0a | ||
|
2f63090e7c | ||
|
8643034945 | ||
|
6cc4d14fcb | ||
|
389ffa820f | ||
|
60fa0d7244 | ||
|
28d6885178 | ||
|
00f579909e | ||
|
a35bccb940 | ||
|
1cba62aa42 | ||
|
0974591a8f | ||
|
326bef66ee | ||
|
67ba8cee09 | ||
|
08107f7103 | ||
|
f5c075936f | ||
|
d493820cc8 | ||
|
af4a006192 | ||
|
946e3fb540 | ||
|
b19338e2f3 | ||
|
d4a44e6089 | ||
|
c90c181785 | ||
|
b75178a184 | ||
|
a77187135f | ||
|
61e24a41a2 | ||
|
07c7bf1d49 | ||
|
d4cb72cb77 | ||
|
948cdf7e5e | ||
|
e93292d98c | ||
|
7105d34fb3 | ||
|
29847c9711 | ||
|
3db778a2b1 | ||
|
361f78542a | ||
|
15d0e04431 | ||
|
b968ef416a | ||
|
6191362fe0 | ||
|
6d8fd79922 | ||
|
0227879a69 | ||
|
e4d2b121c1 | ||
|
f8941ab507 | ||
|
f3ac8a5888 | ||
|
64ac3927ec | ||
|
a558613189 | ||
|
7535ca9a26 | ||
|
03670e2dfe | ||
|
be797f5353 | ||
|
da38df6e4b | ||
|
2d53eb300a | ||
|
523ea78166 | ||
|
3b33730e48 | ||
|
351272cc27 | ||
|
a293827739 | ||
|
ead2cf92d3 | ||
|
dea9e21382 | ||
|
69725eb8c3 | ||
|
d31bb1f9b6 | ||
|
b64979e45a | ||
|
3dd3d2cabb | ||
|
94e7c3527f | ||
|
1a71d22146 | ||
|
fdc3b80f1f | ||
|
b978de78e4 | ||
|
8b6bd296e1 | ||
|
4d075feed6 | ||
|
e0e16489a1 | ||
|
deeb4933fc | ||
|
be8a0ddb3e | ||
|
49b1a6d844 | ||
|
3c1361e377 | ||
|
a7ab5b7504 | ||
|
0c8229d689 | ||
|
aebf45697f | ||
|
d5d5530a8e | ||
|
8aa7776072 | ||
|
f427267f5b | ||
|
3195dd0db0 | ||
|
e67c62e6cd | ||
|
d319a21b01 | ||
|
f8963179c3 | ||
|
d3cd657501 | ||
|
6c6bb2cd1e | ||
|
1771b3964e | ||
|
351c0ee2d7 | ||
|
1c9c380c8c | ||
|
24455bf980 | ||
|
e21b40b46c | ||
|
29eabf9c8a | ||
|
60e20ceeb1 | ||
|
37b35661be | ||
|
b54bb20617 | ||
|
19ce6b71e2 | ||
|
b68663c977 | ||
|
ac385e2647 | ||
|
bc70174f44 | ||
|
b8668b44a0 | ||
|
86a87cc951 | ||
|
be58b1d2be | ||
|
61733f6553 | ||
|
15e772d9dc | ||
|
ae7b81bf86 | ||
|
2c9ac0982a | ||
|
2df390065b | ||
|
247c9aebf3 | ||
|
0783500eaa | ||
|
c2e542004d | ||
|
806ad918f0 | ||
|
84406a74c3 | ||
|
09990acaa2 | ||
|
a73247ec8c | ||
|
e98d43dd65 | ||
|
dbd68cedc9 | ||
|
e6e8200912 | ||
|
7b1380366b | ||
|
1eda806c17 | ||
|
782ecca6a9 | ||
|
e6338705a7 | ||
|
09226e6f12 | ||
|
5ff1991cdc | ||
|
4ebb6de520 | ||
|
1ba7d65582 | ||
|
4e6063a4f8 | ||
|
85476f3549 | ||
|
ef9714b7e0 | ||
|
8d20029557 | ||
|
0f04b44ca1 | ||
|
44ed45502e | ||
|
5bcafe1311 | ||
|
5a771ccc5f | ||
|
c6145b4a3b | ||
|
b20aeca849 | ||
|
793918f2f3 | ||
|
5d410e577e | ||
|
9ec786ec3a | ||
|
e532b4d4fc | ||
|
58585d03c6 | ||
|
a4f66b3d86 | ||
|
c847621874 | ||
|
86f14885eb | ||
|
173e196bc8 | ||
|
7505db871f | ||
|
946dde8957 | ||
|
9a52cfbfbe | ||
|
b248bd6d0c | ||
|
3fff9ad0a2 | ||
|
a695a1bba2 | ||
|
91e384aae8 | ||
|
1ac95b6fa7 | ||
|
6757b6211d | ||
|
4dfb78837e | ||
|
af50ad3db4 | ||
|
01cb94aabc | ||
|
5ffc5060b9 | ||
|
43d7c956a4 | ||
|
863b07951a | ||
|
2101717edb | ||
|
e7ac1476c5 | ||
|
5d24c1fee1 | ||
|
53eb863f9d | ||
|
3c3ba637b5 | ||
|
be8286b15c | ||
|
6f6087995d | ||
|
2ff8a35171 | ||
|
7f8ed7abb6 | ||
|
2ff0c37c12 | ||
|
c593936b32 | ||
|
c54204ede9 | ||
|
d9132bbee3 | ||
|
c1be98762e | ||
|
c2733e2a8f | ||
|
722cf9b4fe | ||
|
01e31e73e0 | ||
|
dba7d05296 | ||
|
a8709a4a45 | ||
|
49b1435cba | ||
|
6a25b41952 | ||
|
c561f99de6 | ||
|
9d9053d828 | ||
|
c3c9a2f3c0 | ||
|
28465142e9 | ||
|
5473a618c9 | ||
|
ac1a8d8053 | ||
|
15ae9203b6 | ||
|
9dfc2ae20b | ||
|
230de7cbdd | ||
|
feaa003a52 | ||
|
295d01dc16 | ||
|
cbf1fde45e | ||
|
6cc47287d3 | ||
|
4bbe728376 | ||
|
427a90ec85 | ||
|
55ddb26dac | ||
|
891777f079 | ||
|
1655286b67 | ||
|
dd81636bf2 | ||
|
56a43a707d | ||
|
c2f92c6e45 | ||
|
61bd2dc840 | ||
|
f6a675f2e2 | ||
|
85b43055a7 | ||
|
e63f7bcc70 | ||
|
384dd37430 | ||
|
c6b336171c | ||
|
d2f4399a1a | ||
|
02d1bc093c | ||
|
420e493987 | ||
|
0a15479bff | ||
|
a9b76a3679 | ||
|
d1a3cd9044 | ||
|
81735d59f8 | ||
|
1d8da7f9f0 | ||
|
c5f0684030 | ||
|
25867adcb9 | ||
|
d55694cd68 | ||
|
05f069d61e | ||
|
5f6e7ad138 | ||
|
61bc38921e | ||
|
94c660545d | ||
|
4d3907948d | ||
|
e6442dd8af | ||
|
7905e0bd70 | ||
|
f4b1da352d | ||
|
0d33348941 | ||
|
c7c875e95f | ||
|
19d24b3e2a | ||
|
8fed6b6657 | ||
|
b5eafa1910 | ||
|
c15501937f | ||
|
4c743bd5b0 | ||
|
44289cbd95 | ||
|
b2f1642cfe | ||
|
341ef0220c | ||
|
9df88115bc | ||
|
c7273edb5e | ||
|
c398aa2b69 | ||
|
aa786eaaf3 | ||
|
e58a5e12d6 | ||
|
12b3575c5c | ||
|
3ca186dc8f | ||
|
1535f596f6 | ||
|
2cc326caa1 | ||
|
43436ae942 | ||
|
fbfd8475de | ||
|
405752f353 | ||
|
2af98b259a | ||
|
015242a666 | ||
|
54933fda2e | ||
|
852d057a47 | ||
|
1778f0b4f3 | ||
|
6daf083b3f | ||
|
4a7d9b130a | ||
|
4163efba55 | ||
|
db5847b49b | ||
|
6829003f5e | ||
|
91deb22a3f |
80
.env.example
80
.env.example
@@ -10,27 +10,27 @@ APP_DEBUG=false
|
||||
SITE_OWNER=mail@example.com
|
||||
|
||||
# The encryption key for your sessions. Keep this very secure.
|
||||
# If you generate a new one existing data must be considered LOST.
|
||||
# If you generate a new one all existing attachments must be considered LOST.
|
||||
# Change it to a string of exactly 32 chars or use something like `php artisan key:generate` to generate it.
|
||||
# If you use Docker or similar, you can set this variable from a file by using APP_KEY_FILE
|
||||
APP_KEY=SomeRandomStringOf32CharsExactly
|
||||
|
||||
#
|
||||
# Firefly III will launch using this language (for new users and unauthenticated visitors)
|
||||
# For a list of available languages: https://github.com/firefly-iii/firefly-iii/tree/master/resources/lang
|
||||
# For a list of available languages: https://github.com/firefly-iii/firefly-iii/tree/main/resources/lang
|
||||
#
|
||||
# If text is still in English, remember that not everything may have been translated.
|
||||
DEFAULT_LANGUAGE=en_US
|
||||
|
||||
# The locale defines how numbers are formatted.
|
||||
# by default this value is the same as whatever the language is.
|
||||
DEFAULT_LOCALE=equal
|
||||
|
||||
# Change this value to your preferred time zone.
|
||||
# Example: Europe/Amsterdam
|
||||
# For a list of supported time zones, see https://en.wikipedia.org/wiki/List_of_tz_database_time_zones
|
||||
TZ=Europe/Amsterdam
|
||||
|
||||
# This variable must match your installation's external address but keep in mind that
|
||||
# it's only used on the command line as a fallback value.
|
||||
APP_URL=http://localhost
|
||||
|
||||
# TRUSTED_PROXIES is a useful variable when using Docker and/or a reverse proxy.
|
||||
# Set it to ** and reverse proxies work just fine.
|
||||
TRUSTED_PROXIES=
|
||||
@@ -57,14 +57,25 @@ APP_LOG_LEVEL=notice
|
||||
# Database credentials. Make sure the database exists. I recommend a dedicated user for Firefly III
|
||||
# For other database types, please see the FAQ: https://docs.firefly-iii.org/support/faq
|
||||
# If you use Docker or similar, you can set these variables from a file by appending them with _FILE
|
||||
# Use "mysql" for MySQL and MariaDB. Use "sqlite" for SQLite.
|
||||
DB_CONNECTION=pgsql
|
||||
# Use "pgsql" for PostgreSQL and MariaDB. Use "sqlite" for SQLite.
|
||||
DB_CONNECTION=mysql
|
||||
DB_HOST=fireflyiiidb
|
||||
DB_PORT=5432
|
||||
DB_PORT=3306
|
||||
DB_DATABASE=firefly
|
||||
DB_USERNAME=firefly
|
||||
DB_PASSWORD=secret_firefly_password
|
||||
|
||||
# MySQL supports SSL. You can configure it here.
|
||||
# If you use Docker or similar, you can set these variables from a file by appending them with _FILE
|
||||
MYSQL_USE_SSL=false
|
||||
MYSQL_SSL_VERIFY_SERVER_CERT=true
|
||||
# You need to set at least of these options
|
||||
MYSQL_SSL_CAPATH=/etc/ssl/certs/
|
||||
MYSQL_SSL_CA=
|
||||
MYSQL_SSL_CERT=
|
||||
MYSQL_SSL_KEY=
|
||||
MYSQL_SSL_CIPHER=
|
||||
|
||||
# PostgreSQL supports SSL. You can configure it here.
|
||||
# If you use Docker or similar, you can set these variables from a file by appending them with _FILE
|
||||
PGSQL_SSL_MODE=prefer
|
||||
@@ -97,8 +108,8 @@ COOKIE_SECURE=false
|
||||
# If you want Firefly III to mail you, update these settings
|
||||
# For instructions, see: https://docs.firefly-iii.org/advanced-installation/email
|
||||
# If you use Docker or similar, you can set these variables from a file by appending them with _FILE
|
||||
MAIL_DRIVER=log
|
||||
MAIL_HOST=smtp.mailtrap.io
|
||||
MAIL_MAILER=log
|
||||
MAIL_HOST=null
|
||||
MAIL_PORT=2525
|
||||
MAIL_FROM=changeme@example.com
|
||||
MAIL_USERNAME=null
|
||||
@@ -156,6 +167,23 @@ FIXER_API_KEY=
|
||||
# If you use Docker or similar, you can set this variable from a file by appending it with _FILE
|
||||
LOGIN_PROVIDER=eloquent
|
||||
|
||||
#
|
||||
# It's also possible to change the way users are authenticated. You could use Authelia for example.
|
||||
# Authentication via the REMOTE_USER header is supported. Change the value below to "remote_user_guard".
|
||||
#
|
||||
# If you do this please read the documentation for instructions and warnings:
|
||||
# https://docs.firefly-iii.org/advanced-installation/authentication
|
||||
#
|
||||
# This function is available in Firefly III v5.3.0 and higher.
|
||||
AUTHENTICATION_GUARD=web
|
||||
|
||||
#
|
||||
# Likewise, it's impossible to log out users who's authentication is handled by an external system.
|
||||
# Enter a custom URL here that will force a logout (your authentication provider can tell you).
|
||||
# Setting this variable only works when AUTHENTICATION_GUARD != web
|
||||
#
|
||||
CUSTOM_LOGOUT_URI=
|
||||
|
||||
# LDAP connection configuration
|
||||
# OpenLDAP, FreeIPA or ActiveDirectory
|
||||
# # If you use Docker or similar, you can set this variable from a file by appending it with _FILE
|
||||
@@ -170,8 +198,16 @@ ADLDAP_PORT=389
|
||||
ADLDAP_TIMEOUT=5
|
||||
ADLDAP_BASEDN=""
|
||||
ADLDAP_FOLLOW_REFFERALS=false
|
||||
|
||||
# SSL/TLS settings
|
||||
ADLDAP_USE_SSL=false
|
||||
ADLDAP_USE_TLS=false
|
||||
ADLDAP_SSL_CACERTDIR=
|
||||
ADLDAP_SSL_CACERTFILE=
|
||||
ADLDAP_SSL_CERTFILE=
|
||||
ADLDAP_SSL_KEYFILE=
|
||||
ADLDAP_SSL_CIPHER_SUITE=
|
||||
ADLDAP_SSL_REQUIRE_CERT=
|
||||
|
||||
# You can set the following variables from a file by appending them with _FILE:
|
||||
ADLDAP_ADMIN_USERNAME=
|
||||
@@ -191,6 +227,7 @@ ADLDAP_AUTH_FIELD=distinguishedname
|
||||
|
||||
# Will allow SSO if your server provides an AUTH_USER field.
|
||||
# You can set the following variables from a file by appending them with _FILE:
|
||||
WINDOWS_SSO_ENABLED=false
|
||||
WINDOWS_SSO_DISCOVER=samaccountname
|
||||
WINDOWS_SSO_KEY=AUTH_USER
|
||||
|
||||
@@ -218,8 +255,9 @@ TRACKER_SITE_ID=
|
||||
TRACKER_URL=
|
||||
|
||||
#
|
||||
# Firefly III could (in the future) collect telemetry on how you use Firefly III.
|
||||
# In order to allow this, change the following variable to true:
|
||||
# Firefly III can collect telemetry on how you use Firefly III. This is opt-in.
|
||||
# In order to allow this, change the following variable to true.
|
||||
# To read more about this feature, go to this page: https://docs.firefly-iii.org/support/telemetry
|
||||
SEND_TELEMETRY=false
|
||||
|
||||
# You can fine tune the start-up of a Docker container by editing these environment variables.
|
||||
@@ -266,7 +304,17 @@ PUSHER_ID=
|
||||
DEMO_USERNAME=
|
||||
DEMO_PASSWORD=
|
||||
USE_ENCRYPTION=false
|
||||
IS_SANDSTORM=false
|
||||
IS_DOCKER=false
|
||||
IS_HEROKU=false
|
||||
BUNQ_USE_SANDBOX=false
|
||||
FIREFLY_III_LAYOUT=v1
|
||||
|
||||
#
|
||||
# If you have trouble configuring your Firefly III installation, DON'T BOTHER setting this variable.
|
||||
# It won't work. It doesn't do ANYTHING. Don't believe the lies you read online. I'm not joking.
|
||||
# This configuration value WILL NOT HELP.
|
||||
#
|
||||
# This variable is ONLY used in some of the emails Firefly III sends around. Nowhere else.
|
||||
# So when configuring anything WEB related this variable doesn't do anything. Nothing
|
||||
#
|
||||
# If you're stuck I understand you get desperate but look SOMEWHERE ELSE.
|
||||
#
|
||||
APP_URL=http://localhost
|
||||
|
12
.github/ISSUE_TEMPLATE/Bug_report.md
vendored
12
.github/ISSUE_TEMPLATE/Bug_report.md
vendored
@@ -16,10 +16,10 @@ I am running Firefly III version x.x.x, and my problem is:
|
||||
<!-- Please add extra info here, such as OS, browser, and the output from the /debug page of your Firefly III installation (click the version at the bottom). -->
|
||||
|
||||
**Bonus points**
|
||||
<!-- Earn bonus points by checking the boxes -->
|
||||
<!-- Before you submit, verify the following please: -->
|
||||
|
||||
- [ ] Nobody reported this bug before
|
||||
- [ ] I have added a stack trace from my log files <!-- (see https://bit.ly/FF3-get-debug-info) -->
|
||||
- [ ] I have added a screenshot.
|
||||
- [ ] I was able to replicate it on the demo site https://demo.firefly-iii.org/
|
||||
<!-- - [ ] I donated money (this is a joke :wink:)-->
|
||||
- I searched and nobody reported this bug before
|
||||
- I have added a stack trace from my log files <!-- (see https://bit.ly/FF3-get-debug-info) -->
|
||||
- I have added a screenshot.
|
||||
- I was able to replicate it on the demo site https://demo.firefly-iii.org/
|
||||
<!-- - I donated money (this is a joke ;)-->
|
||||
|
10
.github/ISSUE_TEMPLATE/Custom.md
vendored
10
.github/ISSUE_TEMPLATE/Custom.md
vendored
@@ -16,8 +16,8 @@ I am running Firefly III version x.x.x.
|
||||
|
||||
<!-- Complete the following checklist for bonus points -->
|
||||
|
||||
- [ ] I have read the FAQ at https://bit.ly/FF3-FAQ
|
||||
- [ ] I added a screenshot
|
||||
- [ ] I added log files <!-- (see https://bit.ly/FF3-get-debug-info) -->
|
||||
- [ ] I was able to replicate the issue on the demo site.
|
||||
<!-- - [ ] I donated money (this is a joke :wink:)-->
|
||||
- I have read the FAQ at https://bit.ly/FF3-FAQ
|
||||
- I added a screenshot
|
||||
- I added log files <!-- (see https://bit.ly/FF3-get-debug-info) -->
|
||||
- I was able to replicate the issue on the demo site.
|
||||
<!-- - I donated money (this is a joke :wink:)-->
|
||||
|
2
.github/contributing.md
vendored
2
.github/contributing.md
vendored
@@ -8,7 +8,7 @@ I am always interested in expanding Firefly III's many features. Just open a tic
|
||||
|
||||
## Pull requests
|
||||
|
||||
When contributing to Firefly III, please first discuss the change you wish to make via issue, email, or any other method. I can only accept pull requests against the `develop` branch, never the `master` branch.
|
||||
When contributing to Firefly III, please first discuss the change you wish to make via issue, email, or any other method. I can only accept pull requests against the `develop` branch, never the `main` branch.
|
||||
|
||||
## Translations :us: :fr: :de:
|
||||
|
||||
|
2
.github/lock.yml
vendored
2
.github/lock.yml
vendored
@@ -32,4 +32,4 @@ setLockReason: true
|
||||
# daysUntilLock: 30
|
||||
|
||||
# Repository to extend settings from
|
||||
# _extends: repo
|
||||
# _extends: repo
|
||||
|
5
.github/pull_request_template.md
vendored
5
.github/pull_request_template.md
vendored
@@ -1,8 +1,9 @@
|
||||
<!--
|
||||
Before you create a new PR, please consider the following two considerations.
|
||||
Before you create a new PR, please consider:
|
||||
|
||||
1) Pull request for the MASTER branch will be closed.
|
||||
1) Pull requests for the MAIN branch will be closed.
|
||||
2) We cannot accept pull requests to add new currencies.
|
||||
3) DO NOT include translations in your PR. Only English US sentences.
|
||||
|
||||
Thanks.
|
||||
-->
|
||||
|
2
.github/security.md
vendored
2
.github/security.md
vendored
@@ -8,5 +8,5 @@ Only the latest version of Firefly III is supported. If you're not running the l
|
||||
|
||||
If you find something that compromises the security of Firefly III, you should [send me a message](mailto:james@firefly-iii.org) as soon as possible. These issues will be fixed immediately. You can also open an issue, but if you feel the issue is sensitive, please drop me a message instead.
|
||||
|
||||
You can use my [GPG key](https://keybase.io/jc5) for extra security. My [GitHub commits](https://github.com/firefly-iii/firefly-iii/commits/master) are almost always signed with this key.
|
||||
You can use my [GPG key](https://keybase.io/jc5) for extra security. My [GitHub commits](https://github.com/firefly-iii/firefly-iii/commits/main) are almost always signed with this key.
|
||||
|
||||
|
2
.gitignore
vendored
2
.gitignore
vendored
@@ -1,4 +1,6 @@
|
||||
/node_modules
|
||||
/frontend/node_modules
|
||||
/frontend/fonts
|
||||
/public/hot
|
||||
/public/storage
|
||||
/storage/*.key
|
||||
|
4
app.json
4
app.json
@@ -3,7 +3,7 @@
|
||||
"description": "A free and open source personal finances manager",
|
||||
"repository": "https://github.com/firefly-iii/firefly-iii",
|
||||
"website": "https://firefly-iii.org/",
|
||||
"logo": "https://raw.githubusercontent.com/firefly-iii/firefly-iii/master/public/mstile-150x150.png",
|
||||
"logo": "https://raw.githubusercontent.com/firefly-iii/firefly-iii/main/public/mstile-150x150.png",
|
||||
"keywords": [
|
||||
"finance",
|
||||
"finances",
|
||||
@@ -62,4 +62,4 @@
|
||||
"value": "base64:If1gJN4pyycXTq+WS5TjneDympKuu+8SKvTl6RZnhJg="
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -50,8 +50,9 @@ use League\Fractal\Resource\Item;
|
||||
class AccountController extends Controller
|
||||
{
|
||||
use AccountFilter, TransactionFilter;
|
||||
/** @var AccountRepositoryInterface The account repository */
|
||||
private $repository;
|
||||
|
||||
private AccountRepositoryInterface $repository;
|
||||
public const RESOURCE_KEY = 'accounts';
|
||||
|
||||
/**
|
||||
* AccountController constructor.
|
||||
@@ -150,7 +151,7 @@ class AccountController extends Controller
|
||||
$transformer = app(AccountTransformer::class);
|
||||
$transformer->setParameters($this->parameters);
|
||||
|
||||
$resource = new FractalCollection($accounts, $transformer, 'accounts');
|
||||
$resource = new FractalCollection($accounts, $transformer, self::RESOURCE_KEY);
|
||||
$resource->setPaginator(new IlluminatePaginatorAdapter($paginator));
|
||||
|
||||
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', 'application/vnd.api+json');
|
||||
@@ -208,7 +209,7 @@ class AccountController extends Controller
|
||||
/** @var AccountTransformer $transformer */
|
||||
$transformer = app(AccountTransformer::class);
|
||||
$transformer->setParameters($this->parameters);
|
||||
$resource = new Item($account, $transformer, 'accounts');
|
||||
$resource = new Item($account, $transformer, self::RESOURCE_KEY);
|
||||
|
||||
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', 'application/vnd.api+json');
|
||||
}
|
||||
@@ -230,7 +231,7 @@ class AccountController extends Controller
|
||||
$transformer = app(AccountTransformer::class);
|
||||
$transformer->setParameters($this->parameters);
|
||||
|
||||
$resource = new Item($account, $transformer, 'accounts');
|
||||
$resource = new Item($account, $transformer, self::RESOURCE_KEY);
|
||||
|
||||
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', 'application/vnd.api+json');
|
||||
}
|
||||
@@ -304,7 +305,7 @@ class AccountController extends Controller
|
||||
/** @var AccountTransformer $transformer */
|
||||
$transformer = app(AccountTransformer::class);
|
||||
$transformer->setParameters($this->parameters);
|
||||
$resource = new Item($account, $transformer, 'accounts');
|
||||
$resource = new Item($account, $transformer, self::RESOURCE_KEY);
|
||||
|
||||
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', 'application/vnd.api+json');
|
||||
}
|
||||
|
@@ -23,10 +23,12 @@ declare(strict_types=1);
|
||||
|
||||
namespace FireflyIII\Api\V1\Controllers;
|
||||
|
||||
use FireflyIII\Api\V1\Middleware\ApiDemoUser;
|
||||
use FireflyIII\Api\V1\Requests\AttachmentStoreRequest;
|
||||
use FireflyIII\Api\V1\Requests\AttachmentUpdateRequest;
|
||||
use FireflyIII\Exceptions\FireflyException;
|
||||
use FireflyIII\Helpers\Attachments\AttachmentHelperInterface;
|
||||
use FireflyIII\Http\Middleware\IsDemoUser;
|
||||
use FireflyIII\Models\Attachment;
|
||||
use FireflyIII\Repositories\Attachment\AttachmentRepositoryInterface;
|
||||
use FireflyIII\Transformers\AttachmentTransformer;
|
||||
@@ -58,6 +60,7 @@ class AttachmentController extends Controller
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
$this->middleware(ApiDemoUser::class)->except(['delete', 'download', 'show', 'index']);
|
||||
$this->middleware(
|
||||
function ($request, $next) {
|
||||
/** @var User $user */
|
||||
@@ -65,6 +68,7 @@ class AttachmentController extends Controller
|
||||
$this->repository = app(AttachmentRepositoryInterface::class);
|
||||
$this->repository->setUser($user);
|
||||
|
||||
|
||||
return $next($request);
|
||||
}
|
||||
);
|
||||
|
@@ -42,10 +42,8 @@ use Illuminate\Http\JsonResponse;
|
||||
class AccountController extends Controller
|
||||
{
|
||||
use ApiSupport;
|
||||
/** @var CurrencyRepositoryInterface */
|
||||
private $currencyRepository;
|
||||
/** @var AccountRepositoryInterface */
|
||||
private $repository;
|
||||
private CurrencyRepositoryInterface $currencyRepository;
|
||||
private AccountRepositoryInterface $repository;
|
||||
|
||||
/**
|
||||
* AccountController constructor.
|
||||
|
@@ -141,49 +141,6 @@ class CategoryController extends Controller
|
||||
}
|
||||
}
|
||||
|
||||
// foreach ([] as $set) {
|
||||
// foreach ($set as $currency) {
|
||||
// $inKey = sprintf('%d-i', $currency['currency_id']);
|
||||
// $outKey = sprintf('%d-e', $currency['currency_id']);
|
||||
// $categories[] = (string)trans('firefly.no_category');
|
||||
// // make data arrays if not yet present.
|
||||
// $tempData[$inKey] = $tempData[$inKey] ?? [
|
||||
// 'currency_id' => $currency['currency_id'],
|
||||
// 'label' => (string)trans('firefly.box_earned_in_currency', ['currency' => $currency['currency_name']]),
|
||||
// 'currency_code' => $currency['currency_code'],
|
||||
// 'currency_symbol' => $currency['currency_symbol'],
|
||||
// 'currency_decimal_places' => $currency['currency_decimal_places'],
|
||||
// 'type' => 'bar', // line, area or bar
|
||||
// 'yAxisID' => 0, // 0, 1, 2
|
||||
// 'entries' => [
|
||||
// // per category:
|
||||
// // "category" => 5,
|
||||
// ],
|
||||
// ];
|
||||
// $tempData[$outKey] = $tempData[$outKey] ?? [
|
||||
// 'currency_id' => $currency['currency_id'],
|
||||
// 'label' => (string)trans('firefly.box_spent_in_currency', ['currency' => $currency['currency_name']]),
|
||||
// 'currency_code' => $currency['currency_code'],
|
||||
// 'currency_symbol' => $currency['currency_symbol'],
|
||||
// 'currency_decimal_places' => $currency['currency_decimal_places'],
|
||||
// 'type' => 'bar', // line, area or bar
|
||||
// 'yAxisID' => 0, // 0, 1, 2
|
||||
// 'entries' => [
|
||||
// // per category:
|
||||
// // "category" => 5,
|
||||
// ],
|
||||
// ];
|
||||
// foreach ($currency['transaction_journals'] as $journal) {
|
||||
// // is it expense or income?
|
||||
// $letter = -1 === bccomp($journal['amount'], '0') ? 'e' : 'i';
|
||||
// $currentKey = sprintf('%d-%s', $currency['currency_id'], $letter);
|
||||
// $name = (string)trans('firefly.no_category');
|
||||
// $tempData[$currentKey]['entries'][$name] = $tempData[$currentKey]['entries'][$name] ?? '0';
|
||||
// $tempData[$currentKey]['entries'][$name] = bcadd($tempData[$currentKey]['entries'][$name], $journal['amount']);
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
// re-sort every spent array and add 0 for missing entries.
|
||||
foreach ($tempData as $index => $set) {
|
||||
$oldSet = $set['entries'];
|
||||
|
@@ -577,7 +577,8 @@ class CurrencyController extends Controller
|
||||
{
|
||||
$manager = $this->getManager();
|
||||
$currency = app('amount')->getDefaultCurrencyByUser(auth()->user());
|
||||
|
||||
$this->parameters->set('defaultCurrency', $currency);
|
||||
|
||||
/** @var CurrencyTransformer $transformer */
|
||||
$transformer = app(CurrencyTransformer::class);
|
||||
$transformer->setParameters($this->parameters);
|
||||
|
@@ -1,181 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* ImportController.php
|
||||
* Copyright (c) 2019 james@firefly-iii.org
|
||||
*
|
||||
* This file is part of Firefly III (https://github.com/firefly-iii).
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace FireflyIII\Api\V1\Controllers;
|
||||
|
||||
use FireflyIII\Helpers\Collector\GroupCollectorInterface;
|
||||
use FireflyIII\Models\ImportJob;
|
||||
use FireflyIII\Repositories\ImportJob\ImportJobRepositoryInterface;
|
||||
use FireflyIII\Support\Http\Api\TransactionFilter;
|
||||
use FireflyIII\Transformers\ImportJobTransformer;
|
||||
use FireflyIII\Transformers\TransactionGroupTransformer;
|
||||
use FireflyIII\User;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Pagination\LengthAwarePaginator;
|
||||
use Illuminate\Support\Collection;
|
||||
use League\Fractal\Pagination\IlluminatePaginatorAdapter;
|
||||
use League\Fractal\Resource\Collection as FractalCollection;
|
||||
use League\Fractal\Resource\Item;
|
||||
|
||||
/**
|
||||
* Class ImportController
|
||||
*
|
||||
* @deprecated
|
||||
* @codeCoverageIgnore
|
||||
*/
|
||||
class ImportController extends Controller
|
||||
{
|
||||
use TransactionFilter;
|
||||
/** @var ImportJobRepositoryInterface Import job repository. */
|
||||
private $repository;
|
||||
|
||||
/**
|
||||
* ImportController constructor.
|
||||
*
|
||||
* @codeCoverageIgnore
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
$this->middleware(
|
||||
function ($request, $next) {
|
||||
/** @var User $user */
|
||||
$user = auth()->user();
|
||||
$this->repository = app(ImportJobRepositoryInterface::class);
|
||||
$this->repository->setUser($user);
|
||||
|
||||
return $next($request);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return JsonResponse
|
||||
* @codeCoverageIgnore
|
||||
*/
|
||||
public function listAll(): JsonResponse
|
||||
{
|
||||
// create some objects:
|
||||
$manager = $this->getManager();
|
||||
$pageSize = (int) app('preferences')->getForUser(auth()->user(), 'listPageSize', 50)->data;
|
||||
|
||||
// get list of accounts. Count it and split it.
|
||||
$collection = $this->repository->get();
|
||||
$count = $collection->count();
|
||||
$importJobs = $collection->slice(($this->parameters->get('page') - 1) * $pageSize, $pageSize);
|
||||
|
||||
// make paginator:
|
||||
$paginator = new LengthAwarePaginator($importJobs, $count, $pageSize, $this->parameters->get('page'));
|
||||
$paginator->setPath(route('api.v1.import.list') . $this->buildParams());
|
||||
|
||||
/** @var ImportJobTransformer $transformer */
|
||||
$transformer = app(ImportJobTransformer::class);
|
||||
$transformer->setParameters($this->parameters);
|
||||
|
||||
$resource = new FractalCollection($importJobs, $transformer, 'import_jobs');
|
||||
$resource->setPaginator(new IlluminatePaginatorAdapter($paginator));
|
||||
|
||||
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', 'application/vnd.api+json');
|
||||
}
|
||||
|
||||
/**
|
||||
* @param ImportJob $importJob
|
||||
*
|
||||
* @return JsonResponse
|
||||
* @codeCoverageIgnore
|
||||
*/
|
||||
public function show(ImportJob $importJob): JsonResponse
|
||||
{
|
||||
$manager = $this->getManager();
|
||||
/** @var ImportJobTransformer $transformer */
|
||||
$transformer = app(ImportJobTransformer::class);
|
||||
$transformer->setParameters($this->parameters);
|
||||
|
||||
$resource = new Item($importJob, $transformer, 'import_jobs');
|
||||
|
||||
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', 'application/vnd.api+json');
|
||||
}
|
||||
|
||||
/**
|
||||
* Show all transactions
|
||||
*
|
||||
* @param Request $request
|
||||
* @param ImportJob $importJob
|
||||
*
|
||||
* @return JsonResponse
|
||||
* @codeCoverageIgnore
|
||||
*/
|
||||
public function transactions(Request $request, ImportJob $importJob): JsonResponse
|
||||
{
|
||||
$pageSize = (int) app('preferences')->getForUser(auth()->user(), 'listPageSize', 50)->data;
|
||||
$type = $request->get('type') ?? 'default';
|
||||
$this->parameters->set('type', $type);
|
||||
|
||||
$types = $this->mapTransactionTypes($this->parameters->get('type'));
|
||||
$manager = $this->getManager();
|
||||
|
||||
$tag = $importJob->tag;
|
||||
$transactions = new Collection();
|
||||
$paginator = new LengthAwarePaginator($transactions, 0, $pageSize);
|
||||
$paginator->setPath(route('api.v1.import.transactions', [$importJob->key]) . $this->buildParams());
|
||||
|
||||
if (null !== $tag) {
|
||||
/** @var User $admin */
|
||||
$admin = auth()->user();
|
||||
|
||||
// use new group collector:
|
||||
/** @var GroupCollectorInterface $collector */
|
||||
$collector = app(GroupCollectorInterface::class);
|
||||
$collector
|
||||
->setUser($admin)
|
||||
// filter on tag.
|
||||
->setTag($tag)
|
||||
// all info needed for the API:
|
||||
->withAPIInformation()
|
||||
// set page size:
|
||||
->setLimit($pageSize)
|
||||
// set page to retrieve
|
||||
->setPage($this->parameters->get('page'))
|
||||
// set types of transactions to return.
|
||||
->setTypes($types);
|
||||
|
||||
if (null !== $this->parameters->get('start') && null !== $this->parameters->get('end')) {
|
||||
$collector->setRange($this->parameters->get('start'), $this->parameters->get('end'));
|
||||
}
|
||||
$paginator = $collector->getPaginatedGroups();
|
||||
$paginator->setPath(route('api.v1.transactions.index') . $this->buildParams());
|
||||
$transactions = $paginator->getCollection();
|
||||
}
|
||||
|
||||
/** @var TransactionGroupTransformer $transformer */
|
||||
$transformer = app(TransactionGroupTransformer::class);
|
||||
$transformer->setParameters($this->parameters);
|
||||
|
||||
$resource = new FractalCollection($transactions, $transformer, 'transactions');
|
||||
$resource->setPaginator(new IlluminatePaginatorAdapter($paginator));
|
||||
|
||||
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', 'application/vnd.api+json');
|
||||
}
|
||||
|
||||
}
|
196
app/Api/V1/Controllers/ObjectGroupController.php
Normal file
196
app/Api/V1/Controllers/ObjectGroupController.php
Normal file
@@ -0,0 +1,196 @@
|
||||
<?php
|
||||
/**
|
||||
* GroupController.php
|
||||
* Copyright (c) 2019 james@firefly-iii.org
|
||||
*
|
||||
* This file is part of Firefly III (https://github.com/firefly-iii).
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace FireflyIII\Api\V1\Controllers;
|
||||
|
||||
use FireflyIII\Api\V1\Requests\ObjectGroupUpdateRequest;
|
||||
use FireflyIII\Models\Account;
|
||||
use FireflyIII\Models\ObjectGroup;
|
||||
use FireflyIII\Repositories\ObjectGroup\ObjectGroupRepositoryInterface;
|
||||
use FireflyIII\Transformers\ObjectGroupTransformer;
|
||||
use FireflyIII\Transformers\PiggyBankTransformer;
|
||||
use FireflyIII\User;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Pagination\LengthAwarePaginator;
|
||||
use League\Fractal\Pagination\IlluminatePaginatorAdapter;
|
||||
use League\Fractal\Resource\Collection as FractalCollection;
|
||||
use League\Fractal\Resource\Item;
|
||||
|
||||
/**
|
||||
* Class GroupController.
|
||||
*
|
||||
*/
|
||||
class ObjectGroupController extends Controller
|
||||
{
|
||||
private ObjectGroupRepositoryInterface $repository;
|
||||
|
||||
/**
|
||||
* ObjectGroupController constructor.
|
||||
*
|
||||
* @codeCoverageIgnore
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
$this->middleware(
|
||||
function ($request, $next) {
|
||||
/** @var User $user */
|
||||
$user = auth()->user();
|
||||
$this->repository = app(ObjectGroupRepositoryInterface::class);
|
||||
$this->repository->setUser($user);
|
||||
|
||||
return $next($request);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove the specified resource from storage.
|
||||
*
|
||||
* @param ObjectGroup $objectGroup
|
||||
*
|
||||
* @codeCoverageIgnore
|
||||
* @return JsonResponse
|
||||
*/
|
||||
public function delete(ObjectGroup $objectGroup): JsonResponse
|
||||
{
|
||||
$this->repository->destroy($objectGroup);
|
||||
|
||||
return response()->json([], 204);
|
||||
}
|
||||
|
||||
/**
|
||||
* Display a listing of the resource.
|
||||
*
|
||||
* @param Request $request
|
||||
*
|
||||
* @codeCoverageIgnore
|
||||
* @return JsonResponse
|
||||
*/
|
||||
public function index(Request $request): JsonResponse
|
||||
{
|
||||
$manager = $this->getManager();
|
||||
|
||||
// types to get, page size:
|
||||
$pageSize = (int) app('preferences')->getForUser(auth()->user(), 'listPageSize', 50)->data;
|
||||
|
||||
// get list of accounts. Count it and split it.
|
||||
$collection = $this->repository->get();
|
||||
$count = $collection->count();
|
||||
$objectGroups = $collection->slice(($this->parameters->get('page') - 1) * $pageSize, $pageSize);
|
||||
|
||||
// make paginator:
|
||||
$paginator = new LengthAwarePaginator($objectGroups, $count, $pageSize, $this->parameters->get('page'));
|
||||
$paginator->setPath(route('api.v1.object-groups.index') . $this->buildParams());
|
||||
|
||||
/** @var ObjectGroupTransformer $transformer */
|
||||
$transformer = app(ObjectGroupTransformer::class);
|
||||
$transformer->setParameters($this->parameters);
|
||||
|
||||
$resource = new FractalCollection($objectGroups, $transformer, 'object_groups');
|
||||
$resource->setPaginator(new IlluminatePaginatorAdapter($paginator));
|
||||
|
||||
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', 'application/vnd.api+json');
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* List all piggies under the object group.
|
||||
*
|
||||
* @param ObjectGroup $objectGroup
|
||||
*
|
||||
* @return JsonResponse
|
||||
* @codeCoverageIgnore
|
||||
*
|
||||
*/
|
||||
public function piggyBanks(ObjectGroup $objectGroup): JsonResponse
|
||||
{
|
||||
// create some objects:
|
||||
$manager = $this->getManager();
|
||||
|
||||
// types to get, page size:
|
||||
$pageSize = (int) app('preferences')->getForUser(auth()->user(), 'listPageSize', 50)->data;
|
||||
|
||||
// get list of piggy banks. Count it and split it.
|
||||
$collection = $this->repository->getPiggyBanks($objectGroup);
|
||||
$count = $collection->count();
|
||||
$piggyBanks = $collection->slice(($this->parameters->get('page') - 1) * $pageSize, $pageSize);
|
||||
|
||||
// make paginator:
|
||||
$paginator = new LengthAwarePaginator($piggyBanks, $count, $pageSize, $this->parameters->get('page'));
|
||||
$paginator->setPath(route('api.v1.object-groups.piggy_banks', [$objectGroup->id]) . $this->buildParams());
|
||||
|
||||
/** @var PiggyBankTransformer $transformer */
|
||||
$transformer = app(PiggyBankTransformer::class);
|
||||
$transformer->setParameters($this->parameters);
|
||||
|
||||
$resource = new FractalCollection($piggyBanks, $transformer, 'piggy_banks');
|
||||
$resource->setPaginator(new IlluminatePaginatorAdapter($paginator));
|
||||
|
||||
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', 'application/vnd.api+json');
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Show single instance.
|
||||
*
|
||||
* @param ObjectGroup $objectGroup
|
||||
*
|
||||
* @return JsonResponse
|
||||
*/
|
||||
public function show(ObjectGroup $objectGroup): JsonResponse
|
||||
{
|
||||
$manager = $this->getManager();
|
||||
|
||||
/** @var ObjectGroupTransformer $transformer */
|
||||
$transformer = app(ObjectGroupTransformer::class);
|
||||
$transformer->setParameters($this->parameters);
|
||||
$resource = new Item($objectGroup, $transformer, 'object_groups');
|
||||
|
||||
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', 'application/vnd.api+json');
|
||||
}
|
||||
|
||||
/**
|
||||
* Update object.
|
||||
*
|
||||
* @param ObjectGroupUpdateRequest $request
|
||||
* @param Account $account
|
||||
*
|
||||
* @return JsonResponse
|
||||
*/
|
||||
public function update(ObjectGroupUpdateRequest $request, ObjectGroup $objectGroup): JsonResponse
|
||||
{
|
||||
$data = $request->getUpdateData();
|
||||
$this->repository->update($objectGroup, $data);
|
||||
$this->repository->sort();
|
||||
$manager = $this->getManager();
|
||||
|
||||
/** @var ObjectGroupTransformer $transformer */
|
||||
$transformer = app(ObjectGroupTransformer::class);
|
||||
$transformer->setParameters($this->parameters);
|
||||
$resource = new Item($objectGroup, $transformer, 'object_groups');
|
||||
|
||||
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', 'application/vnd.api+json');
|
||||
}
|
||||
}
|
@@ -24,6 +24,7 @@ declare(strict_types=1);
|
||||
namespace FireflyIII\Api\V1\Controllers;
|
||||
|
||||
use FireflyIII\Api\V1\Requests\PiggyBankRequest;
|
||||
use FireflyIII\Api\V1\Requests\PiggyBankStoreRequest;
|
||||
use FireflyIII\Exceptions\FireflyException;
|
||||
use FireflyIII\Models\PiggyBank;
|
||||
use FireflyIII\Repositories\PiggyBank\PiggyBankRepositoryInterface;
|
||||
@@ -204,12 +205,12 @@ class PiggyBankController extends Controller
|
||||
/**
|
||||
* Store new object.
|
||||
*
|
||||
* @param PiggyBankRequest $request
|
||||
* @param PiggyBankStoreRequest $request
|
||||
*
|
||||
* @throws FireflyException
|
||||
* @return JsonResponse
|
||||
*/
|
||||
public function store(PiggyBankRequest $request): JsonResponse
|
||||
public function store(PiggyBankStoreRequest $request): JsonResponse
|
||||
{
|
||||
$piggyBank = $this->repository->store($request->getAll());
|
||||
$manager = $this->getManager();
|
||||
@@ -240,7 +241,6 @@ class PiggyBankController extends Controller
|
||||
$this->repository->setCurrentAmount($piggyBank, $data['current_amount']);
|
||||
}
|
||||
|
||||
|
||||
$manager = $this->getManager();
|
||||
/** @var PiggyBankTransformer $transformer */
|
||||
$transformer = app(PiggyBankTransformer::class);
|
||||
|
@@ -1,8 +1,8 @@
|
||||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
/**
|
||||
* AccountController.php
|
||||
* Copyright (c) 2019 james@firefly-iii.org
|
||||
* Copyright (c) 2020 james@firefly-iii.org
|
||||
*
|
||||
* This file is part of Firefly III (https://github.com/firefly-iii).
|
||||
*
|
||||
@@ -20,6 +20,8 @@ declare(strict_types=1);
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace FireflyIII\Api\V1\Controllers\Search;
|
||||
|
||||
use FireflyIII\Api\V1\Controllers\Controller;
|
||||
|
@@ -1,8 +1,8 @@
|
||||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
/**
|
||||
* TransactionController.php
|
||||
* Copyright (c) 2019 james@firefly-iii.org
|
||||
* Copyright (c) 2020 james@firefly-iii.org
|
||||
*
|
||||
* This file is part of Firefly III (https://github.com/firefly-iii).
|
||||
*
|
||||
@@ -20,45 +20,51 @@ declare(strict_types=1);
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace FireflyIII\Api\V1\Controllers\Search;
|
||||
|
||||
use FireflyIII\Api\V1\Controllers\Controller;
|
||||
use FireflyIII\Support\Search\SearchInterface;
|
||||
use FireflyIII\Transformers\TransactionGroupTransformer;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Http\Request;
|
||||
use League\Fractal\Pagination\IlluminatePaginatorAdapter;
|
||||
use League\Fractal\Resource\Collection;
|
||||
|
||||
/**
|
||||
* Class TransactionController
|
||||
*/
|
||||
class TransactionController extends Controller
|
||||
{
|
||||
/** @var string */
|
||||
public const SEARCH_ALL = 'all';
|
||||
/** @var string */
|
||||
public const SEARCH_DESCRIPTION = 'description';
|
||||
/** @var string */
|
||||
public const SEARCH_NOTES = 'notes';
|
||||
/** @var string */
|
||||
public const SEARCH_ACCOUNTS = 'accounts';
|
||||
/** @var array */
|
||||
private $validFields;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
$this->validFields = [
|
||||
self::SEARCH_ALL,
|
||||
self::SEARCH_DESCRIPTION,
|
||||
self::SEARCH_NOTES,
|
||||
self::SEARCH_ACCOUNTS,
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Request $request
|
||||
* @param Request $request
|
||||
* @param SearchInterface $searcher
|
||||
*
|
||||
* @return void
|
||||
* @return JsonResponse
|
||||
*/
|
||||
public function search(Request $request): void
|
||||
public function search(Request $request, SearchInterface $searcher): JsonResponse
|
||||
{
|
||||
die('the route is present but nobody\'s home.');
|
||||
$manager = $this->getManager();
|
||||
$fullQuery = (string) $request->get('query');
|
||||
$page = 0 === (int) $request->get('page') ? 1 : (int) $request->get('page');
|
||||
|
||||
$searcher->parseQuery($fullQuery);
|
||||
$searcher->setPage($page);
|
||||
$searcher->setLimit((int) config('firefly.search_result_limit'));
|
||||
$groups = $searcher->searchTransactions();
|
||||
$parameters = ['search' => $fullQuery];
|
||||
$url = route('api.v1.search.transactions') . '?' . http_build_query($parameters);
|
||||
$groups->setPath($url);
|
||||
$transactions = $groups->getCollection();
|
||||
|
||||
/** @var TransactionGroupTransformer $transformer */
|
||||
$transformer = app(TransactionGroupTransformer::class);
|
||||
$transformer->setParameters($this->parameters);
|
||||
|
||||
$resource = new Collection($transactions, $transformer, 'transactions');
|
||||
$resource->setPaginator(new IlluminatePaginatorAdapter($groups));
|
||||
|
||||
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', 'application/vnd.api+json');
|
||||
}
|
||||
}
|
||||
|
@@ -1,8 +1,8 @@
|
||||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
/**
|
||||
* TransferController.php
|
||||
* Copyright (c) 2019 james@firefly-iii.org
|
||||
* Copyright (c) 2020 james@firefly-iii.org
|
||||
*
|
||||
* This file is part of Firefly III (https://github.com/firefly-iii).
|
||||
*
|
||||
@@ -20,6 +20,8 @@ declare(strict_types=1);
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace FireflyIII\Api\V1\Controllers\Search;
|
||||
|
||||
use FireflyIII\Api\V1\Controllers\Controller;
|
||||
|
@@ -269,6 +269,7 @@ class TransactionController extends Controller
|
||||
*
|
||||
* @param TransactionStoreRequest $request
|
||||
*
|
||||
* @throws FireflyException
|
||||
* @return JsonResponse
|
||||
*/
|
||||
public function store(TransactionStoreRequest $request): JsonResponse
|
||||
@@ -283,7 +284,7 @@ class TransactionController extends Controller
|
||||
try {
|
||||
$transactionGroup = $this->groupRepository->store($data);
|
||||
} catch (DuplicateTransactionException $e) {
|
||||
Log::warning('Caught a duplicate. Return error message.');
|
||||
Log::warning('Caught a duplicate transaction. Return error message.');
|
||||
// return bad validation message.
|
||||
// TODO use Laravel's internal validation thing to do this.
|
||||
$response = [
|
||||
@@ -326,7 +327,7 @@ class TransactionController extends Controller
|
||||
|
||||
$selectedGroup = $collector->getGroups()->first();
|
||||
if (null === $selectedGroup) {
|
||||
throw new NotFoundHttpException(); // @codeCoverageIgnore
|
||||
throw new FireflyException('Cannot find transaction. Possibly, a rule deleted this transaction after its creation.');
|
||||
}
|
||||
/** @var TransactionGroupTransformer $transformer */
|
||||
$transformer = app(TransactionGroupTransformer::class);
|
||||
|
@@ -1,6 +1,6 @@
|
||||
<?php
|
||||
/**
|
||||
* IsSandStormUser.php
|
||||
* ApiDemoUser.php
|
||||
* Copyright (c) 2019 james@firefly-iii.org
|
||||
*
|
||||
* This file is part of Firefly III (https://github.com/firefly-iii).
|
||||
@@ -20,38 +20,40 @@
|
||||
*/
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace FireflyIII\Http\Middleware;
|
||||
namespace FireflyIII\Api\V1\Middleware;
|
||||
|
||||
use Closure;
|
||||
use FireflyIII\Repositories\User\UserRepositoryInterface;
|
||||
use FireflyIII\User;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
|
||||
|
||||
/**
|
||||
* Class IsSandStormUser.
|
||||
* Class ApiDemoUser.
|
||||
*/
|
||||
class IsSandStormUser
|
||||
class ApiDemoUser
|
||||
{
|
||||
/**
|
||||
* Handle an incoming request. May not be a limited user (ie. Sandstorm env. or demo user).
|
||||
* Handle an incoming request.
|
||||
*
|
||||
* @param Request $request
|
||||
* @param Closure $next
|
||||
* @param string|null $guard
|
||||
* @param Request $request
|
||||
* @param Closure $next
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function handle(Request $request, Closure $next, $guard = null)
|
||||
public function handle(Request $request, Closure $next)
|
||||
{
|
||||
if (Auth::guard($guard)->guest()) {
|
||||
// don't care when not logged in, usual stuff applies:
|
||||
/** @var User $user */
|
||||
$user = $request->user();
|
||||
|
||||
if (null === $user) {
|
||||
return $next($request);
|
||||
}
|
||||
|
||||
if (1 === (int) getenv('SANDSTORM')) {
|
||||
app('session')->flash('warning', (string) trans('firefly.sandstorm_not_available'));
|
||||
/** @var UserRepositoryInterface $repository */
|
||||
$repository = app(UserRepositoryInterface::class);
|
||||
|
||||
return response()->redirectTo(route('index'));
|
||||
if ($repository->hasRole($user, 'demo')) {
|
||||
return response('', 403);
|
||||
}
|
||||
|
||||
return $next($request);
|
@@ -70,6 +70,7 @@ class BillRequest extends Request
|
||||
'repeat_freq' => $this->string('repeat_freq'),
|
||||
'skip' => $this->integer('skip'),
|
||||
'active' => $active,
|
||||
'order' => $this->integer('order'),
|
||||
'notes' => $this->nlString('notes'),
|
||||
];
|
||||
}
|
||||
@@ -83,13 +84,13 @@ class BillRequest extends Request
|
||||
public function rules(): array
|
||||
{
|
||||
$rules = [
|
||||
'name' => 'required|between:1,255|uniqueObjectForUser:bills,name',
|
||||
'amount_min' => 'required|numeric|more:0',
|
||||
'amount_max' => 'required|numeric|more:0',
|
||||
'name' => 'between:1,255|uniqueObjectForUser:bills,name',
|
||||
'amount_min' => 'numeric|more:0',
|
||||
'amount_max' => 'numeric|more:0',
|
||||
'currency_id' => 'numeric|exists:transaction_currencies,id',
|
||||
'currency_code' => 'min:3|max:3|exists:transaction_currencies,code',
|
||||
'date' => 'required|date',
|
||||
'repeat_freq' => 'required|in:weekly,monthly,quarterly,half-year,yearly',
|
||||
'date' => 'date',
|
||||
'repeat_freq' => 'in:weekly,monthly,quarterly,half-year,yearly',
|
||||
'skip' => 'between:0,31',
|
||||
'active' => [new IsBoolean],
|
||||
'notes' => 'between:1,65536',
|
||||
|
@@ -1,6 +1,7 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* RabobankDescription.php
|
||||
* ObjectGroupUpdateRequest.php
|
||||
* Copyright (c) 2019 james@firefly-iii.org
|
||||
*
|
||||
* This file is part of Firefly III (https://github.com/firefly-iii).
|
||||
@@ -18,52 +19,53 @@
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace FireflyIII\Import\Specifics;
|
||||
namespace FireflyIII\Api\V1\Requests;
|
||||
|
||||
/**
|
||||
* Class RabobankDescription.
|
||||
* Class AccountObjectGroupUpdateRequestUpdateRequest
|
||||
*
|
||||
* @codeCoverageIgnore
|
||||
* @deprecated
|
||||
*/
|
||||
class RabobankDescription implements SpecificInterface
|
||||
class ObjectGroupUpdateRequest extends Request
|
||||
{
|
||||
|
||||
/**
|
||||
* Description of this specific.
|
||||
* Authorize logged in users.
|
||||
*
|
||||
* @return string
|
||||
* @codeCoverageIgnore
|
||||
* @return bool
|
||||
*/
|
||||
public static function getDescription(): string
|
||||
public function authorize(): bool
|
||||
{
|
||||
return 'import.specific_rabo_descr';
|
||||
// Only allow authenticated users
|
||||
return auth()->check();
|
||||
}
|
||||
|
||||
/**
|
||||
* Name of this specific.
|
||||
*
|
||||
* @return string
|
||||
* @codeCoverageIgnore
|
||||
* @return array
|
||||
*/
|
||||
public static function getName(): string
|
||||
public function getUpdateData(): array
|
||||
{
|
||||
return 'import.specific_rabo_name';
|
||||
return [
|
||||
'title' => $this->string('title'),
|
||||
'order' => $this->integer('order'),
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Run the specific.
|
||||
*
|
||||
* @param array $row
|
||||
* The rules that the incoming request must be matched against.
|
||||
*
|
||||
* @return array
|
||||
*
|
||||
*/
|
||||
public function run(array $row): array
|
||||
public function rules(): array
|
||||
{
|
||||
$row = array_values($row);
|
||||
$objectGroup = $this->route()->parameter('objectGroup');
|
||||
|
||||
return $row;
|
||||
return [
|
||||
'title' => sprintf('min:1|uniqueObjectGroup:%d', $objectGroup->id),
|
||||
'order' => 'numeric',
|
||||
];
|
||||
}
|
||||
}
|
@@ -63,6 +63,7 @@ class PiggyBankRequest extends Request
|
||||
'startdate' => $this->date('start_date'),
|
||||
'targetdate' => $this->date('target_date'),
|
||||
'notes' => $this->nlString('notes'),
|
||||
'order' => $this->integer('order'),
|
||||
];
|
||||
}
|
||||
|
||||
|
86
app/Api/V1/Requests/PiggyBankStoreRequest.php
Normal file
86
app/Api/V1/Requests/PiggyBankStoreRequest.php
Normal file
@@ -0,0 +1,86 @@
|
||||
<?php
|
||||
/**
|
||||
* PiggyBankStoreRequest.php
|
||||
* Copyright (c) 2019 james@firefly-iii.org
|
||||
*
|
||||
* This file is part of Firefly III (https://github.com/firefly-iii).
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace FireflyIII\Api\V1\Requests;
|
||||
|
||||
use FireflyIII\Rules\ZeroOrMore;
|
||||
|
||||
/**
|
||||
*
|
||||
* Class PiggyBankStoreRequest
|
||||
*
|
||||
* @codeCoverageIgnore
|
||||
*/
|
||||
class PiggyBankStoreRequest extends Request
|
||||
{
|
||||
/**
|
||||
* Authorize logged in users.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function authorize(): bool
|
||||
{
|
||||
// Only allow authenticated users
|
||||
return auth()->check();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all data from the request.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getAll(): array
|
||||
{
|
||||
return [
|
||||
'name' => $this->string('name'),
|
||||
'account_id' => $this->integer('account_id'),
|
||||
'targetamount' => $this->string('target_amount'),
|
||||
'current_amount' => $this->string('current_amount'),
|
||||
'startdate' => $this->date('start_date'),
|
||||
'targetdate' => $this->date('target_date'),
|
||||
'notes' => $this->nlString('notes'),
|
||||
'object_group_id' => $this->integer('object_group_id'),
|
||||
'object_group' => $this->string('object_group_name'),
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* The rules that the incoming request must be matched against.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function rules(): array
|
||||
{
|
||||
return [
|
||||
'name' => 'required|between:1,255|uniquePiggyBankForUser',
|
||||
'current_amount' => ['numeric', new ZeroOrMore, 'lte:target_amount'],
|
||||
'account_id' => 'required|numeric|belongsToUser:accounts,id',
|
||||
'object_group_id' => 'numeric|belongsToUser:object_groups,id',
|
||||
'target_amount' => ['numeric', new ZeroOrMore, 'lte:target_amount', 'required'],
|
||||
'start_date' => 'date|nullable',
|
||||
'target_date' => 'date|nullable|after:start_date',
|
||||
'notes' => 'max:65000',
|
||||
];
|
||||
}
|
||||
|
||||
}
|
@@ -1,8 +1,8 @@
|
||||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
/**
|
||||
* TransferRequest.php
|
||||
* Copyright (c) 2019 james@firefly-iii.org
|
||||
* Copyright (c) 2020 james@firefly-iii.org
|
||||
*
|
||||
* This file is part of Firefly III (https://github.com/firefly-iii).
|
||||
*
|
||||
@@ -20,6 +20,8 @@ declare(strict_types=1);
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace FireflyIII\Api\V1\Requests\Search;
|
||||
|
||||
use FireflyIII\Api\V1\Requests\Request;
|
||||
|
@@ -263,17 +263,13 @@ class TransactionUpdateRequest extends Request
|
||||
// TODO if the transaction_journal_id is empty, some fields are mandatory, like the amount!
|
||||
|
||||
// all journals must have a description
|
||||
//$this->validateDescriptions($validator);
|
||||
|
||||
// // validate foreign currency info
|
||||
// $this->validateForeignCurrencyInformation($validator);
|
||||
//
|
||||
|
||||
//
|
||||
// // make sure all splits have valid source + dest info
|
||||
// $this->validateSplitAccounts($validator);
|
||||
// the group must have a description if > 1 journal.
|
||||
// $this->validateGroupDescription($validator);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
@@ -83,8 +83,6 @@ class CorrectDatabase extends Command
|
||||
echo $result;
|
||||
}
|
||||
|
||||
// app('telemetry')->feature('executed-command', $this->signature);
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
@@ -1,5 +1,5 @@
|
||||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
/**
|
||||
* CorrectOpeningBalanceCurrencies.php
|
||||
* Copyright (c) 2020 james@firefly-iii.org
|
||||
@@ -20,6 +20,8 @@ declare(strict_types=1);
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace FireflyIII\Console\Commands\Correction;
|
||||
|
||||
use FireflyIII\Models\Account;
|
||||
@@ -77,8 +79,6 @@ class CorrectOpeningBalanceCurrencies extends Command
|
||||
$this->info('There was nothing to fix in the opening balance transactions.');
|
||||
}
|
||||
|
||||
// app('telemetry')->feature('executed-command', $this->signature);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@@ -78,8 +78,6 @@ class CreateAccessTokens extends Command
|
||||
$end = round(microtime(true) - $start, 2);
|
||||
$this->info(sprintf('Verify access tokens in %s seconds.', $end));
|
||||
|
||||
// app('telemetry')->feature('executed-command', $this->signature);
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
@@ -79,8 +79,6 @@ class CreateLinkTypes extends Command
|
||||
$end = round(microtime(true) - $start, 2);
|
||||
$this->info(sprintf('Verified link types in %s seconds', $end));
|
||||
|
||||
// app('telemetry')->feature('executed-command', $this->signature);
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
@@ -76,8 +76,6 @@ class DeleteEmptyGroups extends Command
|
||||
$end = round(microtime(true) - $start, 2);
|
||||
$this->info(sprintf('Verified empty groups in %s seconds', $end));
|
||||
|
||||
// app('telemetry')->feature('executed-command', $this->signature);
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
@@ -58,8 +58,6 @@ class DeleteEmptyJournals extends Command
|
||||
$this->deleteUnevenJournals();
|
||||
$this->deleteEmptyJournals();
|
||||
|
||||
// app('telemetry')->feature('executed-command', $this->signature);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@@ -62,7 +62,6 @@ class DeleteOrphanedTransactions extends Command
|
||||
$end = round(microtime(true) - $start, 2);
|
||||
$this->info(sprintf('Verified orphans in %s seconds', $end));
|
||||
|
||||
// app('telemetry')->feature('executed-command', $this->signature);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@@ -78,8 +78,6 @@ class DeleteZeroAmount extends Command
|
||||
$end = round(microtime(true) - $start, 2);
|
||||
$this->info(sprintf('Verified zero-amount integrity in %s seconds', $end));
|
||||
|
||||
// app('telemetry')->feature('executed-command', $this->signature);
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
@@ -101,8 +101,6 @@ class EnableCurrencies extends Command
|
||||
$end = round(microtime(true) - $start, 2);
|
||||
$this->info(sprintf('Verified currencies in %s seconds.', $end));
|
||||
|
||||
// app('telemetry')->feature('executed-command', $this->signature);
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
@@ -106,7 +106,6 @@ class FixAccountTypes extends Command
|
||||
$end = round(microtime(true) - $start, 2);
|
||||
$this->info(sprintf('Verifying account types took %s seconds', $end));
|
||||
|
||||
// app('telemetry')->feature('executed-command', $this->signature);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
81
app/Console/Commands/Correction/FixGroupAccounts.php
Normal file
81
app/Console/Commands/Correction/FixGroupAccounts.php
Normal file
@@ -0,0 +1,81 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* FixGroupAccounts.php
|
||||
* Copyright (c) 2020 james@firefly-iii.org
|
||||
*
|
||||
* This file is part of Firefly III (https://github.com/firefly-iii).
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace FireflyIII\Console\Commands\Correction;
|
||||
|
||||
use DB;
|
||||
use FireflyIII\Events\UpdatedTransactionGroup;
|
||||
use FireflyIII\Handlers\Events\UpdatedGroupEventHandler;
|
||||
use FireflyIII\Models\TransactionGroup;
|
||||
use FireflyIII\Models\TransactionJournal;
|
||||
use Illuminate\Console\Command;
|
||||
|
||||
/**
|
||||
* Class FixGroupAccounts
|
||||
*/
|
||||
class FixGroupAccounts extends Command
|
||||
{
|
||||
/**
|
||||
* The console command description.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $description = 'Unify the source / destination accounts of split groups.';
|
||||
/**
|
||||
* The name and signature of the console command.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $signature = 'firefly-iii:unify-group-accounts';
|
||||
|
||||
/**
|
||||
* Execute the console command.
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function handle(): int
|
||||
{
|
||||
// select transaction_group_id, count(transaction_group_id) as the_count from transaction_journals group by transaction_group_id having the_count > 1
|
||||
$groups = [];
|
||||
$res = TransactionJournal
|
||||
::groupBy('transaction_group_id')
|
||||
->get(['transaction_group_id', DB::raw('COUNT(transaction_group_id) as the_count')]);
|
||||
foreach ($res as $journal) {
|
||||
if ((int) $journal->the_count > 1) {
|
||||
$groups[] = (int) $journal->transaction_group_id;
|
||||
}
|
||||
}
|
||||
$handler = new UpdatedGroupEventHandler;
|
||||
foreach($groups as $groupId) {
|
||||
$group = TransactionGroup::find($groupId);
|
||||
$event = new UpdatedTransactionGroup($group);
|
||||
$handler->unifyAccounts($event);
|
||||
}
|
||||
|
||||
$this->line('Updated inconsistent transaction groups.');
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
@@ -1,5 +1,5 @@
|
||||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
/**
|
||||
* FixLongDescriptions.php
|
||||
* Copyright (c) 2020 james@firefly-iii.org
|
||||
@@ -20,6 +20,8 @@ declare(strict_types=1);
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace FireflyIII\Console\Commands\Correction;
|
||||
|
||||
use FireflyIII\Models\TransactionGroup;
|
||||
@@ -75,7 +77,6 @@ class FixLongDescriptions extends Command
|
||||
$end = round(microtime(true) - $start, 2);
|
||||
$this->info(sprintf('Verified all transaction group and journal title lengths in %s seconds.', $end));
|
||||
|
||||
// app('telemetry')->feature('executed-command', $this->signature);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
@@ -98,7 +98,6 @@ class FixPiggies extends Command
|
||||
$end = round(microtime(true) - $start, 2);
|
||||
$this->line(sprintf('Verified the content of %d piggy bank events in %s seconds.', $set->count(), $end));
|
||||
|
||||
// app('telemetry')->feature('executed-command', $this->signature);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
@@ -1,5 +1,5 @@
|
||||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
/**
|
||||
* FixRecurringTransactions.php
|
||||
* Copyright (c) 2020 james@firefly-iii.org
|
||||
@@ -20,6 +20,8 @@ declare(strict_types=1);
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace FireflyIII\Console\Commands\Correction;
|
||||
|
||||
use FireflyIII\Models\Recurrence;
|
||||
@@ -55,9 +57,9 @@ class FixRecurringTransactions extends Command
|
||||
/**
|
||||
* Execute the console command.
|
||||
*
|
||||
* @return mixed
|
||||
* @return int
|
||||
*/
|
||||
public function handle()
|
||||
public function handle(): int
|
||||
{
|
||||
$start = microtime(true);
|
||||
$this->stupidLaravel();
|
||||
@@ -67,7 +69,6 @@ class FixRecurringTransactions extends Command
|
||||
$end = round(microtime(true) - $start, 2);
|
||||
$this->info(sprintf('Corrected recurring transactions %s seconds.', $end));
|
||||
|
||||
// app('telemetry')->feature('executed-command', $this->signature);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@@ -75,7 +75,6 @@ class FixUnevenAmount extends Command
|
||||
$end = round(microtime(true) - $start, 2);
|
||||
$this->info(sprintf('Verified amount integrity in %s seconds', $end));
|
||||
|
||||
// app('telemetry')->feature('executed-command', $this->signature);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@@ -71,7 +71,6 @@ class RemoveBills extends Command
|
||||
$end = round(microtime(true) - $start, 2);
|
||||
$this->info(sprintf('Verified bills / journals in %s seconds', $end));
|
||||
|
||||
// app('telemetry')->feature('executed-command', $this->signature);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
@@ -83,7 +83,6 @@ class RenameMetaFields extends Command
|
||||
$end = round(microtime(true) - $start, 2);
|
||||
$this->info(sprintf('Renamed meta fields in %s seconds', $end));
|
||||
|
||||
// app('telemetry')->feature('executed-command', $this->signature);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@@ -74,7 +74,6 @@ class TransferBudgets extends Command
|
||||
$end = round(microtime(true) - $start, 2);
|
||||
$this->info(sprintf('Verified budget/journals in %s seconds.', $end));
|
||||
|
||||
// app('telemetry')->feature('executed-command', $this->signature);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
@@ -1,6 +1,4 @@
|
||||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
|
||||
/**
|
||||
* CreateDatabase.php
|
||||
@@ -22,6 +20,8 @@ declare(strict_types=1);
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace FireflyIII\Console\Commands;
|
||||
|
||||
use Illuminate\Console\Command;
|
||||
@@ -50,9 +50,9 @@ class CreateDatabase extends Command
|
||||
/**
|
||||
* Execute the console command.
|
||||
*
|
||||
* @return mixed
|
||||
* @return int
|
||||
*/
|
||||
public function handle()
|
||||
public function handle(): int
|
||||
{
|
||||
if ('mysql' !== env('DB_CONNECTION')) {
|
||||
$this->info(sprintf('CreateDB does not apply to "%s", skipped.', env('DB_CONNECTION')));
|
||||
|
@@ -123,7 +123,6 @@ class DecryptDatabase extends Command
|
||||
}
|
||||
$this->info('Done!');
|
||||
|
||||
// app('telemetry')->feature('executed-command', $this->signature);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -160,7 +159,6 @@ class DecryptDatabase extends Command
|
||||
if ('The MAC is invalid.' === $e->getMessage()) {
|
||||
throw new FireflyException($e->getMessage()); // @codeCoverageIgnore
|
||||
}
|
||||
Log::debug(sprintf('Could not decrypt. %s', $e->getMessage()));
|
||||
}
|
||||
|
||||
return $value;
|
||||
|
@@ -1,5 +1,5 @@
|
||||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
/**
|
||||
* ExportData.php
|
||||
* Copyright (c) 2020 james@firefly-iii.org
|
||||
@@ -20,6 +20,8 @@ declare(strict_types=1);
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace FireflyIII\Console\Commands\Export;
|
||||
|
||||
use Carbon\Carbon;
|
||||
@@ -137,11 +139,11 @@ class ExportData extends Command
|
||||
} catch (FireflyException $e) {
|
||||
$this->error(sprintf('Could not store data: %s', $e->getMessage()));
|
||||
|
||||
// app('telemetry')->feature('executed-command-with-error', $this->signature);
|
||||
app('telemetry')->feature('system.command.errored', $this->signature);
|
||||
return 1;
|
||||
}
|
||||
|
||||
// app('telemetry')->feature('executed-command', $this->signature);
|
||||
app('telemetry')->feature('system.command.executed', $this->signature);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@@ -1,341 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* CreateCSVImport.php
|
||||
* Copyright (c) 2020 james@firefly-iii.org
|
||||
*
|
||||
* This file is part of Firefly III (https://github.com/firefly-iii).
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/** @noinspection MultipleReturnStatementsInspection */
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace FireflyIII\Console\Commands\Import;
|
||||
|
||||
use Exception;
|
||||
use FireflyIII\Console\Commands\VerifiesAccessToken;
|
||||
use FireflyIII\Exceptions\FireflyException;
|
||||
use FireflyIII\Import\Routine\RoutineInterface;
|
||||
use FireflyIII\Import\Storage\ImportArrayStorage;
|
||||
use FireflyIII\Models\ImportJob;
|
||||
use FireflyIII\Repositories\ImportJob\ImportJobRepositoryInterface;
|
||||
use FireflyIII\Repositories\User\UserRepositoryInterface;
|
||||
use FireflyIII\User;
|
||||
use Illuminate\Console\Command;
|
||||
use Log;
|
||||
|
||||
/**
|
||||
* Class CreateCSVImport.
|
||||
*
|
||||
* @deprecated
|
||||
* @codeCoverageIgnore
|
||||
*/
|
||||
class CreateCSVImport extends Command
|
||||
{
|
||||
use VerifiesAccessToken;
|
||||
/**
|
||||
* The console command description.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $description = 'Use this command to create a new CSV file import.';
|
||||
/**
|
||||
* The name and signature of the console command.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $signature
|
||||
= 'firefly-iii:csv-import
|
||||
{file? : The CSV file to import.}
|
||||
{configuration? : The configuration file to use for the import.}
|
||||
{--user=1 : The user ID that the import should import for.}
|
||||
{--token= : The user\'s access token.}';
|
||||
/** @var ImportJob */
|
||||
private $importJob;
|
||||
/** @var ImportJobRepositoryInterface */
|
||||
private $importRepository;
|
||||
/** @var UserRepositoryInterface */
|
||||
private $userRepository;
|
||||
|
||||
/**
|
||||
* Run the command.
|
||||
*/
|
||||
public function handle(): int
|
||||
{
|
||||
$this->stupidLaravel();
|
||||
// @codeCoverageIgnoreStart
|
||||
if (!$this->verifyAccessToken()) {
|
||||
$this->errorLine('Invalid access token.');
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (!$this->validArguments()) {
|
||||
$this->errorLine('Invalid arguments.');
|
||||
|
||||
return 1;
|
||||
}
|
||||
// @codeCoverageIgnoreEnd
|
||||
/** @var User $user */
|
||||
$user = $this->userRepository->findNull((int) $this->option('user'));
|
||||
$file = (string) $this->argument('file');
|
||||
$configuration = (string) $this->argument('configuration');
|
||||
|
||||
$this->importRepository->setUser($user);
|
||||
|
||||
$configurationData = json_decode(file_get_contents($configuration), true, 512, JSON_THROW_ON_ERROR);
|
||||
$this->importJob = $this->importRepository->create('file');
|
||||
|
||||
|
||||
// inform user (and log it)
|
||||
$this->infoLine(sprintf('Import file : %s', $file));
|
||||
$this->infoLine(sprintf('Configuration file : %s', $configuration));
|
||||
$this->infoLine(sprintf('User : #%d (%s)', $user->id, $user->email));
|
||||
$this->infoLine(sprintf('Job : %s', $this->importJob->key));
|
||||
|
||||
try {
|
||||
$this->storeFile($file);
|
||||
} catch (FireflyException $e) {
|
||||
$this->errorLine($e->getMessage());
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
// job is ready to go
|
||||
$this->importRepository->setConfiguration($this->importJob, $configurationData);
|
||||
$this->importRepository->setStatus($this->importJob, 'ready_to_run');
|
||||
|
||||
$this->infoLine('The import routine has started. The process is not visible. Please wait.');
|
||||
Log::debug('Go for import!');
|
||||
|
||||
|
||||
// keep repeating this call until job lands on "provider_finished"
|
||||
try {
|
||||
$this->processFile();
|
||||
} catch (FireflyException $e) {
|
||||
$this->errorLine($e->getMessage());
|
||||
|
||||
// app('telemetry')->feature('executed-command-with-error', $this->signature);
|
||||
return 1;
|
||||
}
|
||||
|
||||
// then store data:
|
||||
try {
|
||||
$this->storeData();
|
||||
} catch (FireflyException $e) {
|
||||
$this->errorLine($e->getMessage());
|
||||
|
||||
// app('telemetry')->feature('executed-command-with-error', $this->signature);
|
||||
return 1;
|
||||
}
|
||||
|
||||
// give feedback:
|
||||
$this->giveFeedback();
|
||||
|
||||
// clear cache for user:
|
||||
app('preferences')->setForUser($user, 'lastActivity', microtime());
|
||||
|
||||
// app('telemetry')->feature('executed-command', $this->signature);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $message
|
||||
* @param array|null $data
|
||||
*
|
||||
* @codeCoverageIgnore
|
||||
*/
|
||||
private function errorLine(string $message, array $data = null): void
|
||||
{
|
||||
Log::error($message, $data ?? []);
|
||||
$this->error($message);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
private function giveFeedback(): void
|
||||
{
|
||||
$this->infoLine('Job has finished.');
|
||||
|
||||
|
||||
if (null !== $this->importJob->tag) {
|
||||
$this->infoLine(sprintf('%d transaction(s) have been imported.', $this->importJob->tag->transactionJournals->count()));
|
||||
$this->infoLine(sprintf('You can find your transactions under tag "%s"', $this->importJob->tag->tag));
|
||||
}
|
||||
|
||||
if (null === $this->importJob->tag) {
|
||||
$this->errorLine('No transactions have been imported :(.');
|
||||
}
|
||||
if (count($this->importJob->errors) > 0) {
|
||||
$this->infoLine(sprintf('%d error(s) occurred:', count($this->importJob->errors)));
|
||||
foreach ($this->importJob->errors as $err) {
|
||||
$this->errorLine('- ' . $err);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $message
|
||||
* @param array $data
|
||||
*
|
||||
* @codeCoverageIgnore
|
||||
*/
|
||||
private function infoLine(string $message, array $data = null): void
|
||||
{
|
||||
Log::info($message, $data ?? []);
|
||||
$this->line($message);
|
||||
}
|
||||
|
||||
/**
|
||||
* Keep repeating import call until job lands on "provider_finished".
|
||||
*
|
||||
* @throws FireflyException
|
||||
*/
|
||||
private function processFile(): void
|
||||
{
|
||||
$className = config('import.routine.file');
|
||||
$valid = ['provider_finished'];
|
||||
$count = 0;
|
||||
|
||||
while (!in_array($this->importJob->status, $valid, true) && $count < 6) {
|
||||
Log::debug(sprintf('Now in loop #%d.', $count + 1));
|
||||
/** @var RoutineInterface $routine */
|
||||
$routine = app($className);
|
||||
$routine->setImportJob($this->importJob);
|
||||
try {
|
||||
$routine->run();
|
||||
} catch (FireflyException|Exception $e) {
|
||||
$message = 'The import routine crashed: ' . $e->getMessage();
|
||||
Log::error($message);
|
||||
Log::error($e->getTraceAsString());
|
||||
|
||||
// set job errored out:
|
||||
$this->importRepository->setStatus($this->importJob, 'error');
|
||||
throw new FireflyException($message);
|
||||
}
|
||||
$count++;
|
||||
}
|
||||
$this->importRepository->setStatus($this->importJob, 'provider_finished');
|
||||
$this->importJob->status = 'provider_finished';
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @throws FireflyException
|
||||
*/
|
||||
private function storeData(): void
|
||||
{
|
||||
if ('provider_finished' === $this->importJob->status) {
|
||||
$this->infoLine('Import has finished. Please wait for storage of data.');
|
||||
// set job to be storing data:
|
||||
$this->importRepository->setStatus($this->importJob, 'storing_data');
|
||||
|
||||
/** @var ImportArrayStorage $storage */
|
||||
$storage = app(ImportArrayStorage::class);
|
||||
$storage->setImportJob($this->importJob);
|
||||
|
||||
try {
|
||||
$storage->store();
|
||||
} catch (FireflyException|Exception $e) {
|
||||
$message = 'The import routine crashed: ' . $e->getMessage();
|
||||
Log::error($message);
|
||||
Log::error($e->getTraceAsString());
|
||||
|
||||
// set job errored out:
|
||||
$this->importRepository->setStatus($this->importJob, 'error');
|
||||
throw new FireflyException($message);
|
||||
|
||||
}
|
||||
// set storage to be finished:
|
||||
$this->importRepository->setStatus($this->importJob, 'storage_finished');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Store the supplied file as an attachment to this job.
|
||||
*
|
||||
* @param string $file
|
||||
*
|
||||
* @throws FireflyException
|
||||
*/
|
||||
private function storeFile(string $file): void
|
||||
{
|
||||
// store file as attachment.
|
||||
if ('' !== $file) {
|
||||
$messages = $this->importRepository->storeCLIUpload($this->importJob, 'import_file', $file);
|
||||
if ($messages->count() > 0) {
|
||||
throw new FireflyException($messages->first());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Laravel will execute ALL __construct() methods for ALL commands whenever a SINGLE command is
|
||||
* executed. This leads to noticeable slow-downs and class calls. To prevent this, this method should
|
||||
* be called from the handle method instead of using the constructor to initialize the command.
|
||||
*
|
||||
* @codeCoverageIgnore
|
||||
*/
|
||||
private function stupidLaravel(): void
|
||||
{
|
||||
$this->userRepository = app(UserRepositoryInterface::class);
|
||||
$this->importRepository = app(ImportJobRepositoryInterface::class);
|
||||
}
|
||||
|
||||
/**
|
||||
* Verify user inserts correct arguments.
|
||||
*
|
||||
* @noinspection MultipleReturnStatementsInspection
|
||||
* @return bool
|
||||
* @codeCoverageIgnore
|
||||
*/
|
||||
private function validArguments(): bool
|
||||
{
|
||||
$file = (string) $this->argument('file');
|
||||
$configuration = (string) $this->argument('configuration');
|
||||
$cwd = getcwd();
|
||||
$enabled = (bool) config('import.enabled.file');
|
||||
|
||||
if (false === $enabled) {
|
||||
$this->errorLine('CSV Provider is not enabled.');
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!file_exists($file)) {
|
||||
$this->errorLine(sprintf('Firefly III cannot find file "%s" (working directory: "%s").', $file, $cwd));
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!file_exists($configuration)) {
|
||||
$this->errorLine(sprintf('Firefly III cannot find configuration file "%s" (working directory: "%s").', $configuration, $cwd));
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
$configurationData = json_decode(file_get_contents($configuration), true, 512, JSON_THROW_ON_ERROR);
|
||||
if (null === $configurationData) {
|
||||
$this->errorLine(sprintf('Firefly III cannot read the contents of configuration file "%s" (working directory: "%s").', $configuration, $cwd));
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
@@ -64,7 +64,6 @@ class ReportEmptyObjects extends Command
|
||||
$end = round(microtime(true) - $start, 2);
|
||||
$this->info(sprintf('Report on empty objects finished in %s seconds', $end));
|
||||
|
||||
// app('telemetry')->feature('executed-command', $this->signature);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@@ -69,7 +69,6 @@ class ReportIntegrity extends Command
|
||||
echo $result;
|
||||
}
|
||||
|
||||
// app('telemetry')->feature('executed-command', $this->signature);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
@@ -54,7 +54,6 @@ class ReportSum extends Command
|
||||
{
|
||||
$this->reportSum();
|
||||
|
||||
// app('telemetry')->feature('executed-command', $this->signature);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@@ -1,5 +1,5 @@
|
||||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
/**
|
||||
* RestoreOAuthKeys.php
|
||||
* Copyright (c) 2020 james@firefly-iii.org
|
||||
@@ -20,10 +20,13 @@ declare(strict_types=1);
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace FireflyIII\Console\Commands\Integrity;
|
||||
|
||||
use FireflyIII\Support\System\OAuthKeys;
|
||||
use Illuminate\Console\Command;
|
||||
use Log;
|
||||
|
||||
/**
|
||||
* Class RestoreOAuthKeys
|
||||
@@ -52,7 +55,6 @@ class RestoreOAuthKeys extends Command
|
||||
{
|
||||
$this->restoreOAuthKeys();
|
||||
|
||||
// app('telemetry')->feature('executed-command', $this->signature);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -93,7 +95,9 @@ class RestoreOAuthKeys extends Command
|
||||
*/
|
||||
private function restoreOAuthKeys(): void
|
||||
{
|
||||
Log::debug('Going to restoreOAuthKeys()');
|
||||
if (!$this->keysInDatabase() && !$this->keysOnDrive()) {
|
||||
Log::debug('Keys are not in DB and keys are not on the drive.');
|
||||
$this->generateKeys();
|
||||
$this->storeKeysInDB();
|
||||
$this->line('Generated and stored new keys.');
|
||||
@@ -101,12 +105,14 @@ class RestoreOAuthKeys extends Command
|
||||
return;
|
||||
}
|
||||
if ($this->keysInDatabase() && !$this->keysOnDrive()) {
|
||||
Log::debug('Keys are in DB and keys are not on the drive. Restore.');
|
||||
$this->restoreKeysFromDB();
|
||||
$this->line('Restored OAuth keys from database.');
|
||||
|
||||
return;
|
||||
}
|
||||
if (!$this->keysInDatabase() && $this->keysOnDrive()) {
|
||||
Log::debug('Keys are not in DB and keys are on the drive. Save in DB.');
|
||||
$this->storeKeysInDB();
|
||||
$this->line('Stored OAuth keys in database.');
|
||||
|
||||
|
@@ -86,7 +86,7 @@ class ScanAttachments extends Command
|
||||
$this->line(sprintf('Fixed attachment #%d', $attachment->id));
|
||||
}
|
||||
|
||||
// app('telemetry')->feature('executed-command', $this->signature);
|
||||
app('telemetry')->feature('system.command.executed', $this->signature);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
@@ -1,5 +1,4 @@
|
||||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
/**
|
||||
* SetLatestVersion.php
|
||||
@@ -21,6 +20,8 @@ declare(strict_types=1);
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace FireflyIII\Console\Commands;
|
||||
|
||||
use Illuminate\Console\Command;
|
||||
@@ -59,7 +60,7 @@ class SetLatestVersion extends Command
|
||||
app('fireflyconfig')->set('ff3_version', config('firefly.version'));
|
||||
$this->line('Updated version.');
|
||||
|
||||
// app('telemetry')->feature('executed-command', $this->signature);
|
||||
app('telemetry')->feature('system.command.executed', $this->signature);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@@ -60,7 +60,7 @@ class ApplyRules extends Command
|
||||
*/
|
||||
protected $signature
|
||||
= 'firefly-iii:apply-rules
|
||||
{--user=1 : The user ID that the import should import for.}
|
||||
{--user=1 : The user ID.}
|
||||
{--token= : The user\'s access token.}
|
||||
{--accounts= : A comma-separated list of asset accounts or liabilities to apply your rules to.}
|
||||
{--rule_groups= : A comma-separated list of rule groups to apply. Take the ID\'s of these rule groups from the Firefly III interface.}
|
||||
@@ -112,7 +112,7 @@ class ApplyRules extends Command
|
||||
|
||||
$result = $this->verifyInput();
|
||||
if (false === $result) {
|
||||
// app('telemetry')->feature('executed-command-with-error', $this->signature);
|
||||
app('telemetry')->feature('system.command.errored', $this->signature);
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -131,7 +131,7 @@ class ApplyRules extends Command
|
||||
$this->warn(' --rule_groups=1,2,...');
|
||||
$this->warn(' --all_rules');
|
||||
|
||||
// app('telemetry')->feature('executed-command-with-error', $this->signature);
|
||||
app('telemetry')->feature('system.command.errored', $this->signature);
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -167,7 +167,7 @@ class ApplyRules extends Command
|
||||
$this->line('');
|
||||
$this->line('Done!');
|
||||
|
||||
// app('telemetry')->feature('executed-command', $this->signature);
|
||||
app('telemetry')->feature('system.command.executed', $this->signature);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@@ -94,10 +94,10 @@ class Cron extends Command
|
||||
}
|
||||
|
||||
/*
|
||||
* Fire telemetry cron job (disabled):
|
||||
* Fire telemetry cron job
|
||||
*/
|
||||
try {
|
||||
//$this->telemetryCronJob($force, $date);
|
||||
$this->telemetryCronJob($force, $date);
|
||||
} catch (FireflyException $e) {
|
||||
Log::error($e->getMessage());
|
||||
Log::error($e->getTraceAsString());
|
||||
@@ -106,7 +106,7 @@ class Cron extends Command
|
||||
|
||||
$this->info('More feedback on the cron jobs can be found in the log files.');
|
||||
|
||||
// app('telemetry')->feature('executed-command', $this->signature);
|
||||
app('telemetry')->feature('system.command.executed', $this->signature);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@@ -87,7 +87,6 @@ class AccountCurrencies extends Command
|
||||
$this->info(sprintf('Verified and fixed account currencies in %s seconds.', $end));
|
||||
$this->markAsExecuted();
|
||||
|
||||
// app('telemetry')->feature('executed-command', $this->signature);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@@ -78,8 +78,6 @@ class BackToJournals extends Command
|
||||
$this->info(sprintf('Updated category and budget info for all transaction journals in %s seconds.', $end));
|
||||
$this->markAsExecuted();
|
||||
|
||||
// app('telemetry')->feature('executed-command', $this->signature);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@@ -92,8 +92,6 @@ class BudgetLimitCurrency extends Command
|
||||
|
||||
$this->markAsExecuted();
|
||||
|
||||
// app('telemetry')->feature('executed-command', $this->signature);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@@ -91,8 +91,6 @@ class CCLiabilities extends Command
|
||||
$this->info(sprintf('Verified credit card liabilities in %s seconds', $end));
|
||||
$this->markAsExecuted();
|
||||
|
||||
// app('telemetry')->feature('executed-command', $this->signature);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@@ -101,8 +101,6 @@ class MigrateAttachments extends Command
|
||||
$this->info(sprintf('Migrated attachment notes in %s seconds.', $end));
|
||||
$this->markAsExecuted();
|
||||
|
||||
// app('telemetry')->feature('executed-command', $this->signature);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@@ -100,8 +100,6 @@ class MigrateJournalNotes extends Command
|
||||
$this->info(sprintf('Migrated notes in %s seconds.', $end));
|
||||
$this->markAsExecuted();
|
||||
|
||||
// app('telemetry')->feature('executed-command', $this->signature);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@@ -1,5 +1,5 @@
|
||||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
/**
|
||||
* MigrateRecurrenceMeta.php
|
||||
* Copyright (c) 2020 james@firefly-iii.org
|
||||
@@ -20,6 +20,8 @@ declare(strict_types=1);
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace FireflyIII\Console\Commands\Upgrade;
|
||||
|
||||
use FireflyIII\Models\RecurrenceMeta;
|
||||
@@ -72,8 +74,6 @@ class MigrateRecurrenceMeta extends Command
|
||||
$end = round(microtime(true) - $start, 2);
|
||||
$this->info(sprintf('Migrated recurrence meta data in %s seconds.', $end));
|
||||
|
||||
// app('telemetry')->feature('executed-command', $this->signature);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@@ -1,5 +1,5 @@
|
||||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
/**
|
||||
* MigrateTagLocations.php
|
||||
* Copyright (c) 2020 james@firefly-iii.org
|
||||
@@ -20,6 +20,8 @@ declare(strict_types=1);
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace FireflyIII\Console\Commands\Upgrade;
|
||||
|
||||
use FireflyIII\Models\Location;
|
||||
@@ -65,7 +67,6 @@ class MigrateTagLocations extends Command
|
||||
$end = round(microtime(true) - $start, 2);
|
||||
$this->info(sprintf('Migrated tag locations in %s seconds.', $end));
|
||||
|
||||
// app('telemetry')->feature('executed-command', $this->signature);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@@ -112,8 +112,6 @@ class MigrateToGroups extends Command
|
||||
|
||||
$this->markAsMigrated();
|
||||
|
||||
// app('telemetry')->feature('executed-command', $this->signature);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@@ -99,7 +99,6 @@ class MigrateToRules extends Command
|
||||
$this->info(sprintf('Verified and fixed bills in %s seconds.', $end));
|
||||
$this->markAsExecuted();
|
||||
|
||||
// app('telemetry')->feature('executed-command', $this->signature);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -212,7 +211,6 @@ class MigrateToRules extends Command
|
||||
$lang = app('preferences')->getForUser($user, 'language', 'en_US');
|
||||
$groupTitle = (string) trans('firefly.rulegroup_for_bills_title', [], $lang->data);
|
||||
$ruleGroup = $this->ruleGroupRepository->findByTitle($groupTitle);
|
||||
//$currency = $this->getCurrency($user);
|
||||
|
||||
if (null === $ruleGroup) {
|
||||
$ruleGroup = $this->ruleGroupRepository->store(
|
||||
|
@@ -90,7 +90,6 @@ class OtherCurrenciesCorrections extends Command
|
||||
$end = round(microtime(true) - $start, 2);
|
||||
$this->info(sprintf('Verified and fixed transaction currencies in %s seconds.', $end));
|
||||
|
||||
// app('telemetry')->feature('executed-command', $this->signature);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@@ -91,7 +91,6 @@ class RenameAccountMeta extends Command
|
||||
$end = round(microtime(true) - $start, 2);
|
||||
$this->info(sprintf('Fixed account meta data in %s seconds.', $end));
|
||||
|
||||
// app('telemetry')->feature('executed-command', $this->signature);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@@ -101,7 +101,6 @@ class TransactionIdentifier extends Command
|
||||
$this->info(sprintf('Verified and fixed transaction identifiers in %s seconds.', $end));
|
||||
$this->markAsExecuted();
|
||||
|
||||
// app('telemetry')->feature('executed-command', $this->signature);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@@ -111,7 +111,6 @@ class TransferCurrenciesCorrections extends Command
|
||||
$end = round(microtime(true) - $start, 2);
|
||||
$this->info(sprintf('Verified and fixed currency information for transfers in %s seconds.', $end));
|
||||
|
||||
// app('telemetry')->feature('executed-command', $this->signature);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -342,19 +341,17 @@ class TransferCurrenciesCorrections extends Command
|
||||
if (isset($this->accountCurrencies[$accountId]) && $this->accountCurrencies[$accountId] instanceof TransactionCurrency) {
|
||||
return $this->accountCurrencies[$accountId]; // @codeCoverageIgnore
|
||||
}
|
||||
// TODO we can use getAccountCurrency() instead
|
||||
$currencyId = (int) $this->accountRepos->getMetaValue($account, 'currency_id');
|
||||
$result = $this->currencyRepos->findNull($currencyId);
|
||||
if (null === $result) {
|
||||
$currency = $this->accountRepos->getAccountCurrency($account);
|
||||
if (null === $currency) {
|
||||
// @codeCoverageIgnoreStart
|
||||
$this->accountCurrencies[$accountId] = 0;
|
||||
|
||||
return null;
|
||||
// @codeCoverageIgnoreEnd
|
||||
}
|
||||
$this->accountCurrencies[$accountId] = $result;
|
||||
$this->accountCurrencies[$accountId] = $currency;
|
||||
|
||||
return $result;
|
||||
return $currency;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@@ -76,7 +76,7 @@ class UpgradeDatabase extends Command
|
||||
'firefly-iii:migrate-recurrence-meta',
|
||||
'firefly-iii:migrate-tag-locations',
|
||||
|
||||
// there are 16 verify commands.
|
||||
// there are 15 verify commands.
|
||||
'firefly-iii:fix-piggies',
|
||||
'firefly-iii:create-link-types',
|
||||
'firefly-iii:create-access-tokens',
|
||||
@@ -93,6 +93,7 @@ class UpgradeDatabase extends Command
|
||||
'firefly-iii:fix-ob-currencies',
|
||||
'firefly-iii:fix-long-descriptions',
|
||||
'firefly-iii:fix-recurring-transactions',
|
||||
'firefly-iii:unify-group-accounts',
|
||||
|
||||
// two report commands
|
||||
'firefly-iii:report-empty-objects',
|
||||
@@ -117,7 +118,6 @@ class UpgradeDatabase extends Command
|
||||
// index will set FF3 version.
|
||||
app('fireflyconfig')->set('ff3_version', (string) config('firefly.version'));
|
||||
|
||||
// app('telemetry')->feature('executed-command', $this->signature);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@@ -23,6 +23,7 @@ declare(strict_types=1);
|
||||
|
||||
namespace FireflyIII\Console\Commands;
|
||||
|
||||
use FireflyIII\Support\System\GeneratesInstallationId;
|
||||
use Illuminate\Console\Command;
|
||||
|
||||
/**
|
||||
@@ -32,6 +33,8 @@ use Illuminate\Console\Command;
|
||||
*/
|
||||
class UpgradeFireflyInstructions extends Command
|
||||
{
|
||||
use GeneratesInstallationId;
|
||||
|
||||
/**
|
||||
* The console command description.
|
||||
*
|
||||
@@ -50,6 +53,7 @@ class UpgradeFireflyInstructions extends Command
|
||||
*/
|
||||
public function handle(): int
|
||||
{
|
||||
$this->generateInstallationId();
|
||||
if ('update' === (string) $this->argument('task')) {
|
||||
$this->updateInstructions();
|
||||
}
|
||||
@@ -57,7 +61,14 @@ class UpgradeFireflyInstructions extends Command
|
||||
$this->installInstructions();
|
||||
}
|
||||
|
||||
// app('telemetry')->feature('executed-command', $this->signature);
|
||||
// collect system telemetry
|
||||
$isDocker = true === env('IS_DOCKER', false) ? 'true' : 'false';
|
||||
app('telemetry')->feature('system.php.version', PHP_VERSION);
|
||||
app('telemetry')->feature('system.os.version', PHP_OS);
|
||||
app('telemetry')->feature('system.database.driver', env('DB_CONNECTION', '(unknown)'));
|
||||
app('telemetry')->feature('system.os.is_docker', $isDocker);
|
||||
app('telemetry')->feature('system.command.executed', $this->signature);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@@ -1,8 +1,8 @@
|
||||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
/**
|
||||
* DuplicateTransactionException.php
|
||||
* Copyright (c) 2019 james@firefly-iii.org
|
||||
* Copyright (c) 2020 james@firefly-iii.org
|
||||
*
|
||||
* This file is part of Firefly III (https://github.com/firefly-iii).
|
||||
*
|
||||
@@ -20,6 +20,8 @@ declare(strict_types=1);
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace FireflyIII\Exceptions;
|
||||
|
||||
use Exception;
|
||||
|
@@ -38,6 +38,7 @@ use Illuminate\Http\Request;
|
||||
use Illuminate\Routing\Redirector;
|
||||
use Log;
|
||||
use Symfony\Component\HttpFoundation\Response;
|
||||
use Throwable;
|
||||
|
||||
/**
|
||||
* Class GracefulNotFoundHandler
|
||||
@@ -53,7 +54,7 @@ class GracefulNotFoundHandler extends ExceptionHandler
|
||||
* @throws Exception
|
||||
* @return mixed
|
||||
*/
|
||||
public function render($request, Exception $exception)
|
||||
public function render($request, Throwable $exception)
|
||||
{
|
||||
$route = $request->route();
|
||||
if (null === $route) {
|
||||
@@ -136,12 +137,12 @@ class GracefulNotFoundHandler extends ExceptionHandler
|
||||
|
||||
/**
|
||||
* @param Request $request
|
||||
* @param Exception $exception
|
||||
* @param Throwable $exception
|
||||
*
|
||||
* @throws Exception
|
||||
* @return Redirector|Response
|
||||
*/
|
||||
private function handleAccount(Request $request, Exception $exception)
|
||||
private function handleAccount(Request $request, Throwable $exception)
|
||||
{
|
||||
Log::debug('404 page is probably a deleted account. Redirect to overview of account types.');
|
||||
/** @var User $user */
|
||||
@@ -164,12 +165,12 @@ class GracefulNotFoundHandler extends ExceptionHandler
|
||||
|
||||
/**
|
||||
* @param Request $request
|
||||
* @param Exception $exception
|
||||
* @param Throwable $exception
|
||||
*
|
||||
* @throws Exception
|
||||
* @return RedirectResponse|Redirector|Response
|
||||
*/
|
||||
private function handleAttachment(Request $request, Exception $exception)
|
||||
private function handleAttachment(Request $request, Throwable $exception)
|
||||
{
|
||||
Log::debug('404 page is probably a deleted attachment. Redirect to parent object.');
|
||||
/** @var User $user */
|
||||
@@ -208,13 +209,13 @@ class GracefulNotFoundHandler extends ExceptionHandler
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Request $request
|
||||
* @param Throwable $request
|
||||
* @param Exception $exception
|
||||
*
|
||||
* @throws Exception
|
||||
* @return RedirectResponse|\Illuminate\Http\Response|Redirector|Response
|
||||
*/
|
||||
private function handleGroup(Request $request, Exception $exception)
|
||||
private function handleGroup(Request $request, Throwable $exception)
|
||||
{
|
||||
Log::debug('404 page is probably a deleted group. Redirect to overview of group types.');
|
||||
/** @var User $user */
|
||||
|
@@ -33,9 +33,9 @@ use Illuminate\Auth\AuthenticationException;
|
||||
use Illuminate\Foundation\Exceptions\Handler as ExceptionHandler;
|
||||
use Illuminate\Validation\ValidationException as LaravelValidationException;
|
||||
use League\OAuth2\Server\Exception\OAuthServerException;
|
||||
use Request;
|
||||
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
|
||||
|
||||
use Illuminate\Http\Request;
|
||||
use Throwable;
|
||||
/**
|
||||
* Class Handler
|
||||
*
|
||||
@@ -51,7 +51,7 @@ class Handler extends ExceptionHandler
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function render($request, Exception $exception)
|
||||
public function render($request, Throwable $exception)
|
||||
{
|
||||
if ($exception instanceof LaravelValidationException && $request->expectsJson()) {
|
||||
// ignore it: controller will handle it.
|
||||
@@ -87,7 +87,7 @@ class Handler extends ExceptionHandler
|
||||
);
|
||||
}
|
||||
|
||||
return response()->json(['message' => 'Internal Firefly III Exception. See log files.', 'exception' => get_class($exception)], 500);
|
||||
return response()->json(['message' => sprintf('Internal Firefly III Exception: %s', $exception->getMessage()), 'exception' => get_class($exception)], 500);
|
||||
}
|
||||
|
||||
if ($exception instanceof NotFoundHttpException) {
|
||||
@@ -119,7 +119,7 @@ class Handler extends ExceptionHandler
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function report(Exception $exception)
|
||||
public function report(Throwable $exception)
|
||||
{
|
||||
$doMailError = config('firefly.send_error_message');
|
||||
// if the user wants us to mail:
|
||||
@@ -143,13 +143,13 @@ class Handler extends ExceptionHandler
|
||||
'line' => $exception->getLine(),
|
||||
'code' => $exception->getCode(),
|
||||
'version' => config('firefly.version'),
|
||||
'url' => Request::fullUrl(),
|
||||
'userAgent' => Request::userAgent(),
|
||||
'json' => Request::acceptsJson(),
|
||||
'url' => request()->fullUrl(),
|
||||
'userAgent' => request()->userAgent(),
|
||||
'json' => request()->acceptsJson(),
|
||||
];
|
||||
|
||||
// create job that will mail.
|
||||
$ipAddress = Request::ip() ?? '0.0.0.0';
|
||||
$ipAddress = request()->ip() ?? '0.0.0.0';
|
||||
$job = new MailError($userData, (string) config('firefly.site_owner'), $ipAddress, $data);
|
||||
dispatch($job);
|
||||
}
|
||||
|
@@ -98,7 +98,7 @@ class AccountFactory
|
||||
'user_id' => $this->user->id,
|
||||
'account_type_id' => $type->id,
|
||||
'name' => $data['name'],
|
||||
'virtual_balance' => $data['virtual_balance'] ?? '0',
|
||||
'virtual_balance' => $data['virtual_balance'] ?? null,
|
||||
'active' => true === $data['active'],
|
||||
'iban' => $data['iban'],
|
||||
];
|
||||
@@ -109,12 +109,12 @@ class AccountFactory
|
||||
|
||||
// remove virtual balance when not an asset account or a liability
|
||||
if (!in_array($type->type, $this->canHaveVirtual, true)) {
|
||||
$databaseData['virtual_balance'] = '0';
|
||||
$databaseData['virtual_balance'] = null;
|
||||
}
|
||||
|
||||
// fix virtual balance when it's empty
|
||||
if ('' === $databaseData['virtual_balance']) {
|
||||
$databaseData['virtual_balance'] = '0';
|
||||
if ('' === (string)$databaseData['virtual_balance']) {
|
||||
$databaseData['virtual_balance'] = null;
|
||||
}
|
||||
|
||||
$return = Account::create($databaseData);
|
||||
|
@@ -27,6 +27,7 @@ namespace FireflyIII\Factory;
|
||||
use FireflyIII\Exceptions\FireflyException;
|
||||
use FireflyIII\Models\Bill;
|
||||
use FireflyIII\Models\TransactionCurrency;
|
||||
use FireflyIII\Repositories\ObjectGroup\CreatesObjectGroups;
|
||||
use FireflyIII\Services\Internal\Support\BillServiceTrait;
|
||||
use FireflyIII\User;
|
||||
use Illuminate\Database\QueryException;
|
||||
@@ -37,7 +38,7 @@ use Log;
|
||||
*/
|
||||
class BillFactory
|
||||
{
|
||||
use BillServiceTrait;
|
||||
use BillServiceTrait, CreatesObjectGroups;
|
||||
|
||||
/** @var User */
|
||||
private $user;
|
||||
@@ -97,6 +98,24 @@ class BillFactory
|
||||
$this->updateNote($bill, $data['notes']);
|
||||
}
|
||||
|
||||
$objectGroupTitle = $data['object_group'] ?? '';
|
||||
if ('' !== $objectGroupTitle) {
|
||||
$objectGroup = $this->findOrCreateObjectGroup($objectGroupTitle);
|
||||
if (null !== $objectGroup) {
|
||||
$bill->objectGroups()->sync([$objectGroup->id]);
|
||||
$bill->save();
|
||||
}
|
||||
}
|
||||
// try also with ID:
|
||||
$objectGroupId = (int) ($data['object_group_id'] ?? 0);
|
||||
if (0 !== $objectGroupId) {
|
||||
$objectGroup = $this->findObjectGroupById($objectGroupId);
|
||||
if (null !== $objectGroup) {
|
||||
$bill->objectGroups()->sync([$objectGroup->id]);
|
||||
$bill->save();
|
||||
}
|
||||
}
|
||||
|
||||
return $bill;
|
||||
}
|
||||
|
||||
|
@@ -280,25 +280,29 @@ class TransactionJournalFactory
|
||||
|
||||
/** create or get source and destination accounts */
|
||||
$sourceInfo = [
|
||||
'id' => (int) $row['source_id'],
|
||||
'name' => $row['source_name'],
|
||||
'iban' => $row['source_iban'],
|
||||
'number' => $row['source_number'],
|
||||
'bic' => $row['source_bic'],
|
||||
'id' => (int) $row['source_id'],
|
||||
'name' => $row['source_name'],
|
||||
'iban' => $row['source_iban'],
|
||||
'number' => $row['source_number'],
|
||||
'bic' => $row['source_bic'],
|
||||
'currency_id' => $currency->id,
|
||||
];
|
||||
|
||||
$destInfo = [
|
||||
'id' => (int) $row['destination_id'],
|
||||
'name' => $row['destination_name'],
|
||||
'iban' => $row['destination_iban'],
|
||||
'number' => $row['destination_number'],
|
||||
'bic' => $row['destination_bic'],
|
||||
'id' => (int) $row['destination_id'],
|
||||
'name' => $row['destination_name'],
|
||||
'iban' => $row['destination_iban'],
|
||||
'number' => $row['destination_number'],
|
||||
'bic' => $row['destination_bic'],
|
||||
'currency_id' => $currency->id,
|
||||
];
|
||||
Log::debug('Source info:', $sourceInfo);
|
||||
Log::debug('Destination info:', $destInfo);
|
||||
|
||||
$sourceAccount = $this->getAccount($type->type, 'source', $sourceInfo);
|
||||
Log::debug('Now calling getAccount for the source.');
|
||||
$sourceAccount = $this->getAccount($type->type, 'source', $sourceInfo);
|
||||
Log::debug('Now calling getAccount for the destination.');
|
||||
$destinationAccount = $this->getAccount($type->type, 'destination', $destInfo);
|
||||
Log::debug('Done with getAccount(2x)');
|
||||
$currency = $this->getCurrencyByAccount($type->type, $currency, $sourceAccount, $destinationAccount);
|
||||
$foreignCurrency = $this->compareCurrencies($currency, $foreignCurrency);
|
||||
$foreignCurrency = $this->getForeignByAccount($type->type, $foreignCurrency, $destinationAccount);
|
||||
@@ -363,19 +367,6 @@ class TransactionJournalFactory
|
||||
|
||||
// verify that journal has two transactions. Otherwise, delete and cancel.
|
||||
// TODO this can't be faked so it can't be tested.
|
||||
// $count = $journal->transactions()->count();
|
||||
// if (2 !== $count) {
|
||||
// // @codeCoverageIgnoreStart
|
||||
// Log::error(sprintf('The journal unexpectedly has %d transaction(s). This is not OK. Cancel operation.', $count));
|
||||
// try {
|
||||
// $journal->delete();
|
||||
// } catch (Exception $e) {
|
||||
// Log::debug(sprintf('Dont care: %s.', $e->getMessage()));
|
||||
// }
|
||||
//
|
||||
// return null;
|
||||
// // @codeCoverageIgnoreEnd
|
||||
// }
|
||||
$journal->completed = true;
|
||||
$journal->save();
|
||||
|
||||
@@ -424,7 +415,7 @@ class TransactionJournalFactory
|
||||
->first();
|
||||
}
|
||||
if (null !== $result) {
|
||||
Log::warning('Found a duplicate!');
|
||||
Log::warning(sprintf('Found a duplicate in errorIfDuplicate because hash %s is not unique!', $hash));
|
||||
throw new DuplicateTransactionException(sprintf('Duplicate of transaction #%d.', $result->transactionJournal->transaction_group_id));
|
||||
}
|
||||
}
|
||||
@@ -468,6 +459,7 @@ class TransactionJournalFactory
|
||||
*/
|
||||
private function getCurrency(?TransactionCurrency $currency, Account $account): TransactionCurrency
|
||||
{
|
||||
Log::debug('Now in getCurrency()');
|
||||
$preference = $this->accountRepository->getAccountCurrency($account);
|
||||
if (null === $preference && null === $currency) {
|
||||
// return user's default:
|
||||
@@ -489,6 +481,7 @@ class TransactionJournalFactory
|
||||
*/
|
||||
private function getCurrencyByAccount(string $type, ?TransactionCurrency $currency, Account $source, Account $destination): TransactionCurrency
|
||||
{
|
||||
Log::debug('Now ingetCurrencyByAccount()');
|
||||
switch ($type) {
|
||||
default:
|
||||
case TransactionType::WITHDRAWAL:
|
||||
@@ -538,15 +531,15 @@ class TransactionJournalFactory
|
||||
$dataRow = $row->getArrayCopy();
|
||||
|
||||
unset($dataRow['import_hash_v2'], $dataRow['original_source']);
|
||||
$json = json_encode($dataRow);
|
||||
$json = json_encode($dataRow, JSON_THROW_ON_ERROR, 512);
|
||||
if (false === $json) {
|
||||
// @codeCoverageIgnoreStart
|
||||
$json = json_encode((string) microtime());
|
||||
$json = json_encode((string) microtime(), JSON_THROW_ON_ERROR, 512);
|
||||
Log::error(sprintf('Could not hash the original row! %s', json_last_error_msg()), $dataRow);
|
||||
// @codeCoverageIgnoreEnd
|
||||
}
|
||||
$hash = hash('sha256', $json);
|
||||
Log::debug(sprintf('The hash is: %s', $hash));
|
||||
Log::debug(sprintf('The hash is: %s', $hash), $dataRow);
|
||||
|
||||
return $hash;
|
||||
}
|
||||
@@ -601,7 +594,7 @@ class TransactionJournalFactory
|
||||
|
||||
// validate source account.
|
||||
$sourceId = isset($data['source_id']) ? (int) $data['source_id'] : null;
|
||||
$sourceName = $data['source_name'] ?? null;
|
||||
$sourceName = isset($data['source_name']) ? (string) $data['source_name'] : null;
|
||||
$validSource = $this->accountValidator->validateSource($sourceId, $sourceName, null);
|
||||
|
||||
// do something with result:
|
||||
@@ -611,7 +604,7 @@ class TransactionJournalFactory
|
||||
Log::debug('Source seems valid.');
|
||||
// validate destination account
|
||||
$destinationId = isset($data['destination_id']) ? (int) $data['destination_id'] : null;
|
||||
$destinationName = (string)($data['destination_name'] ?? null);
|
||||
$destinationName = isset($data['destination_name']) ? (string) $data['destination_name'] : null;
|
||||
$validDestination = $this->accountValidator->validateDestination($destinationId, $destinationName, null);
|
||||
// do something with result:
|
||||
if (false === $validDestination) {
|
||||
|
@@ -154,14 +154,14 @@ class MonthReportGenerator implements ReportGeneratorInterface
|
||||
$journals[$index]['invoice_date'] = $journalRepository->getMetaDateById($journal['transaction_journal_id'], 'invoice_date');
|
||||
|
||||
}
|
||||
|
||||
$locale = app('steam')->getLocale();
|
||||
$return = [
|
||||
'journals' => $journals,
|
||||
'currency' => $currency,
|
||||
'exists' => count($journals) > 0,
|
||||
'end' => $this->end->formatLocalized((string) trans('config.month_and_day')),
|
||||
'end' => $this->end->formatLocalized((string) trans('config.month_and_day', [], $locale)),
|
||||
'endBalance' => app('steam')->balance($account, $this->end),
|
||||
'dayBefore' => $date->formatLocalized((string) trans('config.month_and_day')),
|
||||
'dayBefore' => $date->formatLocalized((string) trans('config.month_and_day', [], $locale)),
|
||||
'dayBeforeBalance' => $dayBeforeBalance,
|
||||
];
|
||||
|
||||
|
@@ -23,14 +23,58 @@ declare(strict_types=1);
|
||||
namespace FireflyIII\Handlers\Events;
|
||||
|
||||
use FireflyIII\Events\UpdatedTransactionGroup;
|
||||
use FireflyIII\Models\Account;
|
||||
use FireflyIII\Models\Transaction;
|
||||
use FireflyIII\Models\TransactionJournal;
|
||||
use FireflyIII\Models\TransactionType;
|
||||
use FireflyIII\TransactionRules\Engine\RuleEngine;
|
||||
use Log;
|
||||
|
||||
/**
|
||||
* Class UpdatedGroupEventHandler
|
||||
*/
|
||||
class UpdatedGroupEventHandler
|
||||
{
|
||||
/**
|
||||
* This method will make sure all source / destination accounts are the same.
|
||||
*
|
||||
* @param UpdatedTransactionGroup $updatedGroupEvent
|
||||
*/
|
||||
public function unifyAccounts(UpdatedTransactionGroup $updatedGroupEvent): void
|
||||
{
|
||||
$group = $updatedGroupEvent->transactionGroup;
|
||||
if (1 === $group->transactionJournals->count()) {
|
||||
return;
|
||||
}
|
||||
Log::debug(sprintf('Correct inconsistent accounts in group #%d', $group->id));
|
||||
// first journal:
|
||||
/** @var TransactionJournal $first */
|
||||
$first = $group->transactionJournals()
|
||||
->orderBy('transaction_journals.date', 'DESC')
|
||||
->orderBy('transaction_journals.order', 'ASC')
|
||||
->orderBy('transaction_journals.id', 'DESC')
|
||||
->orderBy('transaction_journals.description', 'DESC')
|
||||
->first();
|
||||
$all = $group->transactionJournals()->get()->pluck('id')->toArray();
|
||||
/** @var Account $sourceAccount */
|
||||
$sourceAccount = $first->transactions()->where('amount', '<', '0')->first()->account;
|
||||
/** @var Account $destAccount */
|
||||
$destAccount = $first->transactions()->where('amount', '>', '0')->first()->account;
|
||||
|
||||
$type = $first->transactionType->type;
|
||||
if (TransactionType::TRANSFER === $type || TransactionType::WITHDRAWAL === $type) {
|
||||
// set all source transactions to source account:
|
||||
Transaction::whereIn('transaction_journal_id', $all)
|
||||
->where('amount', '<', 0)->update(['account_id' => $sourceAccount->id]);
|
||||
}
|
||||
if (TransactionType::TRANSFER === $type || TransactionType::DEPOSIT === $type) {
|
||||
// set all destination transactions to destination account:
|
||||
Transaction::whereIn('transaction_journal_id', $all)
|
||||
->where('amount', '>', 0)->update(['account_id' => $destAccount->id]);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* This method will check all the rules when a journal is updated.
|
||||
*
|
||||
|
@@ -118,6 +118,7 @@ class UserEventHandler
|
||||
if ($repository->hasRole($user, 'demo')) {
|
||||
// set user back to English.
|
||||
app('preferences')->setForUser($user, 'language', 'en_US');
|
||||
app('preferences')->setForUser($user, 'locale', 'equal');
|
||||
app('preferences')->mark();
|
||||
}
|
||||
|
||||
@@ -165,7 +166,8 @@ class UserEventHandler
|
||||
$user = $event->user;
|
||||
$ipAddress = $event->ipAddress;
|
||||
$token = app('preferences')->getForUser($user, 'email_change_undo_token', 'invalid');
|
||||
$uri = route('profile.undo-email-change', [$token->data, hash('sha256', $oldEmail)]);
|
||||
$hashed = hash('sha256', sprintf('%s%s', (string) config('app.key'), $oldEmail));
|
||||
$uri = route('profile.undo-email-change', [$token->data,$hashed]);
|
||||
try {
|
||||
Mail::to($oldEmail)->send(new UndoEmailChangeMail($newEmail, $oldEmail, $uri, $ipAddress));
|
||||
// @codeCoverageIgnoreStart
|
||||
|
@@ -54,6 +54,7 @@ class VersionCheckEventHandler
|
||||
$value = (int) $permission->data;
|
||||
if (1 !== $value) {
|
||||
Log::info('Update check is not enabled.');
|
||||
$this->warnToCheckForUpdates($event);
|
||||
|
||||
return;
|
||||
}
|
||||
@@ -85,4 +86,36 @@ class VersionCheckEventHandler
|
||||
session()->flash($release['level'], $release['message']);
|
||||
app('fireflyconfig')->set('last_update_check', time());
|
||||
}
|
||||
|
||||
/**
|
||||
* @param RequestedVersionCheckStatus $event
|
||||
*/
|
||||
protected function warnToCheckForUpdates(RequestedVersionCheckStatus $event): void
|
||||
{
|
||||
/** @var UserRepositoryInterface $repository */
|
||||
$repository = app(UserRepositoryInterface::class);
|
||||
/** @var User $user */
|
||||
$user = $event->user;
|
||||
if (!$repository->hasRole($user, 'owner')) {
|
||||
Log::debug('User is not admin, done.');
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/** @var Configuration $lastCheckTime */
|
||||
$lastCheckTime = app('fireflyconfig')->get('last_update_warning', time());
|
||||
$now = time();
|
||||
$diff = $now - $lastCheckTime->data;
|
||||
Log::debug(sprintf('Last warning time is %d, current time is %d, difference is %d', $lastCheckTime->data, $now, $diff));
|
||||
if ($diff < 604800 * 4) {
|
||||
Log::debug(sprintf('Warned about updates less than four weeks ago (on %s).', date('Y-m-d H:i:s', $lastCheckTime->data)));
|
||||
|
||||
return;
|
||||
}
|
||||
// last check time was more than a week ago.
|
||||
Log::debug('Have warned about a new version in four weeks!');
|
||||
|
||||
session()->flash('info', (string) trans('firefly.disabled_but_check'));
|
||||
app('fireflyconfig')->set('last_update_warning', time());
|
||||
}
|
||||
}
|
||||
|
@@ -1,5 +1,5 @@
|
||||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
/**
|
||||
* AccountCollection.php
|
||||
* Copyright (c) 2020 james@firefly-iii.org
|
||||
@@ -20,6 +20,8 @@ declare(strict_types=1);
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace FireflyIII\Helpers\Collector\Extensions;
|
||||
|
||||
use FireflyIII\Helpers\Collector\GroupCollectorInterface;
|
||||
@@ -230,4 +232,4 @@ trait AccountCollection
|
||||
|
||||
return $this;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -1,5 +1,5 @@
|
||||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
/**
|
||||
* AmountCollection.php
|
||||
* Copyright (c) 2020 james@firefly-iii.org
|
||||
@@ -20,6 +20,8 @@ declare(strict_types=1);
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace FireflyIII\Helpers\Collector\Extensions;
|
||||
|
||||
use FireflyIII\Helpers\Collector\GroupCollectorInterface;
|
||||
@@ -84,4 +86,4 @@ trait AmountCollection
|
||||
|
||||
return $this;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -1,5 +1,5 @@
|
||||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
/**
|
||||
* CollectorProperties.php
|
||||
* Copyright (c) 2020 james@firefly-iii.org
|
||||
@@ -20,6 +20,8 @@ declare(strict_types=1);
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace FireflyIII\Helpers\Collector\Extensions;
|
||||
|
||||
use FireflyIII\User;
|
||||
@@ -36,6 +38,8 @@ trait CollectorProperties
|
||||
private $hasAccountInfo;
|
||||
/** @var bool Will be true if query result includes bill information. */
|
||||
private $hasBillInformation;
|
||||
/** @var bool */
|
||||
private $hasNotesInformation;
|
||||
/** @var bool Will be true if query result contains budget info. */
|
||||
private $hasBudgetInformation;
|
||||
/** @var bool Will be true if query result contains category info. */
|
||||
@@ -56,4 +60,6 @@ trait CollectorProperties
|
||||
private $total;
|
||||
/** @var User The user object. */
|
||||
private $user;
|
||||
}
|
||||
|
||||
private bool $hasJoinedMetaTables;
|
||||
}
|
||||
|
@@ -1,5 +1,5 @@
|
||||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
/**
|
||||
* MetaCollection.php
|
||||
* Copyright (c) 2020 james@firefly-iii.org
|
||||
@@ -20,6 +20,8 @@ declare(strict_types=1);
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace FireflyIII\Helpers\Collector\Extensions;
|
||||
|
||||
use FireflyIII\Helpers\Collector\GroupCollectorInterface;
|
||||
@@ -28,6 +30,7 @@ use FireflyIII\Models\Budget;
|
||||
use FireflyIII\Models\Category;
|
||||
use FireflyIII\Models\Tag;
|
||||
use Illuminate\Database\Eloquent\Builder as EloquentBuilder;
|
||||
use Illuminate\Database\Query\JoinClause;
|
||||
use Illuminate\Support\Collection;
|
||||
|
||||
/**
|
||||
@@ -36,6 +39,27 @@ use Illuminate\Support\Collection;
|
||||
trait MetaCollection
|
||||
{
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function withNotes(): GroupCollectorInterface
|
||||
{
|
||||
if (false === $this->hasNotesInformation) {
|
||||
// join bill table
|
||||
$this->query->leftJoin(
|
||||
'notes',
|
||||
static function (JoinClause $join) {
|
||||
$join->on('notes.noteable_id', '=', 'transaction_journals.id');
|
||||
$join->where('notes.noteable_type', '=', 'FireflyIII\Models\TransactionJournal');
|
||||
}
|
||||
);
|
||||
// add fields
|
||||
$this->fields[] = 'notes.text as notes';
|
||||
$this->hasNotesInformation = true;
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Limit the search to a specific bill.
|
||||
@@ -288,4 +312,36 @@ trait MetaCollection
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function setExternalId(string $externalId): GroupCollectorInterface
|
||||
{
|
||||
if (false === $this->hasJoinedMetaTables) {
|
||||
$this->hasJoinedMetaTables = true;
|
||||
$this->query->leftJoin('journal_meta', 'transaction_journals.id', '=', 'journal_meta.transaction_journal_id');
|
||||
}
|
||||
$this->query->where('journal_meta.name', '=', 'external_id');
|
||||
$this->query->where('journal_meta.data', 'LIKE', sprintf('%%%s%%', $externalId));
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function setInternalReference(string $internalReference): GroupCollectorInterface
|
||||
{
|
||||
if (false === $this->hasJoinedMetaTables) {
|
||||
$this->hasJoinedMetaTables = true;
|
||||
$this->query->leftJoin('journal_meta', 'transaction_journals.id', '=', 'journal_meta.transaction_journal_id');
|
||||
}
|
||||
|
||||
$this->query->where('journal_meta.name', '=', 'internal_reference');
|
||||
$this->query->where('journal_meta.data', 'LIKE', sprintf('%%%s%%', $internalReference));
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
@@ -1,5 +1,5 @@
|
||||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
/**
|
||||
* TimeCollection.php
|
||||
* Copyright (c) 2020 james@firefly-iii.org
|
||||
@@ -20,6 +20,8 @@ declare(strict_types=1);
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace FireflyIII\Helpers\Collector\Extensions;
|
||||
|
||||
use Carbon\Carbon;
|
||||
@@ -91,8 +93,9 @@ trait TimeCollection
|
||||
if ($end < $start) {
|
||||
[$start, $end] = [$end, $start];
|
||||
}
|
||||
$startStr = $start->format('Y-m-d H:i:s');
|
||||
$endStr = $end->format('Y-m-d H:i:s');
|
||||
// always got to end of day / start of day for ranges.
|
||||
$startStr = $start->format('Y-m-d 00:00:00');
|
||||
$endStr = $end->format('Y-m-d 23:59:59');
|
||||
|
||||
$this->query->where('transaction_journals.date', '>=', $startStr);
|
||||
$this->query->where('transaction_journals.date', '<=', $endStr);
|
||||
@@ -117,4 +120,4 @@ trait TimeCollection
|
||||
|
||||
return $this;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -31,16 +31,11 @@ use FireflyIII\Helpers\Collector\Extensions\AmountCollection;
|
||||
use FireflyIII\Helpers\Collector\Extensions\CollectorProperties;
|
||||
use FireflyIII\Helpers\Collector\Extensions\MetaCollection;
|
||||
use FireflyIII\Helpers\Collector\Extensions\TimeCollection;
|
||||
use FireflyIII\Models\Bill;
|
||||
use FireflyIII\Models\Budget;
|
||||
use FireflyIII\Models\Category;
|
||||
use FireflyIII\Models\Tag;
|
||||
use FireflyIII\Models\TransactionCurrency;
|
||||
use FireflyIII\Models\TransactionGroup;
|
||||
use FireflyIII\Models\TransactionJournal;
|
||||
use FireflyIII\User;
|
||||
use Illuminate\Database\Eloquent\Builder as EloquentBuilder;
|
||||
use Illuminate\Database\Eloquent\Relations\HasMany;
|
||||
use Illuminate\Database\Query\JoinClause;
|
||||
use Illuminate\Pagination\LengthAwarePaginator;
|
||||
use Illuminate\Support\Collection;
|
||||
@@ -67,8 +62,10 @@ class GroupCollector implements GroupCollectorInterface
|
||||
$this->hasCatInformation = false;
|
||||
$this->hasBudgetInformation = false;
|
||||
$this->hasBillInformation = false;
|
||||
$this->hasNotesInformation = false;
|
||||
$this->hasJoinedTagTables = false;
|
||||
$this->hasJoinedAttTables = false;
|
||||
$this->hasJoinedMetaTables = false;
|
||||
$this->integerFields = [
|
||||
'transaction_group_id',
|
||||
'user_id',
|
||||
@@ -171,13 +168,8 @@ class GroupCollector implements GroupCollectorInterface
|
||||
*/
|
||||
public function getGroups(): Collection
|
||||
{
|
||||
//$start = microtime(true);
|
||||
/** @var Collection $result */
|
||||
$result = $this->query->get($this->fields);
|
||||
//$end = round(microtime(true) - $start, 5);
|
||||
// log info about query time.
|
||||
//Log::info(sprintf('Query took Firefly III %s seconds', $end));
|
||||
//Log::info($this->query->toSql(), $this->query->getBindings());
|
||||
|
||||
// now to parse this into an array.
|
||||
$collection = $this->parseArray($result);
|
||||
@@ -316,7 +308,7 @@ class GroupCollector implements GroupCollectorInterface
|
||||
$this->query->where(
|
||||
static function (EloquentBuilder $q) use ($array) {
|
||||
$q->where(
|
||||
function (EloquentBuilder $q1) use ($array) {
|
||||
static function (EloquentBuilder $q1) use ($array) {
|
||||
foreach ($array as $word) {
|
||||
$keyword = sprintf('%%%s%%', $word);
|
||||
$q1->where('transaction_journals.description', 'LIKE', $keyword);
|
||||
@@ -526,7 +518,7 @@ class GroupCollector implements GroupCollectorInterface
|
||||
}
|
||||
// or parse the rest.
|
||||
$journalId = (int) $augumentedJournal->transaction_journal_id;
|
||||
$groups[$groupId]['count']++;
|
||||
|
||||
|
||||
if (isset($groups[$groupId]['transactions'][$journalId])) {
|
||||
// append data to existing group + journal (for multiple tags or multiple attachments)
|
||||
@@ -536,6 +528,7 @@ class GroupCollector implements GroupCollectorInterface
|
||||
|
||||
if (!isset($groups[$groupId]['transactions'][$journalId])) {
|
||||
// create second, third, fourth split:
|
||||
$groups[$groupId]['count']++;
|
||||
$groups[$groupId]['transactions'][$journalId] = $this->parseAugmentedJournal($augumentedJournal);
|
||||
}
|
||||
}
|
||||
@@ -556,9 +549,14 @@ class GroupCollector implements GroupCollectorInterface
|
||||
$result['tags'] = [];
|
||||
$result['attachments'] = [];
|
||||
try {
|
||||
$result['date'] = new Carbon($result['date']);
|
||||
$result['created_at'] = new Carbon($result['created_at']);
|
||||
$result['updated_at'] = new Carbon($result['updated_at']);
|
||||
$result['date'] = new Carbon($result['date'], 'UTC');
|
||||
$result['created_at'] = new Carbon($result['created_at'], 'UTC');
|
||||
$result['updated_at'] = new Carbon($result['updated_at'], 'UTC');
|
||||
|
||||
// this is going to happen a lot:
|
||||
$result['date']->setTimezone(env('TZ'));
|
||||
$result['created_at']->setTimezone(env('TZ'));
|
||||
$result['updated_at']->setTimezone(env('TZ'));
|
||||
} catch (Exception $e) {
|
||||
Log::error($e->getMessage());
|
||||
}
|
||||
|
@@ -398,6 +398,13 @@ interface GroupCollectorInterface
|
||||
*/
|
||||
public function withCategoryInformation(): GroupCollectorInterface;
|
||||
|
||||
/**
|
||||
* Will include notes.
|
||||
*
|
||||
* @return GroupCollectorInterface
|
||||
*/
|
||||
public function withNotes(): GroupCollectorInterface;
|
||||
|
||||
/**
|
||||
* Add tag info.
|
||||
*
|
||||
@@ -419,4 +426,22 @@ interface GroupCollectorInterface
|
||||
*/
|
||||
public function withoutCategory(): GroupCollectorInterface;
|
||||
|
||||
/**
|
||||
* Look for specific external ID's.
|
||||
*
|
||||
* @param string $externalId
|
||||
*
|
||||
* @return GroupCollectorInterface
|
||||
*/
|
||||
public function setExternalId(string $externalId): GroupCollectorInterface;
|
||||
|
||||
/**
|
||||
* Look for specific external ID's.
|
||||
*
|
||||
* @param string $externalId
|
||||
*
|
||||
* @return GroupCollectorInterface
|
||||
*/
|
||||
public function setInternalReference(string $externalId): GroupCollectorInterface;
|
||||
|
||||
}
|
||||
|
@@ -77,7 +77,7 @@ class Help implements HelpInterface
|
||||
*/
|
||||
public function getFromGitHub(string $route, string $language): string
|
||||
{
|
||||
$uri = sprintf('https://raw.githubusercontent.com/firefly-iii/help/master/%s/%s.md', $language, $route);
|
||||
$uri = sprintf('https://raw.githubusercontent.com/firefly-iii/help/main/%s/%s.md', $language, $route);
|
||||
Log::debug(sprintf('Trying to get %s...', $uri));
|
||||
$opt = ['headers' => ['User-Agent' => $this->userAgent]];
|
||||
$content = '';
|
||||
|
@@ -109,15 +109,13 @@ class NetWorth implements NetWorthInterface
|
||||
|
||||
Log::debug(sprintf('Balance is %s', $balance));
|
||||
|
||||
// if the account is a credit card, subtract the virtual balance from the balance,
|
||||
// to better reflect that this is not money that is actually "yours".
|
||||
$role = (string) $this->accountRepository->getMetaValue($account, 'account_role');
|
||||
// always subtract virtual balance.
|
||||
$virtualBalance = (string) $account->virtual_balance;
|
||||
if ('ccAsset' === $role && '' !== $virtualBalance && (float) $virtualBalance > 0) {
|
||||
if ('' !== $virtualBalance) {
|
||||
$balance = bcsub($balance, $virtualBalance);
|
||||
}
|
||||
|
||||
Log::debug(sprintf('Balance corrected to %s', $balance));
|
||||
Log::debug(sprintf('Balance corrected to %s because of virtual balance (%s)', $balance, $virtualBalance));
|
||||
|
||||
if (!isset($netWorth[$currencyId])) {
|
||||
$netWorth[$currencyId] = '0';
|
||||
|
@@ -151,7 +151,12 @@ class CreateController extends Controller
|
||||
// store attachment(s):
|
||||
/** @var array $files */
|
||||
$files = $request->hasFile('attachments') ? $request->file('attachments') : null;
|
||||
$this->attachments->saveAttachmentsForModel($account, $files);
|
||||
if (null !== $files && !auth()->user()->hasRole('demo')) {
|
||||
$this->attachments->saveAttachmentsForModel($account, $files);
|
||||
}
|
||||
if (null !== $files && auth()->user()->hasRole('demo')) {
|
||||
session()->flash('info',(string)trans('firefly.no_att_demo_user'));
|
||||
}
|
||||
|
||||
if (count($this->attachments->getMessages()->get('attachments')) > 0) {
|
||||
$request->session()->flash('info', $this->attachments->getMessages()->get('attachments')); // @codeCoverageIgnore
|
||||
|
@@ -49,8 +49,7 @@ class EditController extends Controller
|
||||
/** @var AccountRepositoryInterface The account repository */
|
||||
private $repository;
|
||||
|
||||
/** @var AttachmentHelperInterface Helper for attachments. */
|
||||
private $attachments;
|
||||
private AttachmentHelperInterface $attachments;
|
||||
|
||||
/**
|
||||
* EditController constructor.
|
||||
@@ -67,7 +66,7 @@ class EditController extends Controller
|
||||
|
||||
$this->repository = app(AccountRepositoryInterface::class);
|
||||
$this->currencyRepos = app(CurrencyRepositoryInterface::class);
|
||||
$this->attachments = app(AttachmentHelperInterface::class);
|
||||
$this->attachments = app(AttachmentHelperInterface::class);
|
||||
|
||||
return $next($request);
|
||||
}
|
||||
@@ -190,9 +189,13 @@ class EditController extends Controller
|
||||
app('preferences')->mark();
|
||||
|
||||
// store new attachment(s):
|
||||
/** @var array $files */
|
||||
$files = $request->hasFile('attachments') ? $request->file('attachments') : null;
|
||||
$this->attachments->saveAttachmentsForModel($account, $files);
|
||||
if (null !== $files && !auth()->user()->hasRole('demo')) {
|
||||
$this->attachments->saveAttachmentsForModel($account, $files);
|
||||
}
|
||||
if (null !== $files && auth()->user()->hasRole('demo')) {
|
||||
session()->flash('info',(string)trans('firefly.no_att_demo_user'));
|
||||
}
|
||||
|
||||
if (count($this->attachments->getMessages()->get('attachments')) > 0) {
|
||||
$request->session()->flash('info', $this->attachments->getMessages()->get('attachments')); // @codeCoverageIgnore
|
||||
|
@@ -101,7 +101,7 @@ class IndexController extends Controller
|
||||
$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->interest = number_format((float) $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));
|
||||
}
|
||||
@@ -155,7 +155,7 @@ class IndexController extends Controller
|
||||
$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->interest = number_format((float) $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));
|
||||
$account->location = $this->repository->getLocation($account);
|
||||
|
@@ -129,9 +129,8 @@ class ReconcileController extends Controller
|
||||
|
||||
$startDate = clone $start;
|
||||
$startDate->subDay();
|
||||
$startBalance = round(app('steam')->balance($account, $startDate), $currency->decimal_places);
|
||||
|
||||
$endBalance = round(app('steam')->balance($account, $end), $currency->decimal_places);
|
||||
$startBalance = number_format((float) app('steam')->balance($account, $startDate), $currency->decimal_places, '.', '');
|
||||
$endBalance = number_format((float) app('steam')->balance($account, $end), $currency->decimal_places, '.', '');
|
||||
$subTitleIcon = config(sprintf('firefly.subIconsByIdentifier.%s', $account->accountType->type));
|
||||
$subTitle = (string) trans('firefly.reconcile_account', ['account' => $account->name]);
|
||||
|
||||
|
@@ -46,10 +46,8 @@ class ShowController extends Controller
|
||||
{
|
||||
use UserNavigation, PeriodOverview;
|
||||
|
||||
/** @var CurrencyRepositoryInterface The currency repository */
|
||||
private $currencyRepos;
|
||||
/** @var AccountRepositoryInterface The account repository */
|
||||
private $repository;
|
||||
private CurrencyRepositoryInterface $currencyRepos;
|
||||
private AccountRepositoryInterface $repository;
|
||||
|
||||
/**
|
||||
* ShowController constructor.
|
||||
|
@@ -25,7 +25,6 @@ namespace FireflyIII\Http\Controllers\Admin;
|
||||
|
||||
use FireflyIII\Http\Controllers\Controller;
|
||||
use FireflyIII\Http\Middleware\IsDemoUser;
|
||||
use FireflyIII\Http\Middleware\IsSandStormUser;
|
||||
use FireflyIII\Http\Requests\ConfigurationRequest;
|
||||
use Illuminate\Contracts\View\Factory;
|
||||
use Illuminate\Http\RedirectResponse;
|
||||
@@ -55,7 +54,6 @@ class ConfigurationController extends Controller
|
||||
}
|
||||
);
|
||||
$this->middleware(IsDemoUser::class)->except(['index']);
|
||||
$this->middleware(IsSandStormUser::class);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@@ -25,7 +25,6 @@ namespace FireflyIII\Http\Controllers\Admin;
|
||||
use FireflyIII\Events\AdminRequestedTestMessage;
|
||||
use FireflyIII\Http\Controllers\Controller;
|
||||
use FireflyIII\Http\Middleware\IsDemoUser;
|
||||
use FireflyIII\Http\Middleware\IsSandStormUser;
|
||||
use FireflyIII\User;
|
||||
use Illuminate\Contracts\View\Factory;
|
||||
use Illuminate\Http\RedirectResponse;
|
||||
@@ -48,7 +47,6 @@ class HomeController extends Controller
|
||||
{
|
||||
parent::__construct();
|
||||
$this->middleware(IsDemoUser::class)->except(['index']);
|
||||
$this->middleware(IsSandStormUser::class)->except(['index']);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -61,9 +59,8 @@ class HomeController extends Controller
|
||||
Log::channel('audit')->info('User visits admin index.');
|
||||
$title = (string) trans('firefly.administration');
|
||||
$mainTitleIcon = 'fa-hand-spock-o';
|
||||
$sandstorm = 1 === (int) getenv('SANDSTORM');
|
||||
|
||||
return view('admin.index', compact('title', 'mainTitleIcon', 'sandstorm'));
|
||||
return view('admin.index', compact('title', 'mainTitleIcon'));
|
||||
}
|
||||
|
||||
/**
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user