mirror of
https://github.com/firefly-iii/firefly-iii.git
synced 2025-11-03 04:41:41 +00:00
Compare commits
415 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e6854b9265 | ||
|
|
122cab1757 | ||
|
|
51b07f08ac | ||
|
|
e453ee19a1 | ||
|
|
4786c97c0b | ||
|
|
b5d4e82f45 | ||
|
|
c0072625c6 | ||
|
|
8c2455e8dd | ||
|
|
55c82b2a0f | ||
|
|
3120e29940 | ||
|
|
1211a5c878 | ||
|
|
8f98be32f9 | ||
|
|
65764199fe | ||
|
|
9ce39f5724 | ||
|
|
59922e6c2e | ||
|
|
cb62469a80 | ||
|
|
3df8c4ff75 | ||
|
|
cf4c1d8089 | ||
|
|
88539497bf | ||
|
|
123693096c | ||
|
|
60786461a9 | ||
|
|
452b6d0e1b | ||
|
|
d04efb8325 | ||
|
|
d1a09ff33b | ||
|
|
29bed2547c | ||
|
|
1209c4e76a | ||
|
|
9cdaf7076a | ||
|
|
2a1738cbe1 | ||
|
|
09bd0b572a | ||
|
|
9c19a08b17 | ||
|
|
37f05338f7 | ||
|
|
a72af79fab | ||
|
|
2dfd230918 | ||
|
|
409c24d45a | ||
|
|
35e187be77 | ||
|
|
df78ef1c78 | ||
|
|
d978838c84 | ||
|
|
3320e06f81 | ||
|
|
ab50a6518b | ||
|
|
e1155328b8 | ||
|
|
daa6ddc39f | ||
|
|
3b1ffc87bc | ||
|
|
94be254367 | ||
|
|
abb1095cef | ||
|
|
f2849c8058 | ||
|
|
e5a08d2cf1 | ||
|
|
46e01475fc | ||
|
|
89c1a2d912 | ||
|
|
2be7813a67 | ||
|
|
cbf14f541c | ||
|
|
8ee4c2ea11 | ||
|
|
980120f1bd | ||
|
|
679e72e5e2 | ||
|
|
ff7f4e5bba | ||
|
|
582c6676c6 | ||
|
|
8002610234 | ||
|
|
3ba81c6254 | ||
|
|
dc16a1a430 | ||
|
|
2f50fb38b0 | ||
|
|
aca008c911 | ||
|
|
ad0dcc2cf4 | ||
|
|
be1d5591c4 | ||
|
|
bb57015004 | ||
|
|
96f7047989 | ||
|
|
25e6114948 | ||
|
|
0ac4a42351 | ||
|
|
02687dfe53 | ||
|
|
ba10aa5ca5 | ||
|
|
c000e090fe | ||
|
|
9c0893c093 | ||
|
|
1e1aa28ab2 | ||
|
|
52a5995bd1 | ||
|
|
5ca0a9f75a | ||
|
|
45d99aa456 | ||
|
|
39eeea9c3c | ||
|
|
55a6cc5cd4 | ||
|
|
e3ecfdfac6 | ||
|
|
3ddbb282d7 | ||
|
|
346478622b | ||
|
|
fcb9e76c17 | ||
|
|
bbcd86eab5 | ||
|
|
24a6f5f36c | ||
|
|
6e18b8056d | ||
|
|
1e5137e5db | ||
|
|
78342537a0 | ||
|
|
b20e736f41 | ||
|
|
df65f08dec | ||
|
|
03b6f6fcb1 | ||
|
|
5c30981e76 | ||
|
|
0b2ca03848 | ||
|
|
70041e713e | ||
|
|
31625cad4b | ||
|
|
8663c877af | ||
|
|
f76ce602ce | ||
|
|
32d1554fbe | ||
|
|
7c28b47f91 | ||
|
|
ff249a4ee6 | ||
|
|
a5c75e6abe | ||
|
|
b8a8ddf23e | ||
|
|
43c52daf6b | ||
|
|
f0265b9fda | ||
|
|
07813fa858 | ||
|
|
ca7c86a057 | ||
|
|
c59ccb1077 | ||
|
|
2ab45ac5d4 | ||
|
|
ae6b177a08 | ||
|
|
50806ace32 | ||
|
|
efb0dc42ff | ||
|
|
2fbeef95f1 | ||
|
|
f02d524e82 | ||
|
|
6479fbabed | ||
|
|
059bf32563 | ||
|
|
2f55499f7d | ||
|
|
9c8bcd4f4c | ||
|
|
2715a181e3 | ||
|
|
b3c831d596 | ||
|
|
274885c8a6 | ||
|
|
d6e5f71d50 | ||
|
|
b9536dfe4e | ||
|
|
22a6e34279 | ||
|
|
b1a68b087c | ||
|
|
ef8f9672af | ||
|
|
b696b09f92 | ||
|
|
9892e70028 | ||
|
|
52f885df20 | ||
|
|
a58c6b0cec | ||
|
|
b59723f276 | ||
|
|
20ab27b237 | ||
|
|
046d7befca | ||
|
|
a8cbbde8fc | ||
|
|
efb7d4275d | ||
|
|
d4f275e566 | ||
|
|
45db911011 | ||
|
|
50fccec438 | ||
|
|
67e72e864c | ||
|
|
dff4946b48 | ||
|
|
a38700f3fa | ||
|
|
42c4441755 | ||
|
|
1a4b646acd | ||
|
|
5888dd38a2 | ||
|
|
f56d63c754 | ||
|
|
93db50383a | ||
|
|
4e9b5a71db | ||
|
|
c85be915e6 | ||
|
|
1df4cdda42 | ||
|
|
cad03b04ae | ||
|
|
cddfa3a8d2 | ||
|
|
3a49af94d0 | ||
|
|
e60320a9be | ||
|
|
0ffb3508c6 | ||
|
|
d618f6d355 | ||
|
|
e542a65bf3 | ||
|
|
d1e1314dcf | ||
|
|
9ebdb00579 | ||
|
|
95a7a0c90d | ||
|
|
cabd3d60f0 | ||
|
|
ab8ee8b72a | ||
|
|
01f06a7e5b | ||
|
|
aa7d4a610b | ||
|
|
3f61b6d707 | ||
|
|
9ae0cc5700 | ||
|
|
6f65a73dd9 | ||
|
|
fb676a9ad7 | ||
|
|
dd66a1adf0 | ||
|
|
8c9bb3addb | ||
|
|
472c1a0c37 | ||
|
|
6fe8bf6c41 | ||
|
|
342e6f2fef | ||
|
|
23a8e3ef41 | ||
|
|
7c11b99469 | ||
|
|
e715162ed6 | ||
|
|
368cc550cb | ||
|
|
60311341e0 | ||
|
|
749ebd9cc4 | ||
|
|
c699a14a35 | ||
|
|
b05a2d385c | ||
|
|
7c78d19e3a | ||
|
|
8632307cb1 | ||
|
|
5a18f3ce4a | ||
|
|
1258aff0b4 | ||
|
|
b0904c11a0 | ||
|
|
ca517eb4d9 | ||
|
|
c522dd2931 | ||
|
|
7399edee2e | ||
|
|
ec93b7b5a0 | ||
|
|
280762fff3 | ||
|
|
b733fa2961 | ||
|
|
5176f8bdc2 | ||
|
|
91d96b2f0e | ||
|
|
c3229e597c | ||
|
|
0f371bc5a9 | ||
|
|
297d5940ce | ||
|
|
3b27ceaf53 | ||
|
|
d9142c1197 | ||
|
|
9b3d1160d6 | ||
|
|
05d144c279 | ||
|
|
a318b66854 | ||
|
|
431eef5e80 | ||
|
|
a8d20c5a01 | ||
|
|
676d75646e | ||
|
|
6cbc438aa0 | ||
|
|
4a8913c98c | ||
|
|
9d1ecd845a | ||
|
|
16987aca71 | ||
|
|
445e8d7838 | ||
|
|
e521d5dcd0 | ||
|
|
a4ed85d33b | ||
|
|
65e8a7fed6 | ||
|
|
1052a19262 | ||
|
|
a2b7a5f1f0 | ||
|
|
9f09872e0f | ||
|
|
60ea033064 | ||
|
|
1f3badb731 | ||
|
|
eb0281e47f | ||
|
|
7fc94415fb | ||
|
|
8dd7d9ba26 | ||
|
|
b9ac43e86d | ||
|
|
99a5f827ae | ||
|
|
fbdb7e099c | ||
|
|
6080dabb56 | ||
|
|
cf1540060a | ||
|
|
f96a9f652d | ||
|
|
d969109e05 | ||
|
|
9a08cf6266 | ||
|
|
10ea575cd8 | ||
|
|
356876b2b2 | ||
|
|
f5197ec2e0 | ||
|
|
71af5db38e | ||
|
|
45195e6496 | ||
|
|
a56a6df557 | ||
|
|
d7e6a7b125 | ||
|
|
ddabfbc1ad | ||
|
|
944864ed25 | ||
|
|
1c795e71d5 | ||
|
|
7d7e1366a6 | ||
|
|
158a7b1517 | ||
|
|
03f19ec235 | ||
|
|
a82ec20833 | ||
|
|
fb8e238319 | ||
|
|
ab943bf006 | ||
|
|
b15b58f099 | ||
|
|
fee8d962e3 | ||
|
|
4b1eaddfc2 | ||
|
|
c0aca0e021 | ||
|
|
4c3910dc59 | ||
|
|
ec9e8cd672 | ||
|
|
5cbd93bba6 | ||
|
|
30fc0fbf54 | ||
|
|
d26e847d54 | ||
|
|
7c553c1f0b | ||
|
|
eb63163ddf | ||
|
|
6e4adc86b8 | ||
|
|
b46398242f | ||
|
|
db071b1014 | ||
|
|
ebf6b50126 | ||
|
|
ebc498f0ff | ||
|
|
ef4c34a31f | ||
|
|
1d26c12771 | ||
|
|
cb8b49fd7a | ||
|
|
b0e6d12325 | ||
|
|
6da6a68e33 | ||
|
|
a12fd4a3ae | ||
|
|
003d8ba02a | ||
|
|
acb2a8697a | ||
|
|
aff0e4a9df | ||
|
|
b7ba04dacf | ||
|
|
ee6c8786b2 | ||
|
|
4fc19b7eba | ||
|
|
37964a375d | ||
|
|
b8573d03a4 | ||
|
|
b104914076 | ||
|
|
1d30b58685 | ||
|
|
326baa93a7 | ||
|
|
ab9f26f850 | ||
|
|
9a944175ac | ||
|
|
0bcc3240b7 | ||
|
|
1bf3608142 | ||
|
|
9dc971550c | ||
|
|
33c52513a3 | ||
|
|
2408ff11f6 | ||
|
|
3d130e5d99 | ||
|
|
bc0355c5b1 | ||
|
|
b90b13632e | ||
|
|
bad57c907c | ||
|
|
374793eb92 | ||
|
|
8a6ae6105e | ||
|
|
ecda8eebf2 | ||
|
|
f0a5257921 | ||
|
|
860a4bdc0a | ||
|
|
f6ddf72323 | ||
|
|
ec212bb98e | ||
|
|
fd7d37ac23 | ||
|
|
b4cd0d6bbc | ||
|
|
0a5908e4d8 | ||
|
|
59f0631685 | ||
|
|
7718deb4a5 | ||
|
|
75d52b7024 | ||
|
|
ecc72dd01b | ||
|
|
6591512cf6 | ||
|
|
4a0e97e36a | ||
|
|
f90b2d9410 | ||
|
|
582ba0ce5d | ||
|
|
ce411ab9b0 | ||
|
|
d90468db3f | ||
|
|
3a621e6ff7 | ||
|
|
a7ffe66547 | ||
|
|
4a57f4d6dd | ||
|
|
5b72ffa575 | ||
|
|
04a9e2cec2 | ||
|
|
17022c1174 | ||
|
|
59914a9d87 | ||
|
|
a7b9653de3 | ||
|
|
c8dc065e24 | ||
|
|
bac58ad0c2 | ||
|
|
6b2431b054 | ||
|
|
7e212ebd48 | ||
|
|
b3223b90da | ||
|
|
6ea773cdd7 | ||
|
|
997cddcb5a | ||
|
|
8228f76f5d | ||
|
|
b35ee9ccf4 | ||
|
|
16942af52b | ||
|
|
b190ce3538 | ||
|
|
9027915280 | ||
|
|
19aaaef37e | ||
|
|
a3bb90e160 | ||
|
|
06bae0dd8b | ||
|
|
7d48ab5671 | ||
|
|
8588405aa1 | ||
|
|
8238ae7d0a | ||
|
|
78ebec01a4 | ||
|
|
ac1137d7e8 | ||
|
|
212e9b833b | ||
|
|
52ad0ba352 | ||
|
|
318d86a1f5 | ||
|
|
fbffba4c21 | ||
|
|
c7f4e5423a | ||
|
|
5f282a9b7d | ||
|
|
7539ee3560 | ||
|
|
032389c6c0 | ||
|
|
788ac54f86 | ||
|
|
4e0fbc8532 | ||
|
|
5764d9756c | ||
|
|
85e79922ab | ||
|
|
6f3826a6ff | ||
|
|
c061b0b777 | ||
|
|
fc7bbfa8e2 | ||
|
|
0da20c7a1b | ||
|
|
4e2d5fe166 | ||
|
|
70767678ba | ||
|
|
7340e146f1 | ||
|
|
583bc59d23 | ||
|
|
ff5b872fa3 | ||
|
|
28517a8b78 | ||
|
|
34138d1533 | ||
|
|
ccf589f093 | ||
|
|
3ee100e71e | ||
|
|
1e0547a02c | ||
|
|
577e1f1b56 | ||
|
|
a7d25125a7 | ||
|
|
dbb09ef5d1 | ||
|
|
d840c94a29 | ||
|
|
114980480e | ||
|
|
95b1a821f3 | ||
|
|
206397cc81 | ||
|
|
a6b1a6d0c2 | ||
|
|
aba39a3b27 | ||
|
|
b5f095dd91 | ||
|
|
a9e92d4fa6 | ||
|
|
867a2eacd3 | ||
|
|
accecf6a76 | ||
|
|
f12b3bc9b7 | ||
|
|
a2ed755c9c | ||
|
|
235639b728 | ||
|
|
b1d5882fa6 | ||
|
|
39e632d950 | ||
|
|
87ced85657 | ||
|
|
0c53a8db66 | ||
|
|
84dcbaf0e7 | ||
|
|
047440eaea | ||
|
|
217ad0234b | ||
|
|
9795f46bea | ||
|
|
10bc0098b9 | ||
|
|
7a900fd3d9 | ||
|
|
45cfb4e565 | ||
|
|
5320480767 | ||
|
|
3e18e984fa | ||
|
|
fce759e98f | ||
|
|
f4439778f1 | ||
|
|
11176fc212 | ||
|
|
ffc71da2eb | ||
|
|
246fa0d6e4 | ||
|
|
3444146da3 | ||
|
|
5c4a482f64 | ||
|
|
01f84ea11d | ||
|
|
08402babbd | ||
|
|
7ef3dcbd23 | ||
|
|
8836fa205b | ||
|
|
f544a278c5 | ||
|
|
4b8fd6adb9 | ||
|
|
1ac8a9b4ac | ||
|
|
08a8a69b34 | ||
|
|
dbd668bda5 | ||
|
|
cc0760553b | ||
|
|
1142ff6b1f | ||
|
|
927da5d742 | ||
|
|
9a734e48fe | ||
|
|
345fe39b54 | ||
|
|
c7e9d62712 | ||
|
|
5918095f11 | ||
|
|
24612eb634 | ||
|
|
f7125d6198 | ||
|
|
47870cd50c | ||
|
|
45fbf83971 | ||
|
|
4d933e1ef7 |
50
.env.example
50
.env.example
@@ -69,6 +69,8 @@ DB_PORT=3306
|
|||||||
DB_DATABASE=firefly
|
DB_DATABASE=firefly
|
||||||
DB_USERNAME=firefly
|
DB_USERNAME=firefly
|
||||||
DB_PASSWORD=secret_firefly_password
|
DB_PASSWORD=secret_firefly_password
|
||||||
|
# leave empty or omit when not using a socket connection
|
||||||
|
DB_SOCKET=
|
||||||
|
|
||||||
# MySQL supports SSL. You can configure it here.
|
# 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
|
# If you use Docker or similar, you can set these variables from a file by appending them with _FILE
|
||||||
@@ -89,6 +91,9 @@ PGSQL_SSL_CERT=null
|
|||||||
PGSQL_SSL_KEY=null
|
PGSQL_SSL_KEY=null
|
||||||
PGSQL_SSL_CRL_FILE=null
|
PGSQL_SSL_CRL_FILE=null
|
||||||
|
|
||||||
|
# more PostgreSQL settings
|
||||||
|
PGSQL_SCHEMA=public
|
||||||
|
|
||||||
# If you're looking for performance improvements, you could install memcached or redis
|
# If you're looking for performance improvements, you could install memcached or redis
|
||||||
CACHE_DRIVER=file
|
CACHE_DRIVER=file
|
||||||
SESSION_DRIVER=file
|
SESSION_DRIVER=file
|
||||||
@@ -137,7 +142,6 @@ MAIL_ENCRYPTION=null
|
|||||||
MAILGUN_DOMAIN=
|
MAILGUN_DOMAIN=
|
||||||
MAILGUN_SECRET=
|
MAILGUN_SECRET=
|
||||||
|
|
||||||
|
|
||||||
# If you are on EU region in mailgun, use api.eu.mailgun.net, otherwise use api.mailgun.net
|
# If you are on EU region in mailgun, use api.eu.mailgun.net, otherwise use api.mailgun.net
|
||||||
# If you use Docker or similar, you can set this variable from a file by appending it with _FILE
|
# If you use Docker or similar, you can set this variable from a file by appending it with _FILE
|
||||||
MAILGUN_ENDPOINT=api.mailgun.net
|
MAILGUN_ENDPOINT=api.mailgun.net
|
||||||
@@ -171,42 +175,14 @@ MAP_DEFAULT_ZOOM=6
|
|||||||
#
|
#
|
||||||
# Firefly III supports a few authentication methods:
|
# Firefly III supports a few authentication methods:
|
||||||
# - 'web' (default, uses built in DB)
|
# - 'web' (default, uses built in DB)
|
||||||
# - 'ldap'
|
|
||||||
# - 'remote_user_guard' for Authelia etc
|
# - 'remote_user_guard' for Authelia etc
|
||||||
# Read more about these settings in the documentation.
|
# Read more about these settings in the documentation.
|
||||||
# https://docs.firefly-iii.org/advanced-installation/authentication
|
# https://docs.firefly-iii.org/advanced-installation/authentication
|
||||||
|
#
|
||||||
|
# LDAP is no longer supported :(
|
||||||
|
#
|
||||||
AUTHENTICATION_GUARD=web
|
AUTHENTICATION_GUARD=web
|
||||||
|
|
||||||
#
|
|
||||||
# Your LDAP server may speak a dialect. You can choose between 'OpenLDAP' and 'ActiveDirectory'
|
|
||||||
# Anything else defaults to 'ActiveDirectory'
|
|
||||||
#
|
|
||||||
LDAP_DIALECT=OpenLDAP
|
|
||||||
|
|
||||||
#
|
|
||||||
# LDAP connection settings:
|
|
||||||
#
|
|
||||||
LDAP_HOST=ldap.yourserver.com
|
|
||||||
LDAP_PORT=389
|
|
||||||
LDAP_TIMEOUT=5
|
|
||||||
LDAP_SSL=false
|
|
||||||
LDAP_TLS=false
|
|
||||||
|
|
||||||
LDAP_BASE_DN="o=something,dc=site,dc=com"
|
|
||||||
LDAP_USERNAME="uid=X,ou=,o=,dc=something,dc=com"
|
|
||||||
LDAP_PASSWORD=super_secret
|
|
||||||
|
|
||||||
LDAP_AUTH_FIELD=uid
|
|
||||||
|
|
||||||
#
|
|
||||||
# If you wish to only authenticate users from a specific group, use the base DN above.
|
|
||||||
#
|
|
||||||
# If you require extra/special filters please use the LDAP_EXTRA_FILTER with a valid DN.
|
|
||||||
#
|
|
||||||
# The extra filter will only be applied after the user is authenticated.
|
|
||||||
#
|
|
||||||
LDAP_EXTRA_FILTER=
|
|
||||||
|
|
||||||
#
|
#
|
||||||
# Remote user guard settings
|
# Remote user guard settings
|
||||||
#
|
#
|
||||||
@@ -249,6 +225,8 @@ ALLOW_WEBHOOKS=false
|
|||||||
#
|
#
|
||||||
# For more info: https://docs.firefly-iii.org/firefly-iii/advanced-installation/cron/
|
# For more info: https://docs.firefly-iii.org/firefly-iii/advanced-installation/cron/
|
||||||
#
|
#
|
||||||
|
# You can set this variable from a file by appending it with _FILE
|
||||||
|
#
|
||||||
STATIC_CRON_TOKEN=
|
STATIC_CRON_TOKEN=
|
||||||
|
|
||||||
# You can fine tune the start-up of a Docker container by editing these environment variables.
|
# You can fine tune the start-up of a Docker container by editing these environment variables.
|
||||||
@@ -256,6 +234,13 @@ STATIC_CRON_TOKEN=
|
|||||||
# However if you know what you're doing you can significantly speed up container start times.
|
# However if you know what you're doing you can significantly speed up container start times.
|
||||||
# Set each value to true to enable, or false to disable.
|
# Set each value to true to enable, or false to disable.
|
||||||
|
|
||||||
|
# Set this to true to build all locales supported by Firefly III.
|
||||||
|
# This may take quite some time (several minutes) and is generally not recommended.
|
||||||
|
# If you wish to change or alter the list of locales, start your Docker container with
|
||||||
|
# `docker run -v locale.gen:/etc/locale.gen -e DKR_BUILD_LOCALE=true`
|
||||||
|
# and make sure your preferred locales are in your own locale.gen.
|
||||||
|
DKR_BUILD_LOCALE=false
|
||||||
|
|
||||||
# Check if the SQLite database exists. Can be skipped if you're not using SQLite.
|
# Check if the SQLite database exists. Can be skipped if you're not using SQLite.
|
||||||
# Won't significantly speed up things.
|
# Won't significantly speed up things.
|
||||||
DKR_CHECK_SQLITE=true
|
DKR_CHECK_SQLITE=true
|
||||||
@@ -284,7 +269,6 @@ DKR_RUN_PASSPORT_INSTALL=true
|
|||||||
# Leave the following configuration vars as is.
|
# Leave the following configuration vars as is.
|
||||||
# Unless you like to tinker and know what you're doing.
|
# Unless you like to tinker and know what you're doing.
|
||||||
APP_NAME=FireflyIII
|
APP_NAME=FireflyIII
|
||||||
ADLDAP_CONNECTION=default
|
|
||||||
BROADCAST_DRIVER=log
|
BROADCAST_DRIVER=log
|
||||||
QUEUE_DRIVER=sync
|
QUEUE_DRIVER=sync
|
||||||
CACHE_PREFIX=firefly
|
CACHE_PREFIX=firefly
|
||||||
|
|||||||
3
.github/ISSUE_TEMPLATE/bug.yml
vendored
3
.github/ISSUE_TEMPLATE/bug.yml
vendored
@@ -14,8 +14,9 @@ body:
|
|||||||
label: I've found a bug and checked that ...
|
label: I've found a bug and checked that ...
|
||||||
description: Make sure that your request fulfills all of the following requirements. If one requirement cannot be satisfied, explain in detail why.
|
description: Make sure that your request fulfills all of the following requirements. If one requirement cannot be satisfied, explain in detail why.
|
||||||
options:
|
options:
|
||||||
- label: ... the documentation does not mention anything about my problem
|
- label: ... [the documentation](https://docs.firefly-iii.org/) does not mention anything about my problem
|
||||||
- label: ... there are no open or closed issues that are related to my problem
|
- label: ... there are no open or closed issues that are related to my problem
|
||||||
|
- label: ... it's [definitely me, not you](https://github.com/firefly-iii/firefly-iii/blob/main/.github/its_you_not_me.md)
|
||||||
|
|
||||||
- type: textarea
|
- type: textarea
|
||||||
attributes:
|
attributes:
|
||||||
|
|||||||
8
.github/dependabot.yml
vendored
8
.github/dependabot.yml
vendored
@@ -19,11 +19,3 @@ updates:
|
|||||||
schedule:
|
schedule:
|
||||||
interval: "weekly"
|
interval: "weekly"
|
||||||
|
|
||||||
# yarn / JS updates for new frontend
|
|
||||||
- package-ecosystem: "npm"
|
|
||||||
directory: "/frontend"
|
|
||||||
target-branch: develop
|
|
||||||
versioning-strategy: increase
|
|
||||||
labels: ["bug"]
|
|
||||||
schedule:
|
|
||||||
interval: "weekly"
|
|
||||||
|
|||||||
16
.github/its_you_not_me.md
vendored
Normal file
16
.github/its_you_not_me.md
vendored
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
# It's not you, it's me
|
||||||
|
|
||||||
|
Sometimes bugs reported to Firefly III are configuration and system problems on the user's side.
|
||||||
|
|
||||||
|
If you run into any of the following problems, there's a good chance it's not a Firefly III issue, but a configuration issue.
|
||||||
|
|
||||||
|
- ⚠️ Firefly III can't connect to the database when starting or the password is wrong, even though you're sure it's correct.
|
||||||
|
- ⚠️ Errors about a missing `APP_KEY` or other encryption/hash problems
|
||||||
|
- ⚠️ You can't login due to `419` errors (page expired)
|
||||||
|
- ⚠️ Any `500` error when starting Firefly III
|
||||||
|
- ⚠️ Any white page when starting Firefly III
|
||||||
|
- ⚠️ Time-out when starting Firefly III for the first time
|
||||||
|
- ⚠️ Firefly III does not work behind your reverse proxy
|
||||||
|
- ⚠️ You can't connect to the Data Importer due to 404's or authentication issues.
|
||||||
|
|
||||||
|
If you run into an issue like this, please start a [discussion](https://github.com/firefly-iii/firefly-iii/discussions) or chat on [Gitter.im](https://gitter.im/firefly-iii/firefly-iii). There's a good chance it's not a bug but something we can fix rather quickly :+1:
|
||||||
7
.github/mergify.yml
vendored
7
.github/mergify.yml
vendored
@@ -1,13 +1,8 @@
|
|||||||
pull_request_rules:
|
pull_request_rules:
|
||||||
- name: Security update by dependabot
|
|
||||||
conditions:
|
|
||||||
- author~=^dependabot(|-preview)\[bot\]$
|
|
||||||
actions:
|
|
||||||
merge:
|
|
||||||
method: merge
|
|
||||||
- name: Close all on main
|
- name: Close all on main
|
||||||
conditions:
|
conditions:
|
||||||
- base=main
|
- base=main
|
||||||
|
- -author~=^dependabot(|-preview)\[bot\]$
|
||||||
actions:
|
actions:
|
||||||
close:
|
close:
|
||||||
message: Please do not open PR's on the `main` branch, but on the `develop` branch only. Thank you!
|
message: Please do not open PR's on the `main` branch, but on the `develop` branch only. Thank you!
|
||||||
|
|||||||
2
.github/support.md
vendored
2
.github/support.md
vendored
@@ -25,7 +25,7 @@ Only then [create a new issue](https://github.com/firefly-iii/firefly-iii/issues
|
|||||||
## Issue closure and abandonment policy
|
## Issue closure and abandonment policy
|
||||||
|
|
||||||
- Issues can be converted into discussions if it's not a bug or feature request.
|
- Issues can be converted into discussions if it's not a bug or feature request.
|
||||||
- Features that won't be implemented will be labelled "wontfix". [This isn't personal](https://docs.firefly-iii.org/firefly-iii/support/features/#ideas-that-wont-be-implemented).
|
- Features that won't be implemented will be labelled "wontfix". [This isn't personal](https://docs.firefly-iii.org/firefly-iii/about-firefly-iii/what-its-not/).
|
||||||
- Issues can be closed if they're duplicates of other issues.
|
- Issues can be closed if they're duplicates of other issues.
|
||||||
- Issues can be closed if the answer is in the FAQ.
|
- Issues can be closed if the answer is in the FAQ.
|
||||||
- Issues will be closed automatically after 14 days.
|
- Issues will be closed automatically after 14 days.
|
||||||
|
|||||||
10
.gitignore
vendored
10
.gitignore
vendored
@@ -1,18 +1,8 @@
|
|||||||
/node_modules
|
/node_modules
|
||||||
/frontend/node_modules
|
/frontend/node_modules
|
||||||
/frontend/fonts
|
|
||||||
/frontend/images
|
|
||||||
/public/hot
|
|
||||||
/public/storage
|
|
||||||
/storage/*.key
|
/storage/*.key
|
||||||
/vendor
|
/vendor
|
||||||
/.vagrant
|
/.vagrant
|
||||||
Homestead.json
|
|
||||||
Homestead.yaml
|
|
||||||
npm-debug.log
|
npm-debug.log
|
||||||
yarn-error.log
|
yarn-error.log
|
||||||
.env
|
.env
|
||||||
public/google*.html
|
|
||||||
report.html
|
|
||||||
composer.phar
|
|
||||||
app.js.map
|
|
||||||
@@ -70,8 +70,9 @@ class AccountController extends Controller
|
|||||||
* @param AutocompleteRequest $request
|
* @param AutocompleteRequest $request
|
||||||
*
|
*
|
||||||
* @return JsonResponse
|
* @return JsonResponse
|
||||||
* @throws FireflyException
|
|
||||||
* @throws JsonException
|
* @throws JsonException
|
||||||
|
* @throws FireflyException
|
||||||
|
* @throws FireflyException
|
||||||
*/
|
*/
|
||||||
public function accounts(AutocompleteRequest $request): JsonResponse
|
public function accounts(AutocompleteRequest $request): JsonResponse
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -35,6 +35,9 @@ use FireflyIII\Repositories\Currency\CurrencyRepositoryInterface;
|
|||||||
use FireflyIII\Support\Http\Api\ApiSupport;
|
use FireflyIII\Support\Http\Api\ApiSupport;
|
||||||
use FireflyIII\User;
|
use FireflyIII\User;
|
||||||
use Illuminate\Http\JsonResponse;
|
use Illuminate\Http\JsonResponse;
|
||||||
|
use JsonException;
|
||||||
|
use Psr\Container\ContainerExceptionInterface;
|
||||||
|
use Psr\Container\NotFoundExceptionInterface;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Class AccountController
|
* Class AccountController
|
||||||
@@ -77,6 +80,9 @@ class AccountController extends Controller
|
|||||||
*
|
*
|
||||||
* @return JsonResponse
|
* @return JsonResponse
|
||||||
* @throws FireflyException
|
* @throws FireflyException
|
||||||
|
* @throws JsonException
|
||||||
|
* @throws ContainerExceptionInterface
|
||||||
|
* @throws NotFoundExceptionInterface
|
||||||
*/
|
*/
|
||||||
public function overview(DateRequest $request): JsonResponse
|
public function overview(DateRequest $request): JsonResponse
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -34,6 +34,8 @@ use Illuminate\Routing\Controller as BaseController;
|
|||||||
use League\Fractal\Manager;
|
use League\Fractal\Manager;
|
||||||
use League\Fractal\Serializer\JsonApiSerializer;
|
use League\Fractal\Serializer\JsonApiSerializer;
|
||||||
use Log;
|
use Log;
|
||||||
|
use Psr\Container\ContainerExceptionInterface;
|
||||||
|
use Psr\Container\NotFoundExceptionInterface;
|
||||||
use Symfony\Component\HttpFoundation\ParameterBag;
|
use Symfony\Component\HttpFoundation\ParameterBag;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -74,6 +76,8 @@ abstract class Controller extends BaseController
|
|||||||
* Method to grab all parameters from the URI.
|
* Method to grab all parameters from the URI.
|
||||||
*
|
*
|
||||||
* @return ParameterBag
|
* @return ParameterBag
|
||||||
|
* @throws ContainerExceptionInterface
|
||||||
|
* @throws NotFoundExceptionInterface
|
||||||
*/
|
*/
|
||||||
private function getParameters(): ParameterBag
|
private function getParameters(): ParameterBag
|
||||||
{
|
{
|
||||||
@@ -94,7 +98,7 @@ abstract class Controller extends BaseController
|
|||||||
$obj = Carbon::parse($date);
|
$obj = Carbon::parse($date);
|
||||||
} catch (InvalidDateException | InvalidFormatException $e) {
|
} catch (InvalidDateException | InvalidFormatException $e) {
|
||||||
// don't care
|
// don't care
|
||||||
Log::error(sprintf('Invalid date exception in API controller: %s', $e->getMessage()));
|
Log::warning(sprintf('Ignored invalid date "%s" in API controller parameter check: %s', $date, $e->getMessage()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
$bag->set($field, $obj);
|
$bag->set($field, $obj);
|
||||||
|
|||||||
@@ -201,4 +201,68 @@ class ListController extends Controller
|
|||||||
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', self::CONTENT_TYPE);
|
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', self::CONTENT_TYPE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This endpoint is documented at:
|
||||||
|
* https://api-docs.firefly-iii.org/#/budgets/listTransactionWithoutBudget
|
||||||
|
*
|
||||||
|
* Show all transactions.
|
||||||
|
*
|
||||||
|
* @param Request $request
|
||||||
|
*
|
||||||
|
* @return JsonResponse
|
||||||
|
* @throws FireflyException
|
||||||
|
* @codeCoverageIgnore
|
||||||
|
*/
|
||||||
|
public function withoutBudget(Request $request): JsonResponse
|
||||||
|
{
|
||||||
|
$pageSize = (int) app('preferences')->getForUser(auth()->user(), 'listPageSize', 50)->data;
|
||||||
|
|
||||||
|
// user can overrule page size with limit parameter.
|
||||||
|
$limit = $this->parameters->get('limit');
|
||||||
|
if (null !== $limit && $limit > 0) {
|
||||||
|
$pageSize = $limit;
|
||||||
|
}
|
||||||
|
|
||||||
|
$type = $request->get('type') ?? 'default';
|
||||||
|
$this->parameters->set('type', $type);
|
||||||
|
|
||||||
|
$types = $this->mapTransactionTypes($this->parameters->get('type'));
|
||||||
|
$manager = $this->getManager();
|
||||||
|
|
||||||
|
/** @var User $admin */
|
||||||
|
$admin = auth()->user();
|
||||||
|
|
||||||
|
// use new group collector:
|
||||||
|
/** @var GroupCollectorInterface $collector */
|
||||||
|
$collector = app(GroupCollectorInterface::class);
|
||||||
|
$collector
|
||||||
|
->setUser($admin)
|
||||||
|
// filter on budget.
|
||||||
|
->withoutBudget()
|
||||||
|
// 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.budgets.without-budget') . $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', self::CONTENT_TYPE);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -77,7 +77,7 @@ class ShowController extends Controller
|
|||||||
$pageSize = (int) app('preferences')->getForUser(auth()->user(), 'listPageSize', 50)->data;
|
$pageSize = (int) app('preferences')->getForUser(auth()->user(), 'listPageSize', 50)->data;
|
||||||
|
|
||||||
// get list of budgets. Count it and split it.
|
// get list of budgets. Count it and split it.
|
||||||
$collection = $this->repository->getAll();
|
$collection = $this->repository->get();
|
||||||
$count = $collection->count();
|
$count = $collection->count();
|
||||||
$piggyBanks = $collection->slice(($this->parameters->get('page') - 1) * $pageSize, $pageSize);
|
$piggyBanks = $collection->slice(($this->parameters->get('page') - 1) * $pageSize, $pageSize);
|
||||||
|
|
||||||
|
|||||||
@@ -145,11 +145,11 @@ class TriggerController extends Controller
|
|||||||
// add a range:
|
// add a range:
|
||||||
$ruleEngine->addOperator(['type' => 'date_before', 'value' => $parameters['end']->format('Y-m-d')]);
|
$ruleEngine->addOperator(['type' => 'date_before', 'value' => $parameters['end']->format('Y-m-d')]);
|
||||||
}
|
}
|
||||||
if (array_key_exists('accounts', $parameters) && '' !== $parameters['accounts']) {
|
if (array_key_exists('accounts', $parameters) && is_array($parameters['accounts']) && count($parameters['accounts']) > 0) {
|
||||||
$ruleEngine->addOperator(['type' => 'account_id', 'value' => implode(',', $parameters['accounts'])]);
|
$ruleEngine->addOperator(['type' => 'account_id', 'value' => implode(',', $parameters['accounts'])]);
|
||||||
}
|
}
|
||||||
|
|
||||||
// file the rule(s)
|
// fire the rule(s)
|
||||||
$ruleEngine->fire();
|
$ruleEngine->fire();
|
||||||
|
|
||||||
return response()->json([], 204);
|
return response()->json([], 204);
|
||||||
|
|||||||
@@ -33,6 +33,7 @@ use FireflyIII\Support\Http\Api\TransactionFilter;
|
|||||||
use FireflyIII\Transformers\CurrencyTransformer;
|
use FireflyIII\Transformers\CurrencyTransformer;
|
||||||
use Illuminate\Http\JsonResponse;
|
use Illuminate\Http\JsonResponse;
|
||||||
use Illuminate\Pagination\LengthAwarePaginator;
|
use Illuminate\Pagination\LengthAwarePaginator;
|
||||||
|
use JsonException;
|
||||||
use League\Fractal\Pagination\IlluminatePaginatorAdapter;
|
use League\Fractal\Pagination\IlluminatePaginatorAdapter;
|
||||||
use League\Fractal\Resource\Collection as FractalCollection;
|
use League\Fractal\Resource\Collection as FractalCollection;
|
||||||
use League\Fractal\Resource\Item;
|
use League\Fractal\Resource\Item;
|
||||||
@@ -72,6 +73,7 @@ class ShowController extends Controller
|
|||||||
*
|
*
|
||||||
* @return JsonResponse
|
* @return JsonResponse
|
||||||
* @throws FireflyException
|
* @throws FireflyException
|
||||||
|
* @throws JsonException
|
||||||
* @codeCoverageIgnore
|
* @codeCoverageIgnore
|
||||||
*/
|
*/
|
||||||
public function index(): JsonResponse
|
public function index(): JsonResponse
|
||||||
@@ -106,6 +108,8 @@ class ShowController extends Controller
|
|||||||
* @param TransactionCurrency $currency
|
* @param TransactionCurrency $currency
|
||||||
*
|
*
|
||||||
* @return JsonResponse
|
* @return JsonResponse
|
||||||
|
* @throws FireflyException
|
||||||
|
* @throws JsonException
|
||||||
* @codeCoverageIgnore
|
* @codeCoverageIgnore
|
||||||
*/
|
*/
|
||||||
public function show(TransactionCurrency $currency): JsonResponse
|
public function show(TransactionCurrency $currency): JsonResponse
|
||||||
@@ -130,6 +134,8 @@ class ShowController extends Controller
|
|||||||
* Show a currency.
|
* Show a currency.
|
||||||
*
|
*
|
||||||
* @return JsonResponse
|
* @return JsonResponse
|
||||||
|
* @throws FireflyException
|
||||||
|
* @throws JsonException
|
||||||
* @codeCoverageIgnore
|
* @codeCoverageIgnore
|
||||||
*/
|
*/
|
||||||
public function showDefault(): JsonResponse
|
public function showDefault(): JsonResponse
|
||||||
|
|||||||
@@ -33,6 +33,7 @@ use FireflyIII\Support\Http\Api\AccountFilter;
|
|||||||
use FireflyIII\Support\Http\Api\TransactionFilter;
|
use FireflyIII\Support\Http\Api\TransactionFilter;
|
||||||
use FireflyIII\Transformers\CurrencyTransformer;
|
use FireflyIII\Transformers\CurrencyTransformer;
|
||||||
use Illuminate\Http\JsonResponse;
|
use Illuminate\Http\JsonResponse;
|
||||||
|
use JsonException;
|
||||||
use League\Fractal\Resource\Item;
|
use League\Fractal\Resource\Item;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -74,6 +75,7 @@ class StoreController extends Controller
|
|||||||
*
|
*
|
||||||
* @return JsonResponse
|
* @return JsonResponse
|
||||||
* @throws FireflyException
|
* @throws FireflyException
|
||||||
|
* @throws JsonException
|
||||||
*/
|
*/
|
||||||
public function store(StoreRequest $request): JsonResponse
|
public function store(StoreRequest $request): JsonResponse
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -75,6 +75,8 @@ class UpdateController extends Controller
|
|||||||
* @param TransactionCurrency $currency
|
* @param TransactionCurrency $currency
|
||||||
*
|
*
|
||||||
* @return JsonResponse
|
* @return JsonResponse
|
||||||
|
* @throws FireflyException
|
||||||
|
* @throws JsonException
|
||||||
* @codeCoverageIgnore
|
* @codeCoverageIgnore
|
||||||
*/
|
*/
|
||||||
public function disable(TransactionCurrency $currency): JsonResponse
|
public function disable(TransactionCurrency $currency): JsonResponse
|
||||||
@@ -108,6 +110,8 @@ class UpdateController extends Controller
|
|||||||
* @param TransactionCurrency $currency
|
* @param TransactionCurrency $currency
|
||||||
*
|
*
|
||||||
* @return JsonResponse
|
* @return JsonResponse
|
||||||
|
* @throws FireflyException
|
||||||
|
* @throws JsonException
|
||||||
* @codeCoverageIgnore
|
* @codeCoverageIgnore
|
||||||
*/
|
*/
|
||||||
public function enable(TransactionCurrency $currency): JsonResponse
|
public function enable(TransactionCurrency $currency): JsonResponse
|
||||||
|
|||||||
@@ -70,8 +70,8 @@ class AccountController extends Controller
|
|||||||
{
|
{
|
||||||
Log::debug('Now in account search()');
|
Log::debug('Now in account search()');
|
||||||
$manager = $this->getManager();
|
$manager = $this->getManager();
|
||||||
$query = $request->get('query');
|
$query = trim((string) $request->get('query'));
|
||||||
$field = $request->get('field');
|
$field = trim((string) $request->get('field'));
|
||||||
$type = $request->get('type') ?? 'all';
|
$type = $request->get('type') ?? 'all';
|
||||||
if ('' === $query || !in_array($field, $this->validFields, true)) {
|
if ('' === $query || !in_array($field, $this->validFields, true)) {
|
||||||
return response(null, 422);
|
return response(null, 422);
|
||||||
|
|||||||
@@ -113,7 +113,7 @@ class BasicController extends Controller
|
|||||||
// give new keys
|
// give new keys
|
||||||
$return = [];
|
$return = [];
|
||||||
foreach ($total as $entry) {
|
foreach ($total as $entry) {
|
||||||
if (null === $code || (null !== $code && $code === $entry['currency_code'])) {
|
if (null === $code || ($code === $entry['currency_code'])) {
|
||||||
$return[$entry['key']] = $entry;
|
$return[$entry['key']] = $entry;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -150,7 +150,9 @@ class BasicController extends Controller
|
|||||||
foreach ($set as $transactionJournal) {
|
foreach ($set as $transactionJournal) {
|
||||||
$currencyId = (int) $transactionJournal['currency_id'];
|
$currencyId = (int) $transactionJournal['currency_id'];
|
||||||
$incomes[$currencyId] = $incomes[$currencyId] ?? '0';
|
$incomes[$currencyId] = $incomes[$currencyId] ?? '0';
|
||||||
$incomes[$currencyId] = bcadd($incomes[$currencyId], bcmul($transactionJournal['amount'], '-1'));
|
$incomes[$currencyId] = bcadd($incomes[$currencyId],
|
||||||
|
bcmul($transactionJournal['amount'], '-1')
|
||||||
|
);
|
||||||
$sums[$currencyId] = $sums[$currencyId] ?? '0';
|
$sums[$currencyId] = $sums[$currencyId] ?? '0';
|
||||||
$sums[$currencyId] = bcadd($sums[$currencyId], bcmul($transactionJournal['amount'], '-1'));
|
$sums[$currencyId] = bcadd($sums[$currencyId], bcmul($transactionJournal['amount'], '-1'));
|
||||||
}
|
}
|
||||||
@@ -362,7 +364,7 @@ class BasicController extends Controller
|
|||||||
function (Account $account) {
|
function (Account $account) {
|
||||||
$includeNetWorth = $this->accountRepository->getMetaValue($account, 'include_net_worth');
|
$includeNetWorth = $this->accountRepository->getMetaValue($account, 'include_net_worth');
|
||||||
|
|
||||||
return null === $includeNetWorth ? true : '1' === $includeNetWorth;
|
return null === $includeNetWorth || '1' === $includeNetWorth;
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|||||||
@@ -30,6 +30,8 @@ use FireflyIII\Repositories\User\UserRepositoryInterface;
|
|||||||
use FireflyIII\Support\Binder\EitherConfigKey;
|
use FireflyIII\Support\Binder\EitherConfigKey;
|
||||||
use Illuminate\Http\JsonResponse;
|
use Illuminate\Http\JsonResponse;
|
||||||
use Log;
|
use Log;
|
||||||
|
use Psr\Container\ContainerExceptionInterface;
|
||||||
|
use Psr\Container\NotFoundExceptionInterface;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Class ConfigurationController
|
* Class ConfigurationController
|
||||||
@@ -94,6 +96,8 @@ class ConfigurationController extends Controller
|
|||||||
*
|
*
|
||||||
* @return array
|
* @return array
|
||||||
* @throws FireflyException
|
* @throws FireflyException
|
||||||
|
* @throws ContainerExceptionInterface
|
||||||
|
* @throws NotFoundExceptionInterface
|
||||||
*/
|
*/
|
||||||
private function getDynamicConfiguration(): array
|
private function getDynamicConfiguration(): array
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -81,7 +81,7 @@ class UserController extends Controller
|
|||||||
return response()->json([], 500);
|
return response()->json([], 500);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($admin->id !== $user->id && $this->repository->hasRole($admin, 'owner')) {
|
if ($this->repository->hasRole($admin, 'owner')) {
|
||||||
$this->repository->destroy($user);
|
$this->repository->destroy($user);
|
||||||
|
|
||||||
return response()->json([], 204);
|
return response()->json([], 204);
|
||||||
|
|||||||
@@ -54,7 +54,7 @@ class AutocompleteRequest extends FormRequest
|
|||||||
return [
|
return [
|
||||||
'types' => $array,
|
'types' => $array,
|
||||||
'query' => $this->string('query'),
|
'query' => $this->string('query'),
|
||||||
'date' => $this->date('date'),
|
'date' => $this->getCarbonDate('date'),
|
||||||
'limit' => $limit,
|
'limit' => $limit,
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -74,10 +74,24 @@ class MoveTransactionsRequest extends FormRequest
|
|||||||
// validate start before end only if both are there.
|
// validate start before end only if both are there.
|
||||||
$data = $validator->getData();
|
$data = $validator->getData();
|
||||||
if (array_key_exists('original_account', $data) && array_key_exists('destination_account', $data)) {
|
if (array_key_exists('original_account', $data) && array_key_exists('destination_account', $data)) {
|
||||||
|
$this->validateMove($validator);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param Validator $validator
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
private function validateMove(Validator $validator): void {
|
||||||
|
$data = $validator->getData();
|
||||||
$repository = app(AccountRepositoryInterface::class);
|
$repository = app(AccountRepositoryInterface::class);
|
||||||
$repository->setUser(auth()->user());
|
$repository->setUser(auth()->user());
|
||||||
$original = $repository->find((int) $data['original_account']);
|
$original = $repository->find((int) $data['original_account']);
|
||||||
$destination = $repository->find((int) $data['destination_account']);
|
$destination = $repository->find((int) $data['destination_account']);
|
||||||
|
|
||||||
|
// not the same type:
|
||||||
if ($original->accountType->type !== $destination->accountType->type) {
|
if ($original->accountType->type !== $destination->accountType->type) {
|
||||||
$validator->errors()->add('title', (string) trans('validation.same_account_type'));
|
$validator->errors()->add('title', (string) trans('validation.same_account_type'));
|
||||||
|
|
||||||
@@ -86,6 +100,8 @@ class MoveTransactionsRequest extends FormRequest
|
|||||||
// get currency pref:
|
// get currency pref:
|
||||||
$originalCurrency = $repository->getAccountCurrency($original);
|
$originalCurrency = $repository->getAccountCurrency($original);
|
||||||
$destinationCurrency = $repository->getAccountCurrency($destination);
|
$destinationCurrency = $repository->getAccountCurrency($destination);
|
||||||
|
|
||||||
|
// check different scenario's.
|
||||||
if (null === $originalCurrency xor null === $destinationCurrency) {
|
if (null === $originalCurrency xor null === $destinationCurrency) {
|
||||||
$validator->errors()->add('title', (string) trans('validation.same_account_currency'));
|
$validator->errors()->add('title', (string) trans('validation.same_account_currency'));
|
||||||
|
|
||||||
@@ -100,6 +116,3 @@ class MoveTransactionsRequest extends FormRequest
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -45,8 +45,8 @@ class DateRequest extends FormRequest
|
|||||||
public function getAll(): array
|
public function getAll(): array
|
||||||
{
|
{
|
||||||
return [
|
return [
|
||||||
'start' => $this->date('start'),
|
'start' => $this->getCarbonDate('start'),
|
||||||
'end' => $this->date('end'),
|
'end' => $this->getCarbonDate('end'),
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -41,8 +41,8 @@ class ExportRequest extends FormRequest
|
|||||||
public function getAll(): array
|
public function getAll(): array
|
||||||
{
|
{
|
||||||
$result = [
|
$result = [
|
||||||
'start' => $this->date('start') ?? Carbon::now()->subYear(),
|
'start' => $this->getCarbonDate('start') ?? Carbon::now()->subYear(),
|
||||||
'end' => $this->date('end') ?? Carbon::now(),
|
'end' => $this->getCarbonDate('end') ?? Carbon::now(),
|
||||||
'type' => $this->string('type'),
|
'type' => $this->string('type'),
|
||||||
];
|
];
|
||||||
$parts = explode(',', $this->string('accounts'));
|
$parts = explode(',', $this->string('accounts'));
|
||||||
|
|||||||
@@ -58,8 +58,8 @@ class GenericRequest extends FormRequest
|
|||||||
public function getAll(): array
|
public function getAll(): array
|
||||||
{
|
{
|
||||||
return [
|
return [
|
||||||
'start' => $this->date('start'),
|
'start' => $this->getCarbonDate('start'),
|
||||||
'end' => $this->date('end'),
|
'end' => $this->getCarbonDate('end'),
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -128,7 +128,7 @@ class GenericRequest extends FormRequest
|
|||||||
foreach ($array as $billId) {
|
foreach ($array as $billId) {
|
||||||
$billId = (int) $billId;
|
$billId = (int) $billId;
|
||||||
$bill = $repository->find($billId);
|
$bill = $repository->find($billId);
|
||||||
if (null !== $billId) {
|
if (null !== $bill) {
|
||||||
$this->bills->push($bill);
|
$this->bills->push($bill);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -160,7 +160,7 @@ class GenericRequest extends FormRequest
|
|||||||
foreach ($array as $budgetId) {
|
foreach ($array as $budgetId) {
|
||||||
$budgetId = (int) $budgetId;
|
$budgetId = (int) $budgetId;
|
||||||
$budget = $repository->find($budgetId);
|
$budget = $repository->find($budgetId);
|
||||||
if (null !== $budgetId) {
|
if (null !== $budget) {
|
||||||
$this->budgets->push($budget);
|
$this->budgets->push($budget);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -192,7 +192,7 @@ class GenericRequest extends FormRequest
|
|||||||
foreach ($array as $categoryId) {
|
foreach ($array as $categoryId) {
|
||||||
$categoryId = (int) $categoryId;
|
$categoryId = (int) $categoryId;
|
||||||
$category = $repository->find($categoryId);
|
$category = $repository->find($categoryId);
|
||||||
if (null !== $categoryId) {
|
if (null !== $category) {
|
||||||
$this->categories->push($category);
|
$this->categories->push($category);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -204,7 +204,7 @@ class GenericRequest extends FormRequest
|
|||||||
*/
|
*/
|
||||||
public function getEnd(): Carbon
|
public function getEnd(): Carbon
|
||||||
{
|
{
|
||||||
$date = $this->date('end');
|
$date = $this->getCarbonDate('end');
|
||||||
$date->endOfDay();
|
$date->endOfDay();
|
||||||
|
|
||||||
return $date;
|
return $date;
|
||||||
@@ -251,7 +251,7 @@ class GenericRequest extends FormRequest
|
|||||||
*/
|
*/
|
||||||
public function getStart(): Carbon
|
public function getStart(): Carbon
|
||||||
{
|
{
|
||||||
$date = $this->date('start');
|
$date = $this->getCarbonDate('start');
|
||||||
$date->startOfDay();
|
$date->startOfDay();
|
||||||
|
|
||||||
return $date;
|
return $date;
|
||||||
@@ -282,7 +282,7 @@ class GenericRequest extends FormRequest
|
|||||||
foreach ($array as $tagId) {
|
foreach ($array as $tagId) {
|
||||||
$tagId = (int) $tagId;
|
$tagId = (int) $tagId;
|
||||||
$tag = $repository->find($tagId);
|
$tag = $repository->find($tagId);
|
||||||
if (null !== $tagId) {
|
if (null !== $tag) {
|
||||||
$this->tags->push($tag);
|
$this->tags->push($tag);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -70,7 +70,7 @@ class StoreRequest extends FormRequest
|
|||||||
'account_number' => $this->string('account_number'),
|
'account_number' => $this->string('account_number'),
|
||||||
'account_role' => $this->string('account_role'),
|
'account_role' => $this->string('account_role'),
|
||||||
'opening_balance' => $this->string('opening_balance'),
|
'opening_balance' => $this->string('opening_balance'),
|
||||||
'opening_balance_date' => $this->date('opening_balance_date'),
|
'opening_balance_date' => $this->getCarbonDate('opening_balance_date'),
|
||||||
'cc_type' => $this->string('credit_card_type'),
|
'cc_type' => $this->string('credit_card_type'),
|
||||||
'cc_monthly_payment_date' => $this->string('monthly_payment_date'),
|
'cc_monthly_payment_date' => $this->string('monthly_payment_date'),
|
||||||
'notes' => $this->stringWithNewlines('notes'),
|
'notes' => $this->stringWithNewlines('notes'),
|
||||||
@@ -82,7 +82,7 @@ class StoreRequest extends FormRequest
|
|||||||
|
|
||||||
if ('liability' === $data['account_type_name'] || 'liabilities' === $data['account_type_name']) {
|
if ('liability' === $data['account_type_name'] || 'liabilities' === $data['account_type_name']) {
|
||||||
$data['opening_balance'] = app('steam')->negative($this->string('liability_amount'));
|
$data['opening_balance'] = app('steam')->negative($this->string('liability_amount'));
|
||||||
$data['opening_balance_date'] = $this->date('liability_start_date');
|
$data['opening_balance_date'] = $this->getCarbonDate('liability_start_date');
|
||||||
$data['account_type_name'] = $this->string('liability_type');
|
$data['account_type_name'] = $this->string('liability_type');
|
||||||
$data['liability_direction'] = $this->string('liability_direction');
|
$data['liability_direction'] = $this->string('liability_direction');
|
||||||
$data['account_type_id'] = null;
|
$data['account_type_id'] = null;
|
||||||
@@ -116,15 +116,15 @@ class StoreRequest extends FormRequest
|
|||||||
'currency_code' => 'min:3|max:3|exists:transaction_currencies,code',
|
'currency_code' => 'min:3|max:3|exists:transaction_currencies,code',
|
||||||
'active' => [new IsBoolean],
|
'active' => [new IsBoolean],
|
||||||
'include_net_worth' => [new IsBoolean],
|
'include_net_worth' => [new IsBoolean],
|
||||||
'account_role' => sprintf('in:%s|required_if:type,asset', $accountRoles),
|
'account_role' => sprintf('nullable|in:%s|required_if:type,asset', $accountRoles),
|
||||||
'credit_card_type' => sprintf('in:%s|required_if:account_role,ccAsset', $ccPaymentTypes),
|
'credit_card_type' => sprintf('nullable|in:%s|required_if:account_role,ccAsset', $ccPaymentTypes),
|
||||||
'monthly_payment_date' => 'date' . '|required_if:account_role,ccAsset|required_if:credit_card_type,monthlyFull',
|
'monthly_payment_date' => 'nullable|date|required_if:account_role,ccAsset|required_if:credit_card_type,monthlyFull',
|
||||||
'liability_type' => 'required_if:type,liability|required_if:type,liabilities|in:loan,debt,mortgage',
|
'liability_type' => 'nullable|required_if:type,liability|required_if:type,liabilities|in:loan,debt,mortgage',
|
||||||
'liability_amount' => 'required_with:liability_start_date|min:0|numeric',
|
'liability_amount' => 'required_with:liability_start_date|min:0|numeric',
|
||||||
'liability_start_date' => 'required_with:liability_amount|date',
|
'liability_start_date' => 'required_with:liability_amount|date',
|
||||||
'liability_direction' => 'required_if:type,liability|required_if:type,liabilities|in:credit,debit',
|
'liability_direction' => 'nullable|required_if:type,liability|required_if:type,liabilities|in:credit,debit',
|
||||||
'interest' => 'between:0,100|numeric',
|
'interest' => 'between:0,100|numeric',
|
||||||
'interest_period' => sprintf('in:%s', join(',', config('firefly.interest_periods'))),
|
'interest_period' => sprintf('nullable|in:%s', join(',', config('firefly.interest_periods'))),
|
||||||
'notes' => 'min:0|max:65536',
|
'notes' => 'min:0|max:65536',
|
||||||
];
|
];
|
||||||
|
|
||||||
|
|||||||
@@ -50,6 +50,7 @@ class StoreRequest extends FormRequest
|
|||||||
'name' => ['name', 'string'],
|
'name' => ['name', 'string'],
|
||||||
'active' => ['active', 'boolean'],
|
'active' => ['active', 'boolean'],
|
||||||
'order' => ['active', 'integer'],
|
'order' => ['active', 'integer'],
|
||||||
|
'notes' => ['notes', 'string'],
|
||||||
|
|
||||||
// auto budget currency:
|
// auto budget currency:
|
||||||
'currency_id' => ['auto_budget_currency_id', 'integer'],
|
'currency_id' => ['auto_budget_currency_id', 'integer'],
|
||||||
@@ -74,6 +75,7 @@ class StoreRequest extends FormRequest
|
|||||||
'active' => [new IsBoolean],
|
'active' => [new IsBoolean],
|
||||||
'currency_id' => 'exists:transaction_currencies,id',
|
'currency_id' => 'exists:transaction_currencies,id',
|
||||||
'currency_code' => 'exists:transaction_currencies,code',
|
'currency_code' => 'exists:transaction_currencies,code',
|
||||||
|
'notes' => 'nullable|between:1,65536',
|
||||||
// auto budget info
|
// auto budget info
|
||||||
'auto_budget_type' => 'in:reset,rollover,none',
|
'auto_budget_type' => 'in:reset,rollover,none',
|
||||||
'auto_budget_amount' => 'numeric|min:0|max:1000000000|required_if:auto_budget_type,reset|required_if:auto_budget_type,rollover',
|
'auto_budget_amount' => 'numeric|min:0|max:1000000000|required_if:auto_budget_type,reset|required_if:auto_budget_type,rollover',
|
||||||
|
|||||||
@@ -51,6 +51,7 @@ class UpdateRequest extends FormRequest
|
|||||||
'name' => ['name', 'string'],
|
'name' => ['name', 'string'],
|
||||||
'active' => ['active', 'boolean'],
|
'active' => ['active', 'boolean'],
|
||||||
'order' => ['order', 'integer'],
|
'order' => ['order', 'integer'],
|
||||||
|
'notes' => ['notes', 'string'],
|
||||||
'currency_id' => ['auto_budget_currency_id', 'integer'],
|
'currency_id' => ['auto_budget_currency_id', 'integer'],
|
||||||
'currency_code' => ['auto_budget_currency_code', 'string'],
|
'currency_code' => ['auto_budget_currency_code', 'string'],
|
||||||
'auto_budget_type' => ['auto_budget_type', 'string'],
|
'auto_budget_type' => ['auto_budget_type', 'string'],
|
||||||
@@ -82,6 +83,7 @@ class UpdateRequest extends FormRequest
|
|||||||
return [
|
return [
|
||||||
'name' => sprintf('between:1,100|uniqueObjectForUser:budgets,name,%d', $budget->id),
|
'name' => sprintf('between:1,100|uniqueObjectForUser:budgets,name,%d', $budget->id),
|
||||||
'active' => [new IsBoolean],
|
'active' => [new IsBoolean],
|
||||||
|
'notes' => 'nullable|between:1,65536',
|
||||||
'auto_budget_type' => 'in:reset,rollover,none',
|
'auto_budget_type' => 'in:reset,rollover,none',
|
||||||
'auto_budget_currency_id' => 'exists:transaction_currencies,id',
|
'auto_budget_currency_id' => 'exists:transaction_currencies,id',
|
||||||
'auto_budget_currency_code' => 'exists:transaction_currencies,code',
|
'auto_budget_currency_code' => 'exists:transaction_currencies,code',
|
||||||
|
|||||||
@@ -44,8 +44,8 @@ class StoreRequest extends FormRequest
|
|||||||
public function getAll(): array
|
public function getAll(): array
|
||||||
{
|
{
|
||||||
return [
|
return [
|
||||||
'start' => $this->date('start'),
|
'start' => $this->getCarbonDate('start'),
|
||||||
'end' => $this->date('end'),
|
'end' => $this->getCarbonDate('end'),
|
||||||
'amount' => $this->string('amount'),
|
'amount' => $this->string('amount'),
|
||||||
'currency_id' => $this->integer('currency_id'),
|
'currency_id' => $this->integer('currency_id'),
|
||||||
'currency_code' => $this->string('currency_code'),
|
'currency_code' => $this->string('currency_code'),
|
||||||
|
|||||||
@@ -51,8 +51,8 @@ class StoreRequest extends FormRequest
|
|||||||
$data['account_id'] = $this->integer('account_id');
|
$data['account_id'] = $this->integer('account_id');
|
||||||
$data['targetamount'] = $this->string('target_amount');
|
$data['targetamount'] = $this->string('target_amount');
|
||||||
$data['current_amount'] = $this->string('current_amount');
|
$data['current_amount'] = $this->string('current_amount');
|
||||||
$data['startdate'] = $this->date('start_date');
|
$data['startdate'] = $this->getCarbonDate('start_date');
|
||||||
$data['targetdate'] = $this->date('target_date');
|
$data['targetdate'] = $this->getCarbonDate('target_date');
|
||||||
$data['notes'] = $this->stringWithNewlines('notes');
|
$data['notes'] = $this->stringWithNewlines('notes');
|
||||||
$data['object_group_id'] = $this->integer('object_group_id');
|
$data['object_group_id'] = $this->integer('object_group_id');
|
||||||
$data['object_group_title'] = $this->string('object_group_title');
|
$data['object_group_title'] = $this->string('object_group_title');
|
||||||
|
|||||||
@@ -141,32 +141,34 @@ class StoreRequest extends FormRequest
|
|||||||
'first_date' => 'required|date',
|
'first_date' => 'required|date',
|
||||||
'apply_rules' => [new IsBoolean],
|
'apply_rules' => [new IsBoolean],
|
||||||
'active' => [new IsBoolean],
|
'active' => [new IsBoolean],
|
||||||
'repeat_until' => 'date',
|
'repeat_until' => 'nullable|date',
|
||||||
'nr_of_repetitions' => 'numeric|between:1,31',
|
'nr_of_repetitions' => 'nullable|numeric|between:1,31',
|
||||||
|
|
||||||
'repetitions.*.type' => 'required|in:daily,weekly,ndom,monthly,yearly',
|
'repetitions.*.type' => 'required|in:daily,weekly,ndom,monthly,yearly',
|
||||||
'repetitions.*.moment' => 'between:0,10',
|
'repetitions.*.moment' => 'between:0,10',
|
||||||
'repetitions.*.skip' => 'numeric|between:0,31',
|
'repetitions.*.skip' => 'nullable|numeric|between:0,31',
|
||||||
'repetitions.*.weekend' => 'numeric|min:1|max:4',
|
'repetitions.*.weekend' => 'numeric|min:1|max:4',
|
||||||
|
|
||||||
'transactions.*.description' => 'required|between:1,255',
|
'transactions.*.description' => 'required|between:1,255',
|
||||||
'transactions.*.amount' => 'required|numeric|gt:0',
|
'transactions.*.amount' => 'required|numeric|gt:0',
|
||||||
'transactions.*.foreign_amount' => 'numeric|gt:0',
|
'transactions.*.foreign_amount' => 'nullable|numeric|gt:0',
|
||||||
'transactions.*.currency_id' => 'numeric|exists:transaction_currencies,id',
|
'transactions.*.currency_id' => 'nullable|numeric|exists:transaction_currencies,id',
|
||||||
'transactions.*.currency_code' => 'min:3|max:3|exists:transaction_currencies,code',
|
'transactions.*.currency_code' => 'nullable|min:3|max:3|exists:transaction_currencies,code',
|
||||||
'transactions.*.foreign_currency_id' => 'numeric|exists:transaction_currencies,id',
|
'transactions.*.foreign_currency_id' => 'nullable|numeric|exists:transaction_currencies,id',
|
||||||
'transactions.*.foreign_currency_code' => 'min:3|max:3|exists:transaction_currencies,code',
|
'transactions.*.foreign_currency_code' => 'nullable|min:3|max:3|exists:transaction_currencies,code',
|
||||||
'transactions.*.source_id' => ['numeric', 'nullable', new BelongsUser],
|
'transactions.*.source_id' => ['numeric', 'nullable', new BelongsUser],
|
||||||
'transactions.*.source_name' => 'between:1,255|nullable',
|
'transactions.*.source_name' => 'between:1,255|nullable',
|
||||||
'transactions.*.destination_id' => ['numeric', 'nullable', new BelongsUser],
|
'transactions.*.destination_id' => ['numeric', 'nullable', new BelongsUser],
|
||||||
'transactions.*.destination_name' => 'between:1,255|nullable',
|
'transactions.*.destination_name' => 'between:1,255|nullable',
|
||||||
|
|
||||||
// new and updated fields:
|
// new and updated fields:
|
||||||
'transactions.*.budget_id' => ['mustExist:budgets,id', new BelongsUser],
|
'transactions.*.budget_id' => ['nullable', 'mustExist:budgets,id', new BelongsUser],
|
||||||
'transactions.*.budget_name' => ['between:1,255', 'nullable', new BelongsUser],
|
'transactions.*.budget_name' => ['between:1,255', 'nullable', new BelongsUser],
|
||||||
'transactions.*.category_id' => ['mustExist:categories,id', new BelongsUser],
|
'transactions.*.category_id' => ['nullable', 'mustExist:categories,id', new BelongsUser],
|
||||||
'transactions.*.category_name' => 'between:1,255|nullable',
|
'transactions.*.category_name' => 'between:1,255|nullable',
|
||||||
'transactions.*.piggy_bank_id' => ['numeric', 'mustExist:piggy_banks,id', new BelongsUser],
|
'transactions.*.piggy_bank_id' => ['nullable', 'numeric', 'mustExist:piggy_banks,id', new BelongsUser],
|
||||||
'transactions.*.piggy_bank_name' => ['between:1,255', 'nullable', new BelongsUser],
|
'transactions.*.piggy_bank_name' => ['between:1,255', 'nullable', new BelongsUser],
|
||||||
'transactions.*.tags' => 'between:1,64000',
|
'transactions.*.tags' => 'nullable|between:1,64000',
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -155,33 +155,34 @@ class UpdateRequest extends FormRequest
|
|||||||
'first_date' => 'date',
|
'first_date' => 'date',
|
||||||
'apply_rules' => [new IsBoolean],
|
'apply_rules' => [new IsBoolean],
|
||||||
'active' => [new IsBoolean],
|
'active' => [new IsBoolean],
|
||||||
'repeat_until' => 'date',
|
'repeat_until' => 'nullable|date',
|
||||||
'nr_of_repetitions' => 'numeric|between:1,31',
|
'nr_of_repetitions' => 'nullable|numeric|between:1,31',
|
||||||
|
|
||||||
'repetitions.*.type' => 'in:daily,weekly,ndom,monthly,yearly',
|
'repetitions.*.type' => 'in:daily,weekly,ndom,monthly,yearly',
|
||||||
'repetitions.*.moment' => 'between:0,10',
|
'repetitions.*.moment' => 'between:0,10',
|
||||||
'repetitions.*.skip' => 'numeric|between:0,31',
|
'repetitions.*.skip' => 'nullable|numeric|between:0,31',
|
||||||
'repetitions.*.weekend' => 'numeric|min:1|max:4',
|
'repetitions.*.weekend' => 'nullable|numeric|min:1|max:4',
|
||||||
|
|
||||||
'transactions.*.description' => 'between:1,255',
|
'transactions.*.description' => 'between:1,255',
|
||||||
'transactions.*.amount' => 'numeric|gt:0',
|
'transactions.*.amount' => 'numeric|gt:0',
|
||||||
'transactions.*.foreign_amount' => 'numeric|gt:0',
|
'transactions.*.foreign_amount' => 'nullable|numeric|gt:0',
|
||||||
'transactions.*.currency_id' => 'numeric|exists:transaction_currencies,id',
|
'transactions.*.currency_id' => 'nullable|numeric|exists:transaction_currencies,id',
|
||||||
'transactions.*.currency_code' => 'min:3|max:3|exists:transaction_currencies,code',
|
'transactions.*.currency_code' => 'nullable|min:3|max:3|exists:transaction_currencies,code',
|
||||||
'transactions.*.foreign_currency_id' => 'numeric|exists:transaction_currencies,id',
|
'transactions.*.foreign_currency_id' => 'nullable|numeric|exists:transaction_currencies,id',
|
||||||
'transactions.*.foreign_currency_code' => 'min:3|max:3|exists:transaction_currencies,code',
|
'transactions.*.foreign_currency_code' => 'nullable|min:3|max:3|exists:transaction_currencies,code',
|
||||||
'transactions.*.source_id' => ['numeric', 'nullable', new BelongsUser],
|
'transactions.*.source_id' => ['numeric', 'nullable', new BelongsUser],
|
||||||
'transactions.*.source_name' => 'between:1,255|nullable',
|
'transactions.*.source_name' => 'between:1,255|nullable',
|
||||||
'transactions.*.destination_id' => ['numeric', 'nullable', new BelongsUser],
|
'transactions.*.destination_id' => ['numeric', 'nullable', new BelongsUser],
|
||||||
'transactions.*.destination_name' => 'between:1,255|nullable',
|
'transactions.*.destination_name' => 'between:1,255|nullable',
|
||||||
|
|
||||||
// new and updated fields:
|
// new and updated fields:
|
||||||
'transactions.*.budget_id' => ['mustExist:budgets,id', new BelongsUser],
|
'transactions.*.budget_id' => ['nullable', 'mustExist:budgets,id', new BelongsUser],
|
||||||
'transactions.*.budget_name' => ['between:1,255', 'nullable', new BelongsUser],
|
'transactions.*.budget_name' => ['between:1,255', 'nullable', new BelongsUser],
|
||||||
'transactions.*.category_id' => ['mustExist:categories,id', new BelongsUser],
|
'transactions.*.category_id' => ['nullable', 'mustExist:categories,id', new BelongsUser],
|
||||||
'transactions.*.category_name' => 'between:1,255|nullable',
|
'transactions.*.category_name' => 'between:1,255|nullable',
|
||||||
'transactions.*.piggy_bank_id' => ['numeric', 'mustExist:piggy_banks,id', new BelongsUser],
|
'transactions.*.piggy_bank_id' => ['nullable', 'numeric', 'mustExist:piggy_banks,id', new BelongsUser],
|
||||||
'transactions.*.piggy_bank_name' => ['between:1,255', 'nullable', new BelongsUser],
|
'transactions.*.piggy_bank_name' => ['between:1,255', 'nullable', new BelongsUser],
|
||||||
'transactions.*.tags' => 'between:1,64000',
|
'transactions.*.tags' => 'nullable|between:1,64000',
|
||||||
|
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -153,12 +153,14 @@ class StoreRequest extends FormRequest
|
|||||||
function (Validator $validator) {
|
function (Validator $validator) {
|
||||||
$this->atLeastOneTrigger($validator);
|
$this->atLeastOneTrigger($validator);
|
||||||
$this->atLeastOneAction($validator);
|
$this->atLeastOneAction($validator);
|
||||||
|
$this->atLeastOneActiveTrigger($validator);
|
||||||
|
$this->atLeastOneActiveAction($validator);
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Adds an error to the validator when there are no repetitions in the array of data.
|
* Adds an error to the validator when there are no triggers in the array of data.
|
||||||
*
|
*
|
||||||
* @param Validator $validator
|
* @param Validator $validator
|
||||||
*/
|
*/
|
||||||
@@ -186,4 +188,62 @@ class StoreRequest extends FormRequest
|
|||||||
$validator->errors()->add('title', (string) trans('validation.at_least_one_action'));
|
$validator->errors()->add('title', (string) trans('validation.at_least_one_action'));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds an error to the validator when there are no ACTIVE triggers in the array of data.
|
||||||
|
*
|
||||||
|
* @param Validator $validator
|
||||||
|
*/
|
||||||
|
protected function atLeastOneActiveTrigger(Validator $validator): void
|
||||||
|
{
|
||||||
|
$data = $validator->getData();
|
||||||
|
$triggers = $data['triggers'] ?? [];
|
||||||
|
// need at least one trigger
|
||||||
|
if (!is_countable($triggers) || empty($triggers)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
$allInactive = true;
|
||||||
|
$inactiveIndex = 0;
|
||||||
|
foreach ($triggers as $index => $trigger) {
|
||||||
|
$active = array_key_exists('active', $trigger) ? $trigger['active'] : true; // assume true
|
||||||
|
if (true === $active) {
|
||||||
|
$allInactive = false;
|
||||||
|
}
|
||||||
|
if (false === $active) {
|
||||||
|
$inactiveIndex = $index;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (true === $allInactive) {
|
||||||
|
$validator->errors()->add(sprintf('triggers.%d.active', $inactiveIndex), (string) trans('validation.at_least_one_active_trigger'));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds an error to the validator when there are no ACTIVE actions in the array of data.
|
||||||
|
*
|
||||||
|
* @param Validator $validator
|
||||||
|
*/
|
||||||
|
protected function atLeastOneActiveAction(Validator $validator): void
|
||||||
|
{
|
||||||
|
$data = $validator->getData();
|
||||||
|
$actions = $data['actions'] ?? [];
|
||||||
|
// need at least one trigger
|
||||||
|
if (!is_countable($actions) || empty($actions)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
$allInactive = true;
|
||||||
|
$inactiveIndex = 0;
|
||||||
|
foreach ($actions as $index => $action) {
|
||||||
|
$active = array_key_exists('active', $action) ? $action['active'] : true; // assume true
|
||||||
|
if (true === $active) {
|
||||||
|
$allInactive = false;
|
||||||
|
}
|
||||||
|
if (false === $active) {
|
||||||
|
$inactiveIndex = $index;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (true === $allInactive) {
|
||||||
|
$validator->errors()->add(sprintf('actions.%d.active', $inactiveIndex), (string) trans('validation.at_least_one_active_action'));
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -55,7 +55,7 @@ class TriggerRequest extends FormRequest
|
|||||||
*/
|
*/
|
||||||
private function getDate(string $field): ?Carbon
|
private function getDate(string $field): ?Carbon
|
||||||
{
|
{
|
||||||
return null === $this->query($field) ? null : Carbon::createFromFormat('Y-m-d', $this->query($field));
|
return null === $this->query($field) ? null : Carbon::createFromFormat('Y-m-d', substr($this->query($field), 0, 10));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -63,7 +63,7 @@ class TriggerRequest extends FormRequest
|
|||||||
*/
|
*/
|
||||||
private function getAccounts(): array
|
private function getAccounts(): array
|
||||||
{
|
{
|
||||||
return $this->get('accounts');
|
return $this->get('accounts') ?? [];
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -53,6 +53,7 @@ class UpdateRequest extends FormRequest
|
|||||||
'strict' => ['strict', 'boolean'],
|
'strict' => ['strict', 'boolean'],
|
||||||
'stop_processing' => ['stop_processing', 'boolean'],
|
'stop_processing' => ['stop_processing', 'boolean'],
|
||||||
'active' => ['active', 'boolean'],
|
'active' => ['active', 'boolean'],
|
||||||
|
'order' => ['order', 'integer'],
|
||||||
];
|
];
|
||||||
|
|
||||||
$return = $this->getAllData($fields);
|
$return = $this->getAllData($fields);
|
||||||
@@ -150,6 +151,7 @@ class UpdateRequest extends FormRequest
|
|||||||
'strict' => [new IsBoolean],
|
'strict' => [new IsBoolean],
|
||||||
'stop_processing' => [new IsBoolean],
|
'stop_processing' => [new IsBoolean],
|
||||||
'active' => [new IsBoolean],
|
'active' => [new IsBoolean],
|
||||||
|
'order' => 'numeric|between:1,1337',
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -165,7 +167,9 @@ class UpdateRequest extends FormRequest
|
|||||||
$validator->after(
|
$validator->after(
|
||||||
function (Validator $validator) {
|
function (Validator $validator) {
|
||||||
$this->atLeastOneTrigger($validator);
|
$this->atLeastOneTrigger($validator);
|
||||||
|
$this->atLeastOneValidTrigger($validator);
|
||||||
$this->atLeastOneAction($validator);
|
$this->atLeastOneAction($validator);
|
||||||
|
$this->atLeastOneValidAction($validator);
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -185,6 +189,35 @@ class UpdateRequest extends FormRequest
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds an error to the validator when there are no repetitions in the array of data.
|
||||||
|
*
|
||||||
|
* @param Validator $validator
|
||||||
|
*/
|
||||||
|
protected function atLeastOneValidTrigger(Validator $validator): void
|
||||||
|
{
|
||||||
|
$data = $validator->getData();
|
||||||
|
$triggers = $data['triggers'] ?? [];
|
||||||
|
$allInactive = true;
|
||||||
|
$inactiveIndex = 0;
|
||||||
|
// need at least one trigger
|
||||||
|
if (is_array($triggers) && empty($triggers)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
foreach ($triggers as $index => $trigger) {
|
||||||
|
$active = array_key_exists('active', $trigger) ? $trigger['active'] : true; // assume true
|
||||||
|
if (true === $active) {
|
||||||
|
$allInactive = false;
|
||||||
|
}
|
||||||
|
if (false === $active) {
|
||||||
|
$inactiveIndex = $index;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (true === $allInactive) {
|
||||||
|
$validator->errors()->add(sprintf('triggers.%d.active', $inactiveIndex), (string) trans('validation.at_least_one_active_trigger'));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Adds an error to the validator when there are no repetitions in the array of data.
|
* Adds an error to the validator when there are no repetitions in the array of data.
|
||||||
*
|
*
|
||||||
@@ -199,4 +232,34 @@ class UpdateRequest extends FormRequest
|
|||||||
$validator->errors()->add('title', (string) trans('validation.at_least_one_action'));
|
$validator->errors()->add('title', (string) trans('validation.at_least_one_action'));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds an error to the validator when there are no repetitions in the array of data.
|
||||||
|
*
|
||||||
|
* @param Validator $validator
|
||||||
|
*/
|
||||||
|
protected function atLeastOneValidAction(Validator $validator): void
|
||||||
|
{
|
||||||
|
$data = $validator->getData();
|
||||||
|
$actions = $data['actions'] ?? [];
|
||||||
|
$allInactive = true;
|
||||||
|
$inactiveIndex = 0;
|
||||||
|
// need at least one action
|
||||||
|
if (is_array($actions) && empty($actions)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach ($actions as $index => $action) {
|
||||||
|
$active = array_key_exists('active', $action) ? $action['active'] : true; // assume true
|
||||||
|
if (true === $active) {
|
||||||
|
$allInactive = false;
|
||||||
|
}
|
||||||
|
if (false === $active) {
|
||||||
|
$inactiveIndex = $index;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (true === $allInactive) {
|
||||||
|
$validator->errors()->add(sprintf('actions.%d.active', $inactiveIndex), (string) trans('validation.at_least_one_active_action'));
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -47,7 +47,7 @@ class StoreRequest extends FormRequest
|
|||||||
{
|
{
|
||||||
$data = [
|
$data = [
|
||||||
'tag' => $this->string('tag'),
|
'tag' => $this->string('tag'),
|
||||||
'date' => $this->date('date'),
|
'date' => $this->getCarbonDate('date'),
|
||||||
'description' => $this->string('description'),
|
'description' => $this->string('description'),
|
||||||
'has_location' => true,
|
'has_location' => true,
|
||||||
];
|
];
|
||||||
|
|||||||
@@ -98,17 +98,17 @@ class StoreRequest extends FormRequest
|
|||||||
|
|
||||||
// source of transaction. If everything is null, assume cash account.
|
// source of transaction. If everything is null, assume cash account.
|
||||||
'source_id' => $this->integerFromValue((string) $object['source_id']),
|
'source_id' => $this->integerFromValue((string) $object['source_id']),
|
||||||
'source_name' => $this->clearString($object['source_name'], false),
|
'source_name' => $this->clearString((string) $object['source_name'], false),
|
||||||
'source_iban' => $this->clearString($object['source_iban'], false),
|
'source_iban' => $this->clearString((string) $object['source_iban'], false),
|
||||||
'source_number' => $this->clearString($object['source_number'], false),
|
'source_number' => $this->clearString((string) $object['source_number'], false),
|
||||||
'source_bic' => $this->clearString($object['source_bic'], false),
|
'source_bic' => $this->clearString((string) $object['source_bic'], false),
|
||||||
|
|
||||||
// destination of transaction. If everything is null, assume cash account.
|
// destination of transaction. If everything is null, assume cash account.
|
||||||
'destination_id' => $this->integerFromValue((string) $object['destination_id']),
|
'destination_id' => $this->integerFromValue((string) $object['destination_id']),
|
||||||
'destination_name' => $this->clearString($object['destination_name'], false),
|
'destination_name' => $this->clearString((string) $object['destination_name'], false),
|
||||||
'destination_iban' => $this->clearString($object['destination_iban'], false),
|
'destination_iban' => $this->clearString((string) $object['destination_iban'], false),
|
||||||
'destination_number' => $this->clearString($object['destination_number'], false),
|
'destination_number' => $this->clearString((string) $object['destination_number'], false),
|
||||||
'destination_bic' => $this->clearString($object['destination_bic'], false),
|
'destination_bic' => $this->clearString((string) $object['destination_bic'], false),
|
||||||
|
|
||||||
// budget info
|
// budget info
|
||||||
'budget_id' => $this->integerFromValue((string) $object['budget_id']),
|
'budget_id' => $this->integerFromValue((string) $object['budget_id']),
|
||||||
@@ -137,7 +137,7 @@ class StoreRequest extends FormRequest
|
|||||||
'original_source' => sprintf('ff3-v%s|api-v%s', config('firefly.version'), config('firefly.api_version')),
|
'original_source' => sprintf('ff3-v%s|api-v%s', config('firefly.version'), config('firefly.api_version')),
|
||||||
'recurrence_id' => $this->integerFromValue($object['recurrence_id']),
|
'recurrence_id' => $this->integerFromValue($object['recurrence_id']),
|
||||||
'bunq_payment_id' => $this->clearString((string) $object['bunq_payment_id'], false),
|
'bunq_payment_id' => $this->clearString((string) $object['bunq_payment_id'], false),
|
||||||
'external_uri' => $this->clearString((string)$object['external_uri'], false),
|
'external_url' => $this->clearString((string) $object['external_url'], false),
|
||||||
|
|
||||||
'sepa_cc' => $this->clearString((string) $object['sepa_cc'], false),
|
'sepa_cc' => $this->clearString((string) $object['sepa_cc'], false),
|
||||||
'sepa_ct_op' => $this->clearString((string) $object['sepa_ct_op'], false),
|
'sepa_ct_op' => $this->clearString((string) $object['sepa_ct_op'], false),
|
||||||
@@ -228,7 +228,7 @@ class StoreRequest extends FormRequest
|
|||||||
'transactions.*.external_id' => 'min:1,max:255|nullable',
|
'transactions.*.external_id' => 'min:1,max:255|nullable',
|
||||||
'transactions.*.recurrence_id' => 'min:1,max:255|nullable',
|
'transactions.*.recurrence_id' => 'min:1,max:255|nullable',
|
||||||
'transactions.*.bunq_payment_id' => 'min:1,max:255|nullable',
|
'transactions.*.bunq_payment_id' => 'min:1,max:255|nullable',
|
||||||
'transactions.*.external_uri' => 'min:1,max:255|nullable|url',
|
'transactions.*.external_url' => 'min:1,max:255|nullable|url',
|
||||||
|
|
||||||
// SEPA fields:
|
// SEPA fields:
|
||||||
'transactions.*.sepa_cc' => 'min:1,max:255|nullable',
|
'transactions.*.sepa_cc' => 'min:1,max:255|nullable',
|
||||||
|
|||||||
@@ -113,7 +113,7 @@ class UpdateRequest extends FormRequest
|
|||||||
'sepa_ep',
|
'sepa_ep',
|
||||||
'sepa_ci',
|
'sepa_ci',
|
||||||
'sepa_batch_id',
|
'sepa_batch_id',
|
||||||
'external_uri',
|
'external_url',
|
||||||
];
|
];
|
||||||
$this->booleanFields = [
|
$this->booleanFields = [
|
||||||
'reconciled',
|
'reconciled',
|
||||||
@@ -292,6 +292,10 @@ class UpdateRequest extends FormRequest
|
|||||||
'transactions.*.date' => [new IsDateOrTime],
|
'transactions.*.date' => [new IsDateOrTime],
|
||||||
'transactions.*.order' => 'numeric|min:0',
|
'transactions.*.order' => 'numeric|min:0',
|
||||||
|
|
||||||
|
// group id:
|
||||||
|
'transactions.*.transaction_journal_id' => ['nullable', 'numeric', new BelongsUser],
|
||||||
|
|
||||||
|
|
||||||
// currency info
|
// currency info
|
||||||
'transactions.*.currency_id' => 'numeric|exists:transaction_currencies,id',
|
'transactions.*.currency_id' => 'numeric|exists:transaction_currencies,id',
|
||||||
'transactions.*.currency_code' => 'min:3|max:3|exists:transaction_currencies,code',
|
'transactions.*.currency_code' => 'min:3|max:3|exists:transaction_currencies,code',
|
||||||
@@ -331,7 +335,7 @@ class UpdateRequest extends FormRequest
|
|||||||
'transactions.*.external_id' => 'min:1,max:255|nullable',
|
'transactions.*.external_id' => 'min:1,max:255|nullable',
|
||||||
'transactions.*.recurrence_id' => 'min:1,max:255|nullable',
|
'transactions.*.recurrence_id' => 'min:1,max:255|nullable',
|
||||||
'transactions.*.bunq_payment_id' => 'min:1,max:255|nullable',
|
'transactions.*.bunq_payment_id' => 'min:1,max:255|nullable',
|
||||||
'transactions.*.external_uri' => 'min:1,max:255|nullable|url',
|
'transactions.*.external_url' => 'min:1,max:255|nullable|url',
|
||||||
|
|
||||||
// SEPA fields:
|
// SEPA fields:
|
||||||
'transactions.*.sepa_cc' => 'min:1,max:255|nullable',
|
'transactions.*.sepa_cc' => 'min:1,max:255|nullable',
|
||||||
@@ -375,6 +379,9 @@ class UpdateRequest extends FormRequest
|
|||||||
// validate source/destination is equal, depending on the transaction journal type.
|
// validate source/destination is equal, depending on the transaction journal type.
|
||||||
$this->validateEqualAccountsForUpdate($validator, $transactionGroup);
|
$this->validateEqualAccountsForUpdate($validator, $transactionGroup);
|
||||||
|
|
||||||
|
// a catch when users submit splits with no source or destination info at all.
|
||||||
|
$this->preventNoAccountInfo($validator,);
|
||||||
|
|
||||||
// validate that the currency fits the source and/or destination account.
|
// validate that the currency fits the source and/or destination account.
|
||||||
// validate all account info
|
// validate all account info
|
||||||
$this->validateAccountInformationUpdate($validator, $transactionGroup);
|
$this->validateAccountInformationUpdate($validator, $transactionGroup);
|
||||||
|
|||||||
@@ -62,7 +62,7 @@ class CronRequest extends FormRequest
|
|||||||
$data['force'] = $this->boolean('force');
|
$data['force'] = $this->boolean('force');
|
||||||
}
|
}
|
||||||
if ($this->has('date')) {
|
if ($this->has('date')) {
|
||||||
$data['date'] = $this->date('date');
|
$data['date'] = $this->getCarbonDate('date');
|
||||||
}
|
}
|
||||||
|
|
||||||
return $data;
|
return $data;
|
||||||
|
|||||||
@@ -28,6 +28,7 @@ use FireflyIII\Rules\IsBoolean;
|
|||||||
use FireflyIII\Support\Request\ChecksLogin;
|
use FireflyIII\Support\Request\ChecksLogin;
|
||||||
use FireflyIII\Support\Request\ConvertsDataTypes;
|
use FireflyIII\Support\Request\ConvertsDataTypes;
|
||||||
use Illuminate\Foundation\Http\FormRequest;
|
use Illuminate\Foundation\Http\FormRequest;
|
||||||
|
use Illuminate\Validation\Validator;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Class UserUpdateRequest
|
* Class UserUpdateRequest
|
||||||
@@ -43,7 +44,7 @@ class UserUpdateRequest extends FormRequest
|
|||||||
*/
|
*/
|
||||||
public function authorize(): bool
|
public function authorize(): bool
|
||||||
{
|
{
|
||||||
return auth()->check() && auth()->user()->hasRole('owner');
|
return auth()->check();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -83,4 +84,25 @@ class UserUpdateRequest extends FormRequest
|
|||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Configure the validator instance.
|
||||||
|
*
|
||||||
|
* @param Validator $validator
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function withValidator(Validator $validator): void
|
||||||
|
{
|
||||||
|
$current = $this->route()->parameter('user');
|
||||||
|
$validator->after(
|
||||||
|
static function (Validator $validator) use ($current) {
|
||||||
|
$isAdmin = auth()->user()->hasRole('owner');
|
||||||
|
// not admin, and not own user?
|
||||||
|
if (auth()->check() && false === $isAdmin && $current?->id !== auth()->user()->id) {
|
||||||
|
$validator->errors()->add('email', (string) trans('validation.invalid_selection'));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -69,6 +69,7 @@ class CorrectDatabase extends Command
|
|||||||
'firefly-iii:delete-empty-journals',
|
'firefly-iii:delete-empty-journals',
|
||||||
'firefly-iii:delete-empty-groups',
|
'firefly-iii:delete-empty-groups',
|
||||||
'firefly-iii:fix-account-types',
|
'firefly-iii:fix-account-types',
|
||||||
|
'firefly-iii:fix-ibans',
|
||||||
'firefly-iii:fix-account-order',
|
'firefly-iii:fix-account-order',
|
||||||
'firefly-iii:rename-meta-fields',
|
'firefly-iii:rename-meta-fields',
|
||||||
'firefly-iii:fix-ob-currencies',
|
'firefly-iii:fix-ob-currencies',
|
||||||
|
|||||||
@@ -57,7 +57,6 @@ class CorrectOpeningBalanceCurrencies extends Command
|
|||||||
* Execute the console command.
|
* Execute the console command.
|
||||||
*
|
*
|
||||||
* @return int
|
* @return int
|
||||||
* @throws JsonException
|
|
||||||
*/
|
*/
|
||||||
public function handle(): int
|
public function handle(): int
|
||||||
{
|
{
|
||||||
@@ -72,9 +71,7 @@ class CorrectOpeningBalanceCurrencies extends Command
|
|||||||
$count = 0;
|
$count = 0;
|
||||||
/** @var TransactionJournal $journal */
|
/** @var TransactionJournal $journal */
|
||||||
foreach ($set as $journal) {
|
foreach ($set as $journal) {
|
||||||
Log::debug(sprintf('Going to fix journal #%d', $journal->id));
|
|
||||||
$count += $this->correctJournal($journal);
|
$count += $this->correctJournal($journal);
|
||||||
Log::debug(sprintf('Done, count is now %d', $count));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($count > 0) {
|
if ($count > 0) {
|
||||||
@@ -100,7 +97,6 @@ class CorrectOpeningBalanceCurrencies extends Command
|
|||||||
*/
|
*/
|
||||||
private function correctJournal(TransactionJournal $journal): int
|
private function correctJournal(TransactionJournal $journal): int
|
||||||
{
|
{
|
||||||
Log::debug(sprintf('Going to correct journal #%d', $journal->id));
|
|
||||||
// get the asset account for this opening balance:
|
// get the asset account for this opening balance:
|
||||||
$account = $this->getAccount($journal);
|
$account = $this->getAccount($journal);
|
||||||
if (null === $account) {
|
if (null === $account) {
|
||||||
@@ -110,9 +106,7 @@ class CorrectOpeningBalanceCurrencies extends Command
|
|||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
Log::debug(sprintf('Found "%s" #%d "%s".', $account->accountType->type, $account->id, $account->name));
|
|
||||||
$currency = $this->getCurrency($account);
|
$currency = $this->getCurrency($account);
|
||||||
Log::debug(sprintf('Found currency #%d (%s)', $currency->id, $currency->code));
|
|
||||||
|
|
||||||
// update journal and all transactions:
|
// update journal and all transactions:
|
||||||
return $this->setCurrency($journal, $currency);
|
return $this->setCurrency($journal, $currency);
|
||||||
@@ -126,20 +120,14 @@ class CorrectOpeningBalanceCurrencies extends Command
|
|||||||
private function getAccount(TransactionJournal $journal): ?Account
|
private function getAccount(TransactionJournal $journal): ?Account
|
||||||
{
|
{
|
||||||
$transactions = $journal->transactions()->get();
|
$transactions = $journal->transactions()->get();
|
||||||
Log::debug(sprintf('Found %d transactions for journal #%d.', $transactions->count(), $journal->id));
|
|
||||||
/** @var Transaction $transaction */
|
/** @var Transaction $transaction */
|
||||||
foreach ($transactions as $transaction) {
|
foreach ($transactions as $transaction) {
|
||||||
Log::debug(sprintf('Testing transaction #%d', $transaction->id));
|
|
||||||
/** @var Account $account */
|
/** @var Account $account */
|
||||||
$account = $transaction->account()->first();
|
$account = $transaction->account()->first();
|
||||||
if (null !== $account && AccountType::INITIAL_BALANCE !== $account->accountType()->first()->type) {
|
if (null !== $account && AccountType::INITIAL_BALANCE !== $account->accountType()->first()->type) {
|
||||||
Log::debug(sprintf('Account of transaction #%d is opposite of IB account (%s).', $transaction->id, $account->accountType()->first()->type));
|
|
||||||
|
|
||||||
return $account;
|
return $account;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Log::debug('Found no IB account in transactions of journal.');
|
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -147,6 +135,8 @@ class CorrectOpeningBalanceCurrencies extends Command
|
|||||||
* @param Account $account
|
* @param Account $account
|
||||||
*
|
*
|
||||||
* @return TransactionCurrency
|
* @return TransactionCurrency
|
||||||
|
* @throws JsonException
|
||||||
|
* @throws \FireflyIII\Exceptions\FireflyException
|
||||||
*/
|
*/
|
||||||
private function getCurrency(Account $account): TransactionCurrency
|
private function getCurrency(Account $account): TransactionCurrency
|
||||||
{
|
{
|
||||||
@@ -165,10 +155,8 @@ class CorrectOpeningBalanceCurrencies extends Command
|
|||||||
*/
|
*/
|
||||||
private function setCurrency(TransactionJournal $journal, TransactionCurrency $currency): int
|
private function setCurrency(TransactionJournal $journal, TransactionCurrency $currency): int
|
||||||
{
|
{
|
||||||
Log::debug('Now in setCurrency');
|
|
||||||
$count = 0;
|
$count = 0;
|
||||||
if ((int) $journal->transaction_currency_id !== (int) $currency->id) {
|
if ((int) $journal->transaction_currency_id !== (int) $currency->id) {
|
||||||
Log::debug(sprintf('Currency ID of journal #%d was #%d, now set to #%d', $journal->id, $journal->transaction_currency_id, $currency->id));
|
|
||||||
$journal->transaction_currency_id = $currency->id;
|
$journal->transaction_currency_id = $currency->id;
|
||||||
$journal->save();
|
$journal->save();
|
||||||
$count = 1;
|
$count = 1;
|
||||||
@@ -177,15 +165,11 @@ class CorrectOpeningBalanceCurrencies extends Command
|
|||||||
/** @var Transaction $transaction */
|
/** @var Transaction $transaction */
|
||||||
foreach ($journal->transactions as $transaction) {
|
foreach ($journal->transactions as $transaction) {
|
||||||
if ((int) $transaction->transaction_currency_id !== (int) $currency->id) {
|
if ((int) $transaction->transaction_currency_id !== (int) $currency->id) {
|
||||||
Log::debug(
|
|
||||||
sprintf('Currency ID of transaction #%d was #%d, now set to #%d', $transaction->id, $transaction->transaction_currency_id, $currency->id)
|
|
||||||
);
|
|
||||||
$transaction->transaction_currency_id = $currency->id;
|
$transaction->transaction_currency_id = $currency->id;
|
||||||
$transaction->save();
|
$transaction->save();
|
||||||
$count = 1;
|
$count = 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Log::debug(sprintf('Return %d', $count));
|
|
||||||
|
|
||||||
return $count;
|
return $count;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ use Illuminate\Console\Command;
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Class CorrectionSkeleton
|
* Class CorrectionSkeleton
|
||||||
|
* TODO DONT FORGET TO ADD THIS TO THE DOCKER BUILD
|
||||||
*/
|
*/
|
||||||
class CorrectionSkeleton extends Command
|
class CorrectionSkeleton extends Command
|
||||||
{
|
{
|
||||||
|
|||||||
72
app/Console/Commands/Correction/FixIbans.php
Normal file
72
app/Console/Commands/Correction/FixIbans.php
Normal file
@@ -0,0 +1,72 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
* FixIbans.php
|
||||||
|
* Copyright (c) 2022 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 FireflyIII\Models\Account;
|
||||||
|
use Illuminate\Console\Command;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class FixIbans
|
||||||
|
*/
|
||||||
|
class FixIbans extends Command
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* The console command description.
|
||||||
|
*
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
protected $description = 'Removes spaces from IBANs';
|
||||||
|
/**
|
||||||
|
* The name and signature of the console command.
|
||||||
|
*
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
protected $signature = 'firefly-iii:fix-ibans';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Execute the console command.
|
||||||
|
*
|
||||||
|
* @return int
|
||||||
|
*/
|
||||||
|
public function handle(): int
|
||||||
|
{
|
||||||
|
$accounts = Account::whereNotNull('iban')->get();
|
||||||
|
/** @var Account $account */
|
||||||
|
foreach ($accounts as $account) {
|
||||||
|
$iban = $account->iban;
|
||||||
|
if (str_contains($iban, ' ')) {
|
||||||
|
|
||||||
|
$iban = app('steam')->filterSpaces((string) $account->iban);
|
||||||
|
if ('' !== $iban) {
|
||||||
|
$account->iban = $iban;
|
||||||
|
$account->save();
|
||||||
|
$this->line(sprintf('Removed spaces from IBAN of account #%d', $account->id));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -68,6 +68,7 @@ class RenameMetaFields extends Command
|
|||||||
'sepa-ep' => 'sepa_ep',
|
'sepa-ep' => 'sepa_ep',
|
||||||
'sepa-ci' => 'sepa_ci',
|
'sepa-ci' => 'sepa_ci',
|
||||||
'sepa-batch-id' => 'sepa_batch_id',
|
'sepa-batch-id' => 'sepa_batch_id',
|
||||||
|
'external_uri' => 'external_url',
|
||||||
];
|
];
|
||||||
foreach ($changes as $original => $update) {
|
foreach ($changes as $original => $update) {
|
||||||
$this->rename($original, $update);
|
$this->rename($original, $update);
|
||||||
|
|||||||
@@ -63,6 +63,12 @@ class CreateDatabase extends Command
|
|||||||
$exists = false;
|
$exists = false;
|
||||||
$checked = false; // checked for existence of DB?
|
$checked = false; // checked for existence of DB?
|
||||||
$dsn = sprintf('mysql:host=%s;port=%d;charset=utf8mb4', env('DB_HOST', 'localhost'), env('DB_PORT', '3306'));
|
$dsn = sprintf('mysql:host=%s;port=%d;charset=utf8mb4', env('DB_HOST', 'localhost'), env('DB_PORT', '3306'));
|
||||||
|
|
||||||
|
if ('' !== env('DB_SOCKET', '')) {
|
||||||
|
$dsn = sprintf('mysql:unix_socket=%s;charset=utf8mb4', env('DB_SOCKET', ''));
|
||||||
|
}
|
||||||
|
$this->info(sprintf('DSN is %s', $dsn));
|
||||||
|
|
||||||
$options = [
|
$options = [
|
||||||
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
|
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
|
||||||
PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
|
PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
|
||||||
|
|||||||
@@ -109,6 +109,8 @@ class DecryptDatabase extends Command
|
|||||||
* @param string $table
|
* @param string $table
|
||||||
*
|
*
|
||||||
* @return bool
|
* @return bool
|
||||||
|
* @throws \Psr\Container\ContainerExceptionInterface
|
||||||
|
* @throws \Psr\Container\NotFoundExceptionInterface
|
||||||
*/
|
*/
|
||||||
private function isDecrypted(string $table): bool
|
private function isDecrypted(string $table): bool
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ use Illuminate\Console\Command;
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Class ReportSkeleton
|
* Class ReportSkeleton
|
||||||
|
* TODO DONT FORGET TO ADD THIS TO THE DOCKER BUILD
|
||||||
*/
|
*/
|
||||||
class ReportSkeleton extends Command
|
class ReportSkeleton extends Command
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -74,11 +74,19 @@ class RestoreOAuthKeys extends Command
|
|||||||
}
|
}
|
||||||
if ($this->keysInDatabase() && !$this->keysOnDrive()) {
|
if ($this->keysInDatabase() && !$this->keysOnDrive()) {
|
||||||
Log::debug('Keys are in DB and keys are not on the drive. Restore.');
|
Log::debug('Keys are in DB and keys are not on the drive. Restore.');
|
||||||
$this->restoreKeysFromDB();
|
$result = $this->restoreKeysFromDB();
|
||||||
|
if (true === $result) {
|
||||||
$this->line('Restored OAuth keys from database.');
|
$this->line('Restored OAuth keys from database.');
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
Log::warning('Could not restore keys. Will create new ones.');
|
||||||
|
$this->generateKeys();
|
||||||
|
$this->storeKeysInDB();
|
||||||
|
$this->line('Generated and stored new keys.');
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
if (!$this->keysInDatabase() && $this->keysOnDrive()) {
|
if (!$this->keysInDatabase() && $this->keysOnDrive()) {
|
||||||
Log::debug('Keys are not in DB and keys are on the drive. Save in DB.');
|
Log::debug('Keys are not in DB and keys are on the drive. Save in DB.');
|
||||||
$this->storeKeysInDB();
|
$this->storeKeysInDB();
|
||||||
@@ -124,8 +132,8 @@ class RestoreOAuthKeys extends Command
|
|||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
private function restoreKeysFromDB(): void
|
private function restoreKeysFromDB(): bool
|
||||||
{
|
{
|
||||||
OAuthKeys::restoreKeysFromDB();
|
return OAuthKeys::restoreKeysFromDB();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -27,7 +27,6 @@ use Crypt;
|
|||||||
use FireflyIII\Models\Attachment;
|
use FireflyIII\Models\Attachment;
|
||||||
use Illuminate\Console\Command;
|
use Illuminate\Console\Command;
|
||||||
use Illuminate\Contracts\Encryption\DecryptException;
|
use Illuminate\Contracts\Encryption\DecryptException;
|
||||||
use Illuminate\Contracts\Filesystem\FileNotFoundException;
|
|
||||||
use Log;
|
use Log;
|
||||||
use Storage;
|
use Storage;
|
||||||
|
|
||||||
@@ -62,10 +61,9 @@ class ScanAttachments extends Command
|
|||||||
/** @var Attachment $attachment */
|
/** @var Attachment $attachment */
|
||||||
foreach ($attachments as $attachment) {
|
foreach ($attachments as $attachment) {
|
||||||
$fileName = $attachment->fileName();
|
$fileName = $attachment->fileName();
|
||||||
try {
|
|
||||||
$encryptedContent = $disk->get($fileName);
|
$encryptedContent = $disk->get($fileName);
|
||||||
} catch (FileNotFoundException $e) {
|
if (null === $encryptedContent) {
|
||||||
$this->error(sprintf('Could not find data for attachment #%d: %s', $attachment->id, $e->getMessage()));
|
Log::error(sprintf('No content for attachment #%d under filename "%s"', $attachment->id, $fileName));
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
|
|||||||
@@ -27,6 +27,7 @@ namespace FireflyIII\Console\Commands\Tools;
|
|||||||
use Carbon\Carbon;
|
use Carbon\Carbon;
|
||||||
use FireflyIII\Exceptions\FireflyException;
|
use FireflyIII\Exceptions\FireflyException;
|
||||||
use FireflyIII\Support\Cronjobs\AutoBudgetCronjob;
|
use FireflyIII\Support\Cronjobs\AutoBudgetCronjob;
|
||||||
|
use FireflyIII\Support\Cronjobs\BillWarningCronjob;
|
||||||
use FireflyIII\Support\Cronjobs\RecurringCronjob;
|
use FireflyIII\Support\Cronjobs\RecurringCronjob;
|
||||||
use Illuminate\Console\Command;
|
use Illuminate\Console\Command;
|
||||||
use InvalidArgumentException;
|
use InvalidArgumentException;
|
||||||
@@ -90,6 +91,17 @@ class Cron extends Command
|
|||||||
$this->error($e->getMessage());
|
$this->error($e->getMessage());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Fire bill warning cron job
|
||||||
|
*/
|
||||||
|
try {
|
||||||
|
$this->billWarningCronJob($force, $date);
|
||||||
|
} catch (FireflyException $e) {
|
||||||
|
Log::error($e->getMessage());
|
||||||
|
Log::error($e->getTraceAsString());
|
||||||
|
$this->error($e->getMessage());
|
||||||
|
}
|
||||||
|
|
||||||
$this->info('More feedback on the cron jobs can be found in the log files.');
|
$this->info('More feedback on the cron jobs can be found in the log files.');
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
@@ -150,4 +162,32 @@ class Cron extends Command
|
|||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param bool $force
|
||||||
|
* @param Carbon|null $date
|
||||||
|
* @throws FireflyException
|
||||||
|
*/
|
||||||
|
private function billWarningCronJob(bool $force, ?Carbon $date): void
|
||||||
|
{
|
||||||
|
$autoBudget = new BillWarningCronjob;
|
||||||
|
$autoBudget->setForce($force);
|
||||||
|
// set date in cron job:
|
||||||
|
if (null !== $date) {
|
||||||
|
$autoBudget->setDate($date);
|
||||||
|
}
|
||||||
|
|
||||||
|
$autoBudget->fire();
|
||||||
|
|
||||||
|
if ($autoBudget->jobErrored) {
|
||||||
|
$this->error(sprintf('Error in "bill warnings" cron: %s', $autoBudget->message));
|
||||||
|
}
|
||||||
|
if ($autoBudget->jobFired) {
|
||||||
|
$this->error(sprintf('"Send bill warnings" cron fired: %s', $autoBudget->message));
|
||||||
|
}
|
||||||
|
if ($autoBudget->jobSucceeded) {
|
||||||
|
$this->error(sprintf('"Send bill warnings" cron ran with success: %s', $autoBudget->message));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -109,6 +109,8 @@ class AccountCurrencies extends Command
|
|||||||
/**
|
/**
|
||||||
* @return bool
|
* @return bool
|
||||||
* @throws FireflyException
|
* @throws FireflyException
|
||||||
|
* @throws \Psr\Container\ContainerExceptionInterface
|
||||||
|
* @throws \Psr\Container\NotFoundExceptionInterface
|
||||||
*/
|
*/
|
||||||
private function isExecuted(): bool
|
private function isExecuted(): bool
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -72,6 +72,8 @@ class AppendBudgetLimitPeriods extends Command
|
|||||||
/**
|
/**
|
||||||
* @return bool
|
* @return bool
|
||||||
* @throws FireflyException
|
* @throws FireflyException
|
||||||
|
* @throws \Psr\Container\ContainerExceptionInterface
|
||||||
|
* @throws \Psr\Container\NotFoundExceptionInterface
|
||||||
*/
|
*/
|
||||||
private function isExecuted(): bool
|
private function isExecuted(): bool
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -86,6 +86,8 @@ class BackToJournals extends Command
|
|||||||
/**
|
/**
|
||||||
* @return bool
|
* @return bool
|
||||||
* @throws FireflyException
|
* @throws FireflyException
|
||||||
|
* @throws \Psr\Container\ContainerExceptionInterface
|
||||||
|
* @throws \Psr\Container\NotFoundExceptionInterface
|
||||||
*/
|
*/
|
||||||
private function isMigrated(): bool
|
private function isMigrated(): bool
|
||||||
{
|
{
|
||||||
@@ -97,6 +99,8 @@ class BackToJournals extends Command
|
|||||||
/**
|
/**
|
||||||
* @return bool
|
* @return bool
|
||||||
* @throws FireflyException
|
* @throws FireflyException
|
||||||
|
* @throws \Psr\Container\ContainerExceptionInterface
|
||||||
|
* @throws \Psr\Container\NotFoundExceptionInterface
|
||||||
*/
|
*/
|
||||||
private function isExecuted(): bool
|
private function isExecuted(): bool
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -99,6 +99,8 @@ class BudgetLimitCurrency extends Command
|
|||||||
/**
|
/**
|
||||||
* @return bool
|
* @return bool
|
||||||
* @throws FireflyException
|
* @throws FireflyException
|
||||||
|
* @throws \Psr\Container\ContainerExceptionInterface
|
||||||
|
* @throws \Psr\Container\NotFoundExceptionInterface
|
||||||
*/
|
*/
|
||||||
private function isExecuted(): bool
|
private function isExecuted(): bool
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -96,6 +96,8 @@ class CCLiabilities extends Command
|
|||||||
/**
|
/**
|
||||||
* @return bool
|
* @return bool
|
||||||
* @throws FireflyException
|
* @throws FireflyException
|
||||||
|
* @throws \Psr\Container\ContainerExceptionInterface
|
||||||
|
* @throws \Psr\Container\NotFoundExceptionInterface
|
||||||
*/
|
*/
|
||||||
private function isExecuted(): bool
|
private function isExecuted(): bool
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -77,6 +77,8 @@ class CreateGroupMemberships extends Command
|
|||||||
/**
|
/**
|
||||||
* @return bool
|
* @return bool
|
||||||
* @throws FireflyException
|
* @throws FireflyException
|
||||||
|
* @throws \Psr\Container\ContainerExceptionInterface
|
||||||
|
* @throws \Psr\Container\NotFoundExceptionInterface
|
||||||
*/
|
*/
|
||||||
private function isExecuted(): bool
|
private function isExecuted(): bool
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -108,6 +108,8 @@ class MigrateAttachments extends Command
|
|||||||
/**
|
/**
|
||||||
* @return bool
|
* @return bool
|
||||||
* @throws FireflyException
|
* @throws FireflyException
|
||||||
|
* @throws \Psr\Container\ContainerExceptionInterface
|
||||||
|
* @throws \Psr\Container\NotFoundExceptionInterface
|
||||||
*/
|
*/
|
||||||
private function isExecuted(): bool
|
private function isExecuted(): bool
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -106,6 +106,8 @@ class MigrateJournalNotes extends Command
|
|||||||
/**
|
/**
|
||||||
* @return bool
|
* @return bool
|
||||||
* @throws FireflyException
|
* @throws FireflyException
|
||||||
|
* @throws \Psr\Container\ContainerExceptionInterface
|
||||||
|
* @throws \Psr\Container\NotFoundExceptionInterface
|
||||||
*/
|
*/
|
||||||
private function isExecuted(): bool
|
private function isExecuted(): bool
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -84,6 +84,8 @@ class MigrateRecurrenceMeta extends Command
|
|||||||
/**
|
/**
|
||||||
* @return bool
|
* @return bool
|
||||||
* @throws FireflyException
|
* @throws FireflyException
|
||||||
|
* @throws \Psr\Container\ContainerExceptionInterface
|
||||||
|
* @throws \Psr\Container\NotFoundExceptionInterface
|
||||||
*/
|
*/
|
||||||
private function isExecuted(): bool
|
private function isExecuted(): bool
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -77,6 +77,8 @@ class MigrateRecurrenceType extends Command
|
|||||||
/**
|
/**
|
||||||
* @return bool
|
* @return bool
|
||||||
* @throws FireflyException
|
* @throws FireflyException
|
||||||
|
* @throws \Psr\Container\ContainerExceptionInterface
|
||||||
|
* @throws \Psr\Container\NotFoundExceptionInterface
|
||||||
*/
|
*/
|
||||||
private function isExecuted(): bool
|
private function isExecuted(): bool
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -75,6 +75,8 @@ class MigrateTagLocations extends Command
|
|||||||
/**
|
/**
|
||||||
* @return bool
|
* @return bool
|
||||||
* @throws FireflyException
|
* @throws FireflyException
|
||||||
|
* @throws \Psr\Container\ContainerExceptionInterface
|
||||||
|
* @throws \Psr\Container\NotFoundExceptionInterface
|
||||||
*/
|
*/
|
||||||
private function isExecuted(): bool
|
private function isExecuted(): bool
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -129,6 +129,8 @@ class MigrateToGroups extends Command
|
|||||||
/**
|
/**
|
||||||
* @return bool
|
* @return bool
|
||||||
* @throws FireflyException
|
* @throws FireflyException
|
||||||
|
* @throws \Psr\Container\ContainerExceptionInterface
|
||||||
|
* @throws \Psr\Container\NotFoundExceptionInterface
|
||||||
*/
|
*/
|
||||||
private function isMigrated(): bool
|
private function isMigrated(): bool
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -120,6 +120,8 @@ class MigrateToRules extends Command
|
|||||||
/**
|
/**
|
||||||
* @return bool
|
* @return bool
|
||||||
* @throws FireflyException
|
* @throws FireflyException
|
||||||
|
* @throws \Psr\Container\ContainerExceptionInterface
|
||||||
|
* @throws \Psr\Container\NotFoundExceptionInterface
|
||||||
*/
|
*/
|
||||||
private function isExecuted(): bool
|
private function isExecuted(): bool
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -115,6 +115,8 @@ class OtherCurrenciesCorrections extends Command
|
|||||||
/**
|
/**
|
||||||
* @return bool
|
* @return bool
|
||||||
* @throws FireflyException
|
* @throws FireflyException
|
||||||
|
* @throws \Psr\Container\ContainerExceptionInterface
|
||||||
|
* @throws \Psr\Container\NotFoundExceptionInterface
|
||||||
*/
|
*/
|
||||||
private function isExecuted(): bool
|
private function isExecuted(): bool
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -99,6 +99,8 @@ class RenameAccountMeta extends Command
|
|||||||
/**
|
/**
|
||||||
* @return bool
|
* @return bool
|
||||||
* @throws FireflyException
|
* @throws FireflyException
|
||||||
|
* @throws \Psr\Container\ContainerExceptionInterface
|
||||||
|
* @throws \Psr\Container\NotFoundExceptionInterface
|
||||||
*/
|
*/
|
||||||
private function isExecuted(): bool
|
private function isExecuted(): bool
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -123,6 +123,8 @@ class TransactionIdentifier extends Command
|
|||||||
/**
|
/**
|
||||||
* @return bool
|
* @return bool
|
||||||
* @throws FireflyException
|
* @throws FireflyException
|
||||||
|
* @throws \Psr\Container\ContainerExceptionInterface
|
||||||
|
* @throws \Psr\Container\NotFoundExceptionInterface
|
||||||
*/
|
*/
|
||||||
private function isExecuted(): bool
|
private function isExecuted(): bool
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -68,6 +68,9 @@ class TransferCurrenciesCorrections extends Command
|
|||||||
* Execute the console command.
|
* Execute the console command.
|
||||||
*
|
*
|
||||||
* @return int
|
* @return int
|
||||||
|
* @throws FireflyException
|
||||||
|
* @throws \Psr\Container\ContainerExceptionInterface
|
||||||
|
* @throws \Psr\Container\NotFoundExceptionInterface
|
||||||
*/
|
*/
|
||||||
public function handle(): int
|
public function handle(): int
|
||||||
{
|
{
|
||||||
@@ -134,6 +137,8 @@ class TransferCurrenciesCorrections extends Command
|
|||||||
/**
|
/**
|
||||||
* @return bool
|
* @return bool
|
||||||
* @throws FireflyException
|
* @throws FireflyException
|
||||||
|
* @throws \Psr\Container\ContainerExceptionInterface
|
||||||
|
* @throws \Psr\Container\NotFoundExceptionInterface
|
||||||
*/
|
*/
|
||||||
private function isExecuted(): bool
|
private function isExecuted(): bool
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -98,6 +98,7 @@ class UpgradeDatabase extends Command
|
|||||||
'firefly-iii:unify-group-accounts',
|
'firefly-iii:unify-group-accounts',
|
||||||
'firefly-iii:fix-transaction-types',
|
'firefly-iii:fix-transaction-types',
|
||||||
'firefly-iii:fix-frontpage-accounts',
|
'firefly-iii:fix-frontpage-accounts',
|
||||||
|
'firefly-iii:fix-ibans',
|
||||||
|
|
||||||
// two report commands
|
// two report commands
|
||||||
'firefly-iii:report-empty-objects',
|
'firefly-iii:report-empty-objects',
|
||||||
|
|||||||
@@ -81,6 +81,8 @@ class UpgradeLiabilities extends Command
|
|||||||
/**
|
/**
|
||||||
* @return bool
|
* @return bool
|
||||||
* @throws FireflyException
|
* @throws FireflyException
|
||||||
|
* @throws \Psr\Container\ContainerExceptionInterface
|
||||||
|
* @throws \Psr\Container\NotFoundExceptionInterface
|
||||||
*/
|
*/
|
||||||
private function isExecuted(): bool
|
private function isExecuted(): bool
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -5,7 +5,8 @@ namespace FireflyIII\Console\Commands\Upgrade;
|
|||||||
use Illuminate\Console\Command;
|
use Illuminate\Console\Command;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Class UpgradeSkeleton
|
* Class UpgradeSkeleton.
|
||||||
|
* TODO DONT FORGET TO ADD THIS TO THE DOCKER BUILD
|
||||||
*/
|
*/
|
||||||
class UpgradeSkeleton extends Command
|
class UpgradeSkeleton extends Command
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -25,7 +25,6 @@ declare(strict_types=1);
|
|||||||
namespace FireflyIII\Console\Commands;
|
namespace FireflyIII\Console\Commands;
|
||||||
|
|
||||||
use Illuminate\Console\Command;
|
use Illuminate\Console\Command;
|
||||||
use Illuminate\Contracts\Filesystem\FileNotFoundException;
|
|
||||||
use Log;
|
use Log;
|
||||||
use Storage;
|
use Storage;
|
||||||
|
|
||||||
@@ -51,7 +50,7 @@ class VerifySecurityAlerts extends Command
|
|||||||
* Execute the console command.
|
* Execute the console command.
|
||||||
*
|
*
|
||||||
* @return int
|
* @return int
|
||||||
* @throws FileNotFoundException
|
* @throws \League\Flysystem\FilesystemException
|
||||||
*/
|
*/
|
||||||
public function handle(): int
|
public function handle(): int
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -42,7 +42,6 @@ class Kernel extends ConsoleKernel
|
|||||||
{
|
{
|
||||||
$this->load(__DIR__ . '/Commands');
|
$this->load(__DIR__ . '/Commands');
|
||||||
|
|
||||||
/** @noinspection PhpIncludeInspection */
|
|
||||||
require base_path('routes/console.php');
|
require base_path('routes/console.php');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -30,6 +30,6 @@ namespace FireflyIII\Enums;
|
|||||||
class ClauseType
|
class ClauseType
|
||||||
{
|
{
|
||||||
public const TRANSACTION = 'transaction';
|
public const TRANSACTION = 'transaction';
|
||||||
public const WHERE = 'where';
|
|
||||||
public const UPDATE = 'update';
|
public const UPDATE = 'update';
|
||||||
|
public const WHERE = 'where';
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
<?php
|
<?php
|
||||||
declare(strict_types=1);
|
|
||||||
/*
|
/*
|
||||||
* ActuallyLoggedIn.php
|
* ActuallyLoggedIn.php
|
||||||
* Copyright (c) 2021 james@firefly-iii.org
|
* Copyright (c) 2022 james@firefly-iii.org
|
||||||
*
|
*
|
||||||
* This file is part of Firefly III (https://github.com/firefly-iii).
|
* 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/>.
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
namespace FireflyIII\Events;
|
namespace FireflyIII\Events;
|
||||||
|
|
||||||
use FireflyIII\User;
|
use FireflyIII\User;
|
||||||
|
|||||||
@@ -37,21 +37,16 @@ class AdminRequestedTestMessage extends Event
|
|||||||
{
|
{
|
||||||
use SerializesModels;
|
use SerializesModels;
|
||||||
|
|
||||||
/** @var string The users IP address */
|
public User $user;
|
||||||
public $ipAddress;
|
|
||||||
/** @var User The user */
|
|
||||||
public $user;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a new event instance.
|
* Create a new event instance.
|
||||||
*
|
*
|
||||||
* @param User $user
|
* @param User $user
|
||||||
* @param string $ipAddress
|
|
||||||
*/
|
*/
|
||||||
public function __construct(User $user, string $ipAddress)
|
public function __construct(User $user)
|
||||||
{
|
{
|
||||||
Log::debug(sprintf('Triggered AdminRequestedTestMessage for user #%d (%s) and IP %s!', $user->id, $user->email, $ipAddress));
|
Log::debug(sprintf('Triggered AdminRequestedTestMessage for user #%d (%s)', $user->id, $user->email));
|
||||||
$this->user = $user;
|
$this->user = $user;
|
||||||
$this->ipAddress = $ipAddress;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -40,10 +40,8 @@ class RequestedReportOnJournals
|
|||||||
{
|
{
|
||||||
use Dispatchable, InteractsWithSockets, SerializesModels;
|
use Dispatchable, InteractsWithSockets, SerializesModels;
|
||||||
|
|
||||||
/** @var Collection The transaction groups to report on. */
|
public Collection $groups;
|
||||||
public $groups;
|
public int $userId;
|
||||||
/** @var int The ID of the user. */
|
|
||||||
public $userId;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a new event instance.
|
* Create a new event instance.
|
||||||
|
|||||||
@@ -36,14 +36,9 @@ class UserChangedEmail extends Event
|
|||||||
{
|
{
|
||||||
use SerializesModels;
|
use SerializesModels;
|
||||||
|
|
||||||
/** @var string The user's IP address */
|
public string $newEmail;
|
||||||
public $ipAddress;
|
public string $oldEmail;
|
||||||
/** @var string The user's new email address */
|
public User $user;
|
||||||
public $newEmail;
|
|
||||||
/** @var string The user's old email address */
|
|
||||||
public $oldEmail;
|
|
||||||
/** @var User The user itself */
|
|
||||||
public $user;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* UserChangedEmail constructor.
|
* UserChangedEmail constructor.
|
||||||
@@ -51,12 +46,10 @@ class UserChangedEmail extends Event
|
|||||||
* @param User $user
|
* @param User $user
|
||||||
* @param string $newEmail
|
* @param string $newEmail
|
||||||
* @param string $oldEmail
|
* @param string $oldEmail
|
||||||
* @param string $ipAddress
|
|
||||||
*/
|
*/
|
||||||
public function __construct(User $user, string $newEmail, string $oldEmail, string $ipAddress)
|
public function __construct(User $user, string $newEmail, string $oldEmail)
|
||||||
{
|
{
|
||||||
$this->user = $user;
|
$this->user = $user;
|
||||||
$this->ipAddress = $ipAddress;
|
|
||||||
$this->oldEmail = $oldEmail;
|
$this->oldEmail = $oldEmail;
|
||||||
$this->newEmail = $newEmail;
|
$this->newEmail = $newEmail;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* HelpController.php
|
* DestroyedTransactionGroup.php
|
||||||
* Copyright (c) 2019 james@firefly-iii.org
|
* Copyright (c) 2019 james@firefly-iii.org
|
||||||
*
|
*
|
||||||
* This file is part of Firefly III (https://github.com/firefly-iii).
|
* This file is part of Firefly III (https://github.com/firefly-iii).
|
||||||
@@ -18,33 +19,36 @@
|
|||||||
* You should have received a copy of the GNU Affero General Public License
|
* 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/>.
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
declare(strict_types=1);
|
declare(strict_types=1);
|
||||||
|
|
||||||
namespace FireflyIII\Http\Controllers;
|
namespace FireflyIII\Events;
|
||||||
|
|
||||||
use FireflyIII\Exceptions\FireflyException;
|
use FireflyIII\Models\Bill;
|
||||||
use Illuminate\Http\JsonResponse;
|
use Illuminate\Queue\SerializesModels;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Class HelpController.
|
* Class WarnUserAboutBill.
|
||||||
|
*
|
||||||
|
* @codeCoverageIgnore
|
||||||
*/
|
*/
|
||||||
class HelpController extends Controller
|
class WarnUserAboutBill extends Event
|
||||||
{
|
{
|
||||||
|
use SerializesModels;
|
||||||
|
|
||||||
|
public Bill $bill;
|
||||||
|
public int $diff;
|
||||||
|
public string $field;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Show help for a route.
|
* @param Bill $bill
|
||||||
*
|
* @param string $field
|
||||||
* @param string $route
|
* @param int $diff
|
||||||
*
|
|
||||||
* @return JsonResponse
|
|
||||||
* @throws FireflyException
|
|
||||||
*/
|
*/
|
||||||
public function show(string $route): JsonResponse
|
public function __construct(Bill $bill, string $field, int $diff)
|
||||||
{
|
{
|
||||||
/** @var string $language */
|
$this->bill = $bill;
|
||||||
$language = app('preferences')->get('language', config('firefly.default_language', 'en_US'))->data;
|
$this->field = $field;
|
||||||
$html = $this->getHelpText($route, $language);
|
$this->diff = $diff;
|
||||||
|
|
||||||
return response()->json(['html' => $html]);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -71,9 +71,11 @@ class GracefulNotFoundHandler extends ExceptionHandler
|
|||||||
|
|
||||||
return parent::render($request, $e);
|
return parent::render($request, $e);
|
||||||
case 'accounts.show':
|
case 'accounts.show':
|
||||||
|
case 'accounts.edit':
|
||||||
case 'accounts.show.all':
|
case 'accounts.show.all':
|
||||||
return $this->handleAccount($request, $e);
|
return $this->handleAccount($request, $e);
|
||||||
case 'transactions.show':
|
case 'transactions.show':
|
||||||
|
case 'transactions.edit':
|
||||||
return $this->handleGroup($request, $e);
|
return $this->handleGroup($request, $e);
|
||||||
case 'attachments.show':
|
case 'attachments.show':
|
||||||
case 'attachments.edit':
|
case 'attachments.edit':
|
||||||
@@ -91,6 +93,7 @@ class GracefulNotFoundHandler extends ExceptionHandler
|
|||||||
return redirect(route('currencies.index'));
|
return redirect(route('currencies.index'));
|
||||||
case 'budgets.show':
|
case 'budgets.show':
|
||||||
case 'budgets.edit':
|
case 'budgets.edit':
|
||||||
|
case 'budgets.show.limit':
|
||||||
$request->session()->reflash();
|
$request->session()->reflash();
|
||||||
|
|
||||||
return redirect(route('budgets.index'));
|
return redirect(route('budgets.index'));
|
||||||
@@ -118,7 +121,6 @@ class GracefulNotFoundHandler extends ExceptionHandler
|
|||||||
$request->session()->reflash();
|
$request->session()->reflash();
|
||||||
|
|
||||||
return redirect(route('rules.index'));
|
return redirect(route('rules.index'));
|
||||||
case 'transactions.edit':
|
|
||||||
case 'transactions.mass.edit':
|
case 'transactions.mass.edit':
|
||||||
case 'transactions.mass.delete':
|
case 'transactions.mass.delete':
|
||||||
case 'transactions.bulk.edit':
|
case 'transactions.bulk.edit':
|
||||||
|
|||||||
@@ -153,6 +153,12 @@ class Handler extends ExceptionHandler
|
|||||||
$userData['id'] = auth()->user()->id;
|
$userData['id'] = auth()->user()->id;
|
||||||
$userData['email'] = auth()->user()->email;
|
$userData['email'] = auth()->user()->email;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$headers = [];
|
||||||
|
if (request()->headers) {
|
||||||
|
$headers = request()->headers->all();
|
||||||
|
}
|
||||||
|
|
||||||
$data = [
|
$data = [
|
||||||
'class' => get_class($e),
|
'class' => get_class($e),
|
||||||
'errorMessage' => $e->getMessage(),
|
'errorMessage' => $e->getMessage(),
|
||||||
@@ -165,6 +171,7 @@ class Handler extends ExceptionHandler
|
|||||||
'url' => request()->fullUrl(),
|
'url' => request()->fullUrl(),
|
||||||
'userAgent' => request()->userAgent(),
|
'userAgent' => request()->userAgent(),
|
||||||
'json' => request()->acceptsJson(),
|
'json' => request()->acceptsJson(),
|
||||||
|
'headers' => $headers,
|
||||||
];
|
];
|
||||||
|
|
||||||
// create job that will mail.
|
// create job that will mail.
|
||||||
|
|||||||
@@ -74,6 +74,7 @@ class AccountFactory
|
|||||||
*
|
*
|
||||||
* @return Account
|
* @return Account
|
||||||
* @throws FireflyException
|
* @throws FireflyException
|
||||||
|
* @throws JsonException
|
||||||
*/
|
*/
|
||||||
public function findOrCreate(string $accountName, string $accountType): Account
|
public function findOrCreate(string $accountName, string $accountType): Account
|
||||||
{
|
{
|
||||||
@@ -182,6 +183,7 @@ class AccountFactory
|
|||||||
* @param array $data
|
* @param array $data
|
||||||
*
|
*
|
||||||
* @return Account
|
* @return Account
|
||||||
|
* @throws FireflyException
|
||||||
* @throws JsonException
|
* @throws JsonException
|
||||||
*/
|
*/
|
||||||
private function createAccount(AccountType $type, array $data): Account
|
private function createAccount(AccountType $type, array $data): Account
|
||||||
@@ -361,7 +363,6 @@ class AccountFactory
|
|||||||
* @param array $data
|
* @param array $data
|
||||||
*
|
*
|
||||||
* @throws FireflyException
|
* @throws FireflyException
|
||||||
* @throws JsonException
|
|
||||||
*/
|
*/
|
||||||
private function storeOrder(Account $account, array $data): void
|
private function storeOrder(Account $account, array $data): void
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -58,12 +58,10 @@ class AccountMetaFactory
|
|||||||
}
|
}
|
||||||
|
|
||||||
// if $data has field and $entry is not null, update $entry:
|
// if $data has field and $entry is not null, update $entry:
|
||||||
if (null !== $entry) {
|
|
||||||
$entry->data = $value;
|
$entry->data = $value;
|
||||||
$entry->save();
|
$entry->save();
|
||||||
Log::debug(sprintf('Updated meta-field "%s":"%s" for #%d ("%s") ', $field, $value, $account->id, $account->name));
|
Log::debug(sprintf('Updated meta-field "%s":"%s" for #%d ("%s") ', $field, $value, $account->id, $account->name));
|
||||||
}
|
}
|
||||||
}
|
|
||||||
if ('' === $value && null !== $entry) {
|
if ('' === $value && null !== $entry) {
|
||||||
try {
|
try {
|
||||||
$entry->delete();
|
$entry->delete();
|
||||||
|
|||||||
@@ -46,6 +46,7 @@ class BillFactory
|
|||||||
*
|
*
|
||||||
* @return Bill|null
|
* @return Bill|null
|
||||||
* @throws FireflyException
|
* @throws FireflyException
|
||||||
|
* @throws \JsonException
|
||||||
*/
|
*/
|
||||||
public function create(array $data): ?Bill
|
public function create(array $data): ?Bill
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -43,6 +43,15 @@ class TransactionCurrencyFactory
|
|||||||
*/
|
*/
|
||||||
public function create(array $data): TransactionCurrency
|
public function create(array $data): TransactionCurrency
|
||||||
{
|
{
|
||||||
|
// if the code already exists (deleted)
|
||||||
|
// force delete it and then create the transaction:
|
||||||
|
$count = TransactionCurrency::withTrashed()->whereCode($data['code'])->count();
|
||||||
|
if (1 === $count) {
|
||||||
|
$old = TransactionCurrency::withTrashed()->whereCode($data['code'])->first();
|
||||||
|
$old->forceDelete();
|
||||||
|
Log::warning(sprintf('Force deleted old currency with ID #%d and code "%s".', $old->id, $data['code']));
|
||||||
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
/** @var TransactionCurrency $result */
|
/** @var TransactionCurrency $result */
|
||||||
$result = TransactionCurrency::create(
|
$result = TransactionCurrency::create(
|
||||||
|
|||||||
@@ -57,6 +57,7 @@ class TransactionGroupFactory
|
|||||||
* @return TransactionGroup
|
* @return TransactionGroup
|
||||||
* @throws DuplicateTransactionException
|
* @throws DuplicateTransactionException
|
||||||
* @throws FireflyException
|
* @throws FireflyException
|
||||||
|
* @throws \JsonException
|
||||||
*/
|
*/
|
||||||
public function create(array $data): TransactionGroup
|
public function create(array $data): TransactionGroup
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -417,6 +417,8 @@ class TransactionJournalFactory
|
|||||||
* @param Account $account
|
* @param Account $account
|
||||||
*
|
*
|
||||||
* @return TransactionCurrency
|
* @return TransactionCurrency
|
||||||
|
* @throws FireflyException
|
||||||
|
* @throws JsonException
|
||||||
*/
|
*/
|
||||||
private function getCurrency(?TransactionCurrency $currency, Account $account): TransactionCurrency
|
private function getCurrency(?TransactionCurrency $currency, Account $account): TransactionCurrency
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -52,7 +52,7 @@ class MonthReportGenerator implements ReportGeneratorInterface
|
|||||||
$reportType = 'account';
|
$reportType = 'account';
|
||||||
$preferredPeriod = $this->preferredPeriod();
|
$preferredPeriod = $this->preferredPeriod();
|
||||||
try {
|
try {
|
||||||
$result = prefixView('reports.double.report', compact('accountIds', 'reportType', 'doubleIds', 'preferredPeriod'))
|
$result = view('reports.double.report', compact('accountIds', 'reportType', 'doubleIds', 'preferredPeriod'))
|
||||||
->with('start', $this->start)->with('end', $this->end)
|
->with('start', $this->start)->with('end', $this->end)
|
||||||
->with('doubles', $this->expense)
|
->with('doubles', $this->expense)
|
||||||
->render();
|
->render();
|
||||||
@@ -64,6 +64,16 @@ class MonthReportGenerator implements ReportGeneratorInterface
|
|||||||
return $result;
|
return $result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the preferred period.
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
protected function preferredPeriod(): string
|
||||||
|
{
|
||||||
|
return 'day';
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set accounts.
|
* Set accounts.
|
||||||
*
|
*
|
||||||
@@ -155,14 +165,4 @@ class MonthReportGenerator implements ReportGeneratorInterface
|
|||||||
{
|
{
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Return the preferred period.
|
|
||||||
*
|
|
||||||
* @return string
|
|
||||||
*/
|
|
||||||
protected function preferredPeriod(): string
|
|
||||||
{
|
|
||||||
return 'day';
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -49,6 +49,8 @@ class MonthReportGenerator implements ReportGeneratorInterface
|
|||||||
* Generates the report.
|
* Generates the report.
|
||||||
*
|
*
|
||||||
* @return string
|
* @return string
|
||||||
|
* @throws FireflyException
|
||||||
|
* @throws JsonException
|
||||||
* @codeCoverageIgnore
|
* @codeCoverageIgnore
|
||||||
*/
|
*/
|
||||||
public function generate(): string
|
public function generate(): string
|
||||||
@@ -78,7 +80,7 @@ class MonthReportGenerator implements ReportGeneratorInterface
|
|||||||
'due_date', 'payment_date', 'invoice_date',
|
'due_date', 'payment_date', 'invoice_date',
|
||||||
];
|
];
|
||||||
try {
|
try {
|
||||||
$result = prefixView('reports.audit.report', compact('reportType', 'accountIds', 'auditData', 'hideable', 'defaultShow'))
|
$result = view('reports.audit.report', compact('reportType', 'accountIds', 'auditData', 'hideable', 'defaultShow'))
|
||||||
->with('start', $this->start)->with('end', $this->end)->with('accounts', $this->accounts)
|
->with('start', $this->start)->with('end', $this->end)->with('accounts', $this->accounts)
|
||||||
->render();
|
->render();
|
||||||
} catch (Throwable $e) { // @phpstan-ignore-line
|
} catch (Throwable $e) { // @phpstan-ignore-line
|
||||||
@@ -90,6 +92,80 @@ class MonthReportGenerator implements ReportGeneratorInterface
|
|||||||
return $result;
|
return $result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the audit report.
|
||||||
|
*
|
||||||
|
* @param Account $account
|
||||||
|
* @param Carbon $date
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
* @throws FireflyException
|
||||||
|
* @throws JsonException
|
||||||
|
*/
|
||||||
|
#[ArrayShape(['journals' => "array", 'currency' => "mixed", 'exists' => "bool", 'end' => "string", 'endBalance' => "mixed", 'dayBefore' => "string",
|
||||||
|
'dayBeforeBalance' => "mixed"])] public function getAuditReport(Account $account, Carbon $date): array
|
||||||
|
{
|
||||||
|
/** @var AccountRepositoryInterface $accountRepository */
|
||||||
|
$accountRepository = app(AccountRepositoryInterface::class);
|
||||||
|
$accountRepository->setUser($account->user);
|
||||||
|
|
||||||
|
/** @var JournalRepositoryInterface $journalRepository */
|
||||||
|
$journalRepository = app(JournalRepositoryInterface::class);
|
||||||
|
$journalRepository->setUser($account->user);
|
||||||
|
|
||||||
|
/** @var GroupCollectorInterface $collector */
|
||||||
|
$collector = app(GroupCollectorInterface::class);
|
||||||
|
$collector->setAccounts(new Collection([$account]))->setRange($this->start, $this->end)->withAccountInformation()
|
||||||
|
->withBudgetInformation()->withCategoryInformation()->withBillInformation();
|
||||||
|
$journals = $collector->getExtractedJournals();
|
||||||
|
$journals = array_reverse($journals, true);
|
||||||
|
$dayBeforeBalance = app('steam')->balance($account, $date);
|
||||||
|
$startBalance = $dayBeforeBalance;
|
||||||
|
$defaultCurrency = app('amount')->getDefaultCurrencyByUser($account->user);
|
||||||
|
$currency = $accountRepository->getAccountCurrency($account) ?? $defaultCurrency;
|
||||||
|
|
||||||
|
foreach ($journals as $index => $journal) {
|
||||||
|
$journals[$index]['balance_before'] = $startBalance;
|
||||||
|
$transactionAmount = $journal['amount'];
|
||||||
|
|
||||||
|
// make sure amount is in the right "direction".
|
||||||
|
if ($account->id === $journal['destination_account_id']) {
|
||||||
|
$transactionAmount = app('steam')->positive($journal['amount']);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($currency->id === $journal['foreign_currency_id']) {
|
||||||
|
$transactionAmount = $journal['foreign_amount'];
|
||||||
|
if ($account->id === $journal['destination_account_id']) {
|
||||||
|
$transactionAmount = app('steam')->positive($journal['foreign_amount']);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$newBalance = bcadd($startBalance, $transactionAmount);
|
||||||
|
$journals[$index]['balance_after'] = $newBalance;
|
||||||
|
$startBalance = $newBalance;
|
||||||
|
|
||||||
|
// add meta dates for each journal.
|
||||||
|
$journals[$index]['interest_date'] = $journalRepository->getMetaDateById($journal['transaction_journal_id'], 'interest_date');
|
||||||
|
$journals[$index]['book_date'] = $journalRepository->getMetaDateById($journal['transaction_journal_id'], 'book_date');
|
||||||
|
$journals[$index]['process_date'] = $journalRepository->getMetaDateById($journal['transaction_journal_id'], 'process_date');
|
||||||
|
$journals[$index]['due_date'] = $journalRepository->getMetaDateById($journal['transaction_journal_id'], 'due_date');
|
||||||
|
$journals[$index]['payment_date'] = $journalRepository->getMetaDateById($journal['transaction_journal_id'], 'payment_date');
|
||||||
|
$journals[$index]['invoice_date'] = $journalRepository->getMetaDateById($journal['transaction_journal_id'], 'invoice_date');
|
||||||
|
|
||||||
|
}
|
||||||
|
$locale = app('steam')->getLocale();
|
||||||
|
|
||||||
|
return [
|
||||||
|
'journals' => $journals,
|
||||||
|
'currency' => $currency,
|
||||||
|
'exists' => !empty($journals),
|
||||||
|
'end' => $this->end->isoFormat((string) trans('config.month_and_day_moment_js', [], $locale)),
|
||||||
|
'endBalance' => app('steam')->balance($account, $this->end),
|
||||||
|
'dayBefore' => $date->isoFormat((string) trans('config.month_and_day_moment_js', [], $locale)),
|
||||||
|
'dayBeforeBalance' => $dayBeforeBalance,
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Account collection setter.
|
* Account collection setter.
|
||||||
*
|
*
|
||||||
@@ -187,78 +263,4 @@ class MonthReportGenerator implements ReportGeneratorInterface
|
|||||||
{
|
{
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the audit report.
|
|
||||||
*
|
|
||||||
* @param Account $account
|
|
||||||
* @param Carbon $date
|
|
||||||
*
|
|
||||||
* @return array
|
|
||||||
* @throws FireflyException
|
|
||||||
* @throws JsonException
|
|
||||||
*/
|
|
||||||
#[ArrayShape(['journals' => "array", 'currency' => "mixed", 'exists' => "bool", 'end' => "string", 'endBalance' => "mixed", 'dayBefore' => "string",
|
|
||||||
'dayBeforeBalance' => "mixed"])] public function getAuditReport(Account $account, Carbon $date): array
|
|
||||||
{
|
|
||||||
/** @var AccountRepositoryInterface $accountRepository */
|
|
||||||
$accountRepository = app(AccountRepositoryInterface::class);
|
|
||||||
$accountRepository->setUser($account->user);
|
|
||||||
|
|
||||||
/** @var JournalRepositoryInterface $journalRepository */
|
|
||||||
$journalRepository = app(JournalRepositoryInterface::class);
|
|
||||||
$journalRepository->setUser($account->user);
|
|
||||||
|
|
||||||
/** @var GroupCollectorInterface $collector */
|
|
||||||
$collector = app(GroupCollectorInterface::class);
|
|
||||||
$collector->setAccounts(new Collection([$account]))->setRange($this->start, $this->end)->withAccountInformation()
|
|
||||||
->withBudgetInformation()->withCategoryInformation()->withBillInformation();
|
|
||||||
$journals = $collector->getExtractedJournals();
|
|
||||||
$journals = array_reverse($journals, true);
|
|
||||||
$dayBeforeBalance = app('steam')->balance($account, $date);
|
|
||||||
$startBalance = $dayBeforeBalance;
|
|
||||||
$defaultCurrency = app('amount')->getDefaultCurrencyByUser($account->user);
|
|
||||||
$currency = $accountRepository->getAccountCurrency($account) ?? $defaultCurrency;
|
|
||||||
|
|
||||||
foreach ($journals as $index => $journal) {
|
|
||||||
$journals[$index]['balance_before'] = $startBalance;
|
|
||||||
$transactionAmount = $journal['amount'];
|
|
||||||
|
|
||||||
// make sure amount is in the right "direction".
|
|
||||||
if ($account->id === $journal['destination_account_id']) {
|
|
||||||
$transactionAmount = app('steam')->positive($journal['amount']);
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($currency->id === $journal['foreign_currency_id']) {
|
|
||||||
$transactionAmount = $journal['foreign_amount'];
|
|
||||||
if ($account->id === $journal['destination_account_id']) {
|
|
||||||
$transactionAmount = app('steam')->positive($journal['foreign_amount']);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
$newBalance = bcadd($startBalance, $transactionAmount);
|
|
||||||
$journals[$index]['balance_after'] = $newBalance;
|
|
||||||
$startBalance = $newBalance;
|
|
||||||
|
|
||||||
// add meta dates for each journal.
|
|
||||||
$journals[$index]['interest_date'] = $journalRepository->getMetaDateById($journal['transaction_journal_id'], 'interest_date');
|
|
||||||
$journals[$index]['book_date'] = $journalRepository->getMetaDateById($journal['transaction_journal_id'], 'book_date');
|
|
||||||
$journals[$index]['process_date'] = $journalRepository->getMetaDateById($journal['transaction_journal_id'], 'process_date');
|
|
||||||
$journals[$index]['due_date'] = $journalRepository->getMetaDateById($journal['transaction_journal_id'], 'due_date');
|
|
||||||
$journals[$index]['payment_date'] = $journalRepository->getMetaDateById($journal['transaction_journal_id'], 'payment_date');
|
|
||||||
$journals[$index]['invoice_date'] = $journalRepository->getMetaDateById($journal['transaction_journal_id'], 'invoice_date');
|
|
||||||
|
|
||||||
}
|
|
||||||
$locale = app('steam')->getLocale();
|
|
||||||
|
|
||||||
return [
|
|
||||||
'journals' => $journals,
|
|
||||||
'currency' => $currency,
|
|
||||||
'exists' => !empty($journals),
|
|
||||||
'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', [], $locale)),
|
|
||||||
'dayBeforeBalance' => $dayBeforeBalance,
|
|
||||||
];
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -64,7 +64,7 @@ class MonthReportGenerator implements ReportGeneratorInterface
|
|||||||
$accountIds = implode(',', $this->accounts->pluck('id')->toArray());
|
$accountIds = implode(',', $this->accounts->pluck('id')->toArray());
|
||||||
$budgetIds = implode(',', $this->budgets->pluck('id')->toArray());
|
$budgetIds = implode(',', $this->budgets->pluck('id')->toArray());
|
||||||
try {
|
try {
|
||||||
$result = prefixView(
|
$result = view(
|
||||||
'reports.budget.month',
|
'reports.budget.month',
|
||||||
compact('accountIds', 'budgetIds')
|
compact('accountIds', 'budgetIds')
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -76,7 +76,7 @@ class MonthReportGenerator implements ReportGeneratorInterface
|
|||||||
|
|
||||||
// render!
|
// render!
|
||||||
try {
|
try {
|
||||||
return prefixView('reports.category.month', compact('accountIds', 'categoryIds', 'reportType'))
|
return view('reports.category.month', compact('accountIds', 'categoryIds', 'reportType'))
|
||||||
->with('start', $this->start)->with('end', $this->end)
|
->with('start', $this->start)->with('end', $this->end)
|
||||||
->with('categories', $this->categories)
|
->with('categories', $this->categories)
|
||||||
->with('accounts', $this->accounts)
|
->with('accounts', $this->accounts)
|
||||||
|
|||||||
@@ -53,7 +53,7 @@ class MonthReportGenerator implements ReportGeneratorInterface
|
|||||||
$reportType = 'default';
|
$reportType = 'default';
|
||||||
|
|
||||||
try {
|
try {
|
||||||
return prefixView('reports.default.month', compact('accountIds', 'reportType'))->with('start', $this->start)->with('end', $this->end)->render();
|
return view('reports.default.month', compact('accountIds', 'reportType'))->with('start', $this->start)->with('end', $this->end)->render();
|
||||||
} catch (Throwable $e) { // @phpstan-ignore-line
|
} catch (Throwable $e) { // @phpstan-ignore-line
|
||||||
Log::error(sprintf('Cannot render reports.default.month: %s', $e->getMessage()));
|
Log::error(sprintf('Cannot render reports.default.month: %s', $e->getMessage()));
|
||||||
$result = 'Could not render report view.';
|
$result = 'Could not render report view.';
|
||||||
|
|||||||
@@ -54,7 +54,7 @@ class MultiYearReportGenerator implements ReportGeneratorInterface
|
|||||||
$reportType = 'default';
|
$reportType = 'default';
|
||||||
|
|
||||||
try {
|
try {
|
||||||
return prefixView(
|
return view(
|
||||||
'reports.default.multi-year',
|
'reports.default.multi-year',
|
||||||
compact('accountIds', 'reportType')
|
compact('accountIds', 'reportType')
|
||||||
)->with('start', $this->start)->with('end', $this->end)->render();
|
)->with('start', $this->start)->with('end', $this->end)->render();
|
||||||
|
|||||||
@@ -54,7 +54,7 @@ class YearReportGenerator implements ReportGeneratorInterface
|
|||||||
$reportType = 'default';
|
$reportType = 'default';
|
||||||
|
|
||||||
try {
|
try {
|
||||||
$result = prefixView(
|
$result = view(
|
||||||
'reports.default.year',
|
'reports.default.year',
|
||||||
compact('accountIds', 'reportType')
|
compact('accountIds', 'reportType')
|
||||||
)->with('start', $this->start)->with('end', $this->end)->render();
|
)->with('start', $this->start)->with('end', $this->end)->render();
|
||||||
|
|||||||
@@ -75,7 +75,7 @@ class MonthReportGenerator implements ReportGeneratorInterface
|
|||||||
|
|
||||||
// render!
|
// render!
|
||||||
try {
|
try {
|
||||||
$result = prefixView(
|
$result = view(
|
||||||
'reports.tag.month',
|
'reports.tag.month',
|
||||||
compact('accountIds', 'reportType', 'tagIds')
|
compact('accountIds', 'reportType', 'tagIds')
|
||||||
)->with('start', $this->start)->with('end', $this->end)->with('tags', $this->tags)->with('accounts', $this->accounts)->render();
|
)->with('start', $this->start)->with('end', $this->end)->with('tags', $this->tags)->with('accounts', $this->accounts)->render();
|
||||||
|
|||||||
@@ -66,38 +66,6 @@ class StandardMessageGenerator implements MessageGeneratorInterface
|
|||||||
$this->run();
|
$this->run();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @inheritDoc
|
|
||||||
*/
|
|
||||||
public function getVersion(): int
|
|
||||||
{
|
|
||||||
return $this->version;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param Collection $objects
|
|
||||||
*/
|
|
||||||
public function setObjects(Collection $objects): void
|
|
||||||
{
|
|
||||||
$this->objects = $objects;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param int $trigger
|
|
||||||
*/
|
|
||||||
public function setTrigger(int $trigger): void
|
|
||||||
{
|
|
||||||
$this->trigger = $trigger;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param User $user
|
|
||||||
*/
|
|
||||||
public function setUser(User $user): void
|
|
||||||
{
|
|
||||||
$this->user = $user;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return Collection
|
* @return Collection
|
||||||
*/
|
*/
|
||||||
@@ -134,6 +102,8 @@ class StandardMessageGenerator implements MessageGeneratorInterface
|
|||||||
/**
|
/**
|
||||||
* @param Webhook $webhook
|
* @param Webhook $webhook
|
||||||
* @param Model $model
|
* @param Model $model
|
||||||
|
* @throws FireflyException
|
||||||
|
* @throws \JsonException
|
||||||
*/
|
*/
|
||||||
private function generateMessage(Webhook $webhook, Model $model): void
|
private function generateMessage(Webhook $webhook, Model $model): void
|
||||||
{
|
{
|
||||||
@@ -197,6 +167,14 @@ class StandardMessageGenerator implements MessageGeneratorInterface
|
|||||||
$this->storeMessage($webhook, $basicMessage);
|
$this->storeMessage($webhook, $basicMessage);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @inheritDoc
|
||||||
|
*/
|
||||||
|
public function getVersion(): int
|
||||||
|
{
|
||||||
|
return $this->version;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param TransactionGroup $transactionGroup
|
* @param TransactionGroup $transactionGroup
|
||||||
*
|
*
|
||||||
@@ -220,9 +198,9 @@ class StandardMessageGenerator implements MessageGeneratorInterface
|
|||||||
* @param Webhook $webhook
|
* @param Webhook $webhook
|
||||||
* @param array $message
|
* @param array $message
|
||||||
*
|
*
|
||||||
* @return WebhookMessage
|
* @return void
|
||||||
*/
|
*/
|
||||||
private function storeMessage(Webhook $webhook, array $message): WebhookMessage
|
private function storeMessage(Webhook $webhook, array $message): void
|
||||||
{
|
{
|
||||||
$webhookMessage = new WebhookMessage;
|
$webhookMessage = new WebhookMessage;
|
||||||
$webhookMessage->webhook()->associate($webhook);
|
$webhookMessage->webhook()->associate($webhook);
|
||||||
@@ -233,6 +211,29 @@ class StandardMessageGenerator implements MessageGeneratorInterface
|
|||||||
$webhookMessage->save();
|
$webhookMessage->save();
|
||||||
Log::debug(sprintf('Stored new webhook message #%d', $webhookMessage->id));
|
Log::debug(sprintf('Stored new webhook message #%d', $webhookMessage->id));
|
||||||
|
|
||||||
return $webhookMessage;
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param Collection $objects
|
||||||
|
*/
|
||||||
|
public function setObjects(Collection $objects): void
|
||||||
|
{
|
||||||
|
$this->objects = $objects;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param int $trigger
|
||||||
|
*/
|
||||||
|
public function setTrigger(int $trigger): void
|
||||||
|
{
|
||||||
|
$this->trigger = $trigger;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param User $user
|
||||||
|
*/
|
||||||
|
public function setUser(User $user): void
|
||||||
|
{
|
||||||
|
$this->user = $user;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -30,7 +30,6 @@ use FireflyIII\Repositories\User\UserRepositoryInterface;
|
|||||||
use Laravel\Passport\Events\AccessTokenCreated;
|
use Laravel\Passport\Events\AccessTokenCreated;
|
||||||
use Log;
|
use Log;
|
||||||
use Mail;
|
use Mail;
|
||||||
use Request;
|
|
||||||
use Session;
|
use Session;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -59,18 +58,16 @@ class APIEventHandler
|
|||||||
$email = config('firefly.site_owner');
|
$email = config('firefly.site_owner');
|
||||||
}
|
}
|
||||||
|
|
||||||
$ipAddress = Request::ip();
|
|
||||||
|
|
||||||
// see if user has alternative email address:
|
// see if user has alternative email address:
|
||||||
$pref = app('preferences')->getForUser($user, 'remote_guard_alt_email');
|
$pref = app('preferences')->getForUser($user, 'remote_guard_alt_email');
|
||||||
if (null !== $pref) {
|
if (null !== $pref) {
|
||||||
$email = (string) (is_array($pref->data) ? $email : $pref->data);
|
$email = (string) (is_array($pref->data) ? $email : $pref->data);
|
||||||
}
|
}
|
||||||
|
|
||||||
Log::debug(sprintf('Now in APIEventHandler::accessTokenCreated. Email is %s, IP is %s', $email, $ipAddress));
|
Log::debug(sprintf('Now in APIEventHandler::accessTokenCreated. Email is %s', $email));
|
||||||
try {
|
try {
|
||||||
Log::debug('Trying to send message...');
|
Log::debug('Trying to send message...');
|
||||||
Mail::to($email)->send(new AccessTokenCreatedMail($email, $ipAddress));
|
Mail::to($email)->send(new AccessTokenCreatedMail);
|
||||||
|
|
||||||
} catch (Exception $e) { // @phpstan-ignore-line
|
} catch (Exception $e) { // @phpstan-ignore-line
|
||||||
Log::debug('Send message failed! :(');
|
Log::debug('Send message failed! :(');
|
||||||
|
|||||||
@@ -52,7 +52,6 @@ class AdminEventHandler
|
|||||||
// is user even admin?
|
// is user even admin?
|
||||||
if ($repository->hasRole($event->user, 'owner')) {
|
if ($repository->hasRole($event->user, 'owner')) {
|
||||||
$email = $event->user->email;
|
$email = $event->user->email;
|
||||||
$ipAddress = $event->ipAddress;
|
|
||||||
|
|
||||||
// if user is demo user, send to owner:
|
// if user is demo user, send to owner:
|
||||||
if ($event->user->hasRole('demo')) {
|
if ($event->user->hasRole('demo')) {
|
||||||
@@ -65,10 +64,10 @@ class AdminEventHandler
|
|||||||
$email = $pref->data;
|
$email = $pref->data;
|
||||||
}
|
}
|
||||||
|
|
||||||
Log::debug(sprintf('Now in sendTestMessage event handler. Email is %s, IP is %s', $email, $ipAddress));
|
Log::debug(sprintf('Now in sendTestMessage event handler. Email is %s', $email));
|
||||||
try {
|
try {
|
||||||
Log::debug('Trying to send message...');
|
Log::debug('Trying to send message...');
|
||||||
Mail::to($email)->send(new AdminTestMail($email, $ipAddress));
|
Mail::to($email)->send(new AdminTestMail($email));
|
||||||
|
|
||||||
// Laravel cannot pretend this process failed during testing.
|
// Laravel cannot pretend this process failed during testing.
|
||||||
} catch (Exception $e) { // @phpstan-ignore-line
|
} catch (Exception $e) { // @phpstan-ignore-line
|
||||||
|
|||||||
@@ -43,7 +43,6 @@ class AutomationHandler
|
|||||||
* @param RequestedReportOnJournals $event
|
* @param RequestedReportOnJournals $event
|
||||||
*
|
*
|
||||||
* @return bool
|
* @return bool
|
||||||
* @throws FireflyException
|
|
||||||
*/
|
*/
|
||||||
public function reportJournals(RequestedReportOnJournals $event): bool
|
public function reportJournals(RequestedReportOnJournals $event): bool
|
||||||
{
|
{
|
||||||
@@ -58,23 +57,9 @@ class AutomationHandler
|
|||||||
$repository = app(UserRepositoryInterface::class);
|
$repository = app(UserRepositoryInterface::class);
|
||||||
$user = $repository->find($event->userId);
|
$user = $repository->find($event->userId);
|
||||||
if (null !== $user && 0 !== $event->groups->count()) {
|
if (null !== $user && 0 !== $event->groups->count()) {
|
||||||
|
|
||||||
$email = $user->email;
|
|
||||||
|
|
||||||
// see if user has alternative email address:
|
|
||||||
$pref = app('preferences')->getForUser($user, 'remote_guard_alt_email');
|
|
||||||
if (null !== $pref) {
|
|
||||||
$email = $pref->data;
|
|
||||||
}
|
|
||||||
|
|
||||||
// if user is demo user, send to owner:
|
|
||||||
if ($user->hasRole('demo')) {
|
|
||||||
$email = config('firefly.site_owner');
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
Log::debug('Trying to mail...');
|
Log::debug('Trying to mail...');
|
||||||
Mail::to($user->email)->send(new ReportNewJournalsMail($email, '127.0.0.1', $event->groups));
|
Mail::to($user->email)->send(new ReportNewJournalsMail($event->groups));
|
||||||
|
|
||||||
} catch (Exception $e) { // @phpstan-ignore-line
|
} catch (Exception $e) { // @phpstan-ignore-line
|
||||||
Log::debug('Send message failed! :(');
|
Log::debug('Send message failed! :(');
|
||||||
|
|||||||
64
app/Handlers/Events/BillEventHandler.php
Normal file
64
app/Handlers/Events/BillEventHandler.php
Normal file
@@ -0,0 +1,64 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
* BillEventHandler.php
|
||||||
|
* Copyright (c) 2022 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\Handlers\Events;
|
||||||
|
|
||||||
|
use FireflyIII\Events\WarnUserAboutBill;
|
||||||
|
use FireflyIII\Mail\BillWarningMail;
|
||||||
|
use Log;
|
||||||
|
use Mail;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class BillEventHandler
|
||||||
|
*/
|
||||||
|
class BillEventHandler
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @param WarnUserAboutBill $event
|
||||||
|
* @return void
|
||||||
|
* @throws \FireflyIII\Exceptions\FireflyException
|
||||||
|
*/
|
||||||
|
public function warnAboutBill(WarnUserAboutBill $event): void
|
||||||
|
{
|
||||||
|
$bill = $event->bill;
|
||||||
|
$field = $event->field;
|
||||||
|
$diff = $event->diff;
|
||||||
|
$user = $bill->user;
|
||||||
|
$address = $user->email;
|
||||||
|
$ipAddress = request()?->ip();
|
||||||
|
|
||||||
|
// see if user has alternative email address:
|
||||||
|
$pref = app('preferences')->getForUser($user, 'remote_guard_alt_email');
|
||||||
|
if (null !== $pref) {
|
||||||
|
$address = $pref->data;
|
||||||
|
}
|
||||||
|
|
||||||
|
// send message:
|
||||||
|
Mail::to($address)->send(new BillWarningMail($bill, $field, $diff, $ipAddress));
|
||||||
|
|
||||||
|
|
||||||
|
Log::debug('warnAboutBill');
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user