mirror of
https://github.com/firefly-iii/firefly-iii.git
synced 2026-01-08 03:21:20 +00:00
Compare commits
338 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
bc4ac303e2 | ||
|
|
0e9fbecbe4 | ||
|
|
226b3cfdd8 | ||
|
|
d43fa3790d | ||
|
|
ca04113aa7 | ||
|
|
817c157db4 | ||
|
|
07edbe758a | ||
|
|
46ba0a5a5a | ||
|
|
480b636c7e | ||
|
|
20340dff7b | ||
|
|
cfbabb500f | ||
|
|
a4cb2c1cb1 | ||
|
|
bd31b7e943 | ||
|
|
b2e7c767df | ||
|
|
bb9f763729 | ||
|
|
fb61229bf3 | ||
|
|
fc30d41ee5 | ||
|
|
7666147f3c | ||
|
|
52f8b24041 | ||
|
|
eaf2667abb | ||
|
|
de754ca4e0 | ||
|
|
96dd89fbeb | ||
|
|
bae40e2cbc | ||
|
|
6a647dab8b | ||
|
|
ebcf5b71d2 | ||
|
|
02370fb65d | ||
|
|
1e4f4907e3 | ||
|
|
13f72c73fb | ||
|
|
69b4632ef6 | ||
|
|
ede8c293fc | ||
|
|
0cfe991482 | ||
|
|
6377459e2f | ||
|
|
33fe6dbfa3 | ||
|
|
e158b9b64e | ||
|
|
dfa9e537b3 | ||
|
|
6d28ece616 | ||
|
|
59f4ecdaa6 | ||
|
|
10d953f336 | ||
|
|
5b771f7def | ||
|
|
4a8e3ee845 | ||
|
|
9a1f559dd2 | ||
|
|
62321a03ca | ||
|
|
40ca72c656 | ||
|
|
34fcff7a9d | ||
|
|
e1c829f4fa | ||
|
|
46136d94e9 | ||
|
|
0e2e8d1be5 | ||
|
|
1d1aa5dd3a | ||
|
|
0d82589916 | ||
|
|
4fc13037d2 | ||
|
|
3764499714 | ||
|
|
c4bbbc49b4 | ||
|
|
503158ab97 | ||
|
|
8c1d1d1db0 | ||
|
|
7dc72a2894 | ||
|
|
07cfba1b3a | ||
|
|
c55b80f467 | ||
|
|
2099da7142 | ||
|
|
ea125936e7 | ||
|
|
5de01628a6 | ||
|
|
2834aca597 | ||
|
|
88bab888d8 | ||
|
|
dfdbace298 | ||
|
|
a9590d2bb6 | ||
|
|
29a81eb05e | ||
|
|
20490fcd80 | ||
|
|
e775927f60 | ||
|
|
835a421909 | ||
|
|
850a0ae17e | ||
|
|
2b54363dd7 | ||
|
|
b174a06b86 | ||
|
|
d4096103cb | ||
|
|
3f493aceb2 | ||
|
|
05309da76d | ||
|
|
179f720806 | ||
|
|
7c34144ccd | ||
|
|
cc234b594d | ||
|
|
024cf610a8 | ||
|
|
a1896a6336 | ||
|
|
d30da7bf5d | ||
|
|
f8e914416d | ||
|
|
433da921bb | ||
|
|
4876053018 | ||
|
|
0c3a580b33 | ||
|
|
7689b7b4b0 | ||
|
|
21bff39e31 | ||
|
|
ba09901228 | ||
|
|
90bf2e58b2 | ||
|
|
004807aa32 | ||
|
|
35bacf2ad0 | ||
|
|
81d17409d4 | ||
|
|
a8080f55f0 | ||
|
|
379c540bd8 | ||
|
|
f319005357 | ||
|
|
df0e2dd2a2 | ||
|
|
219a0cd612 | ||
|
|
3ca3ce0726 | ||
|
|
566be8dc63 | ||
|
|
6bd4fa1c0a | ||
|
|
c767ee04f4 | ||
|
|
a5f89e0967 | ||
|
|
7355d14159 | ||
|
|
efd5ceb405 | ||
|
|
035dc8ceb4 | ||
|
|
11be33e942 | ||
|
|
e125254687 | ||
|
|
a2b997ba20 | ||
|
|
7327941c77 | ||
|
|
6c9eb1b699 | ||
|
|
60e262dece | ||
|
|
9c5463e515 | ||
|
|
6941176519 | ||
|
|
cb2c52cddb | ||
|
|
dd95776144 | ||
|
|
b95ca98be9 | ||
|
|
67b090b4d8 | ||
|
|
54b76a03ce | ||
|
|
cd6c727730 | ||
|
|
a35c6e29b6 | ||
|
|
95ce72fce7 | ||
|
|
a803dfc7fa | ||
|
|
c465d1c059 | ||
|
|
9914c0791e | ||
|
|
96baf5d3c7 | ||
|
|
a205367b62 | ||
|
|
6218fa90de | ||
|
|
51a770cfdc | ||
|
|
16fba15b5c | ||
|
|
ec2463a3ba | ||
|
|
b605ede74e | ||
|
|
b1b13d3696 | ||
|
|
51b11e5188 | ||
|
|
eefa84a77b | ||
|
|
5908b4b000 | ||
|
|
2ed433c96d | ||
|
|
9865800e39 | ||
|
|
4f697e77d5 | ||
|
|
c957aded98 | ||
|
|
aa0758cd2b | ||
|
|
0c2093753d | ||
|
|
136f983353 | ||
|
|
7943164375 | ||
|
|
32e58d0a60 | ||
|
|
bc807965ab | ||
|
|
477788658b | ||
|
|
723abf44bd | ||
|
|
fd1298d4d2 | ||
|
|
42f39536a1 | ||
|
|
6f0ac91bd2 | ||
|
|
6dea9156ab | ||
|
|
c5051b3e46 | ||
|
|
229d033e1a | ||
|
|
f494ba7065 | ||
|
|
201bc7db53 | ||
|
|
cd2a251f22 | ||
|
|
ff44ad4994 | ||
|
|
b496ca6a2c | ||
|
|
5908c0ce8c | ||
|
|
f7eef25fed | ||
|
|
049c93465a | ||
|
|
33294dd9f0 | ||
|
|
0a89f4000d | ||
|
|
422e80530b | ||
|
|
07a8c69ba8 | ||
|
|
5449879a7d | ||
|
|
8dbc846314 | ||
|
|
f0d3ca5d53 | ||
|
|
5af026674f | ||
|
|
2ebb4778cd | ||
|
|
bf3c57d26b | ||
|
|
cb9c87102f | ||
|
|
c73b003de4 | ||
|
|
771d448a7b | ||
|
|
de12db5f05 | ||
|
|
dd49926cc2 | ||
|
|
7a9ab190eb | ||
|
|
2290fcde22 | ||
|
|
ae85876965 | ||
|
|
f07d8e958f | ||
|
|
610af45dee | ||
|
|
138a5bc3fe | ||
|
|
427e9c5637 | ||
|
|
e3e8336602 | ||
|
|
194073e49a | ||
|
|
1af45aff73 | ||
|
|
56518ea028 | ||
|
|
c1ac2bb156 | ||
|
|
a004f27361 | ||
|
|
7843c55409 | ||
|
|
41da7d9f9a | ||
|
|
2add644706 | ||
|
|
dfd9cf0874 | ||
|
|
7ad09da4e9 | ||
|
|
8efbeb14d2 | ||
|
|
a1005d91df | ||
|
|
a681f1ce3c | ||
|
|
5a0714ca1a | ||
|
|
bd5c790043 | ||
|
|
2ae3cf79e4 | ||
|
|
fb122ba097 | ||
|
|
0c104cd86c | ||
|
|
a687f4ad68 | ||
|
|
228f42cf04 | ||
|
|
6d4956b574 | ||
|
|
0c7b652a70 | ||
|
|
d35470a79e | ||
|
|
719d610be3 | ||
|
|
07ae64693e | ||
|
|
0ccc1271a6 | ||
|
|
26fa2b0b74 | ||
|
|
6f64c19c32 | ||
|
|
e3e0e12fef | ||
|
|
0312ba8ad7 | ||
|
|
2ad8e7f343 | ||
|
|
d6298d9f05 | ||
|
|
89be30c4b9 | ||
|
|
6bcfea1de4 | ||
|
|
e8c9554dd6 | ||
|
|
02272f7db0 | ||
|
|
5a73e79475 | ||
|
|
7f4ecd40ce | ||
|
|
7c950c3022 | ||
|
|
dbf019135a | ||
|
|
e504ee82e5 | ||
|
|
780a15fe4f | ||
|
|
abb249643f | ||
|
|
086eccaf4a | ||
|
|
871033501a | ||
|
|
ccd727488f | ||
|
|
aa59d0f082 | ||
|
|
5d12f53283 | ||
|
|
59c005875a | ||
|
|
06d22e843a | ||
|
|
4fa5f4e5a3 | ||
|
|
67ea825d4a | ||
|
|
a616e06f9d | ||
|
|
b7752928a4 | ||
|
|
ca096852a5 | ||
|
|
ea2c48bca5 | ||
|
|
a722dc4235 | ||
|
|
dbbf0ff5e4 | ||
|
|
a941519db5 | ||
|
|
d4ba014a8a | ||
|
|
d193a6aec4 | ||
|
|
1f0fdf3da7 | ||
|
|
b705240faa | ||
|
|
662b832274 | ||
|
|
aed7e6d289 | ||
|
|
f7a1201d02 | ||
|
|
4d5bdd25a8 | ||
|
|
4a90ce35f2 | ||
|
|
02f5eddd14 | ||
|
|
5ca4f1b181 | ||
|
|
ec7ef3a813 | ||
|
|
49ff6febe5 | ||
|
|
2d66a9212f | ||
|
|
44fb307da4 | ||
|
|
cfc2181a48 | ||
|
|
cf4a846312 | ||
|
|
633b357d7b | ||
|
|
b96d67a54e | ||
|
|
5b83931b01 | ||
|
|
f22b54de30 | ||
|
|
a3306bb26f | ||
|
|
0adacac269 | ||
|
|
7359ed2ba2 | ||
|
|
5a5f4e8161 | ||
|
|
b886cc1333 | ||
|
|
9299efd086 | ||
|
|
1502aa3b20 | ||
|
|
73e32ecdcb | ||
|
|
ac8776aea4 | ||
|
|
7b41c5b301 | ||
|
|
369839e012 | ||
|
|
8fde16422e | ||
|
|
f1462dbd3d | ||
|
|
5dad569d62 | ||
|
|
c424bb097d | ||
|
|
e4b1760b20 | ||
|
|
780e365a78 | ||
|
|
3d1523a060 | ||
|
|
ff403dfa2e | ||
|
|
89834baf01 | ||
|
|
b8699422c8 | ||
|
|
6bc772d640 | ||
|
|
0712f30a51 | ||
|
|
9116796d90 | ||
|
|
a95fdb903b | ||
|
|
2ca6421206 | ||
|
|
cd076cc069 | ||
|
|
46482bdae1 | ||
|
|
5189c897be | ||
|
|
2c7d25d472 | ||
|
|
0da370c42d | ||
|
|
6f036d9120 | ||
|
|
260bbd79fd | ||
|
|
37ad6a3a62 | ||
|
|
aa25007431 | ||
|
|
8b33ec1339 | ||
|
|
cede11ecea | ||
|
|
2b4088c5f7 | ||
|
|
d872484607 | ||
|
|
f3f2160d96 | ||
|
|
bcdb849b46 | ||
|
|
5846431b34 | ||
|
|
0217d9396a | ||
|
|
c99e233026 | ||
|
|
f670d930f3 | ||
|
|
0237d78f61 | ||
|
|
5665f127aa | ||
|
|
76386dad7d | ||
|
|
42072fdda4 | ||
|
|
fc80f828be | ||
|
|
d05a1e0260 | ||
|
|
b315882f58 | ||
|
|
2f2f907ffe | ||
|
|
10492e3b2f | ||
|
|
8e08ff2d39 | ||
|
|
e78a59a8a8 | ||
|
|
cbe47a9dcc | ||
|
|
a1056147d8 | ||
|
|
8692590600 | ||
|
|
57345113b5 | ||
|
|
52f02cb9eb | ||
|
|
5d4dcd7e4b | ||
|
|
7d1f4d8907 | ||
|
|
a76241c7ba | ||
|
|
bdc6678341 | ||
|
|
c99b7e927d | ||
|
|
1675a0d442 | ||
|
|
c0d2cd8962 | ||
|
|
146c9fd947 | ||
|
|
666e9897ea | ||
|
|
81d70bd811 | ||
|
|
f6f8bb7fd1 | ||
|
|
7c3aaf7b7c | ||
|
|
32ea28f783 | ||
|
|
17f365941b |
11
.deploy/docker/cronjob.conf
Normal file
11
.deploy/docker/cronjob.conf
Normal file
@@ -0,0 +1,11 @@
|
||||
[program:cron]
|
||||
command=/usr/sbin/cron -f -L 15
|
||||
user=root
|
||||
autostart=true
|
||||
autorestart=true
|
||||
stdout_events_enabled=true
|
||||
stderr_events_enabled=true
|
||||
stdout_logfile=/dev/stdout
|
||||
stdout_logfile_maxbytes=0
|
||||
startsecs=10
|
||||
startretries=3
|
||||
@@ -16,14 +16,14 @@ mkdir -p $FIREFLY_PATH/storage/upload
|
||||
|
||||
|
||||
# make sure we own the volumes:
|
||||
chown -R www-data:www-data -R $FIREFLY_PATH/storage/export $FIREFLY_PATH/storage/upload $FIREFLY_PATH/storage/logs $FIREFLY_PATH/storage/framework/cache
|
||||
chmod -R 775 $FIREFLY_PATH/storage/export $FIREFLY_PATH/storage/upload $FIREFLY_PATH/storage/upload $FIREFLY_PATH/storage/logs $FIREFLY_PATH/storage/framework/cache
|
||||
chown -R www-data:www-data -R $FIREFLY_PATH/storage
|
||||
chmod -R 775 $FIREFLY_PATH/storage
|
||||
|
||||
# remove any lingering files that may break upgrades:
|
||||
rm -f $FIREFLY_PATH/storage/logs/laravel.log
|
||||
|
||||
cat .env.docker | envsubst > .env && cat .env
|
||||
cat .env.docker | envsubst > .env
|
||||
composer dump-autoload
|
||||
php artisan package:discover
|
||||
php artisan firefly:instructions install
|
||||
exec apache2-foreground
|
||||
exec /usr/bin/supervisord -c /etc/supervisor/supervisord.conf --nodaemon
|
||||
6
.deploy/docker/firefly-iii.conf
Normal file
6
.deploy/docker/firefly-iii.conf
Normal file
@@ -0,0 +1,6 @@
|
||||
[program:apache2]
|
||||
command=/bin/bash -c "source /etc/apache2/envvars && exec /usr/sbin/apache2 -DFOREGROUND"
|
||||
stdout_events_enabled=true
|
||||
stderr_events_enabled=true
|
||||
stdout_logfile=/dev/stdout
|
||||
stdout_logfile_maxbytes=0
|
||||
30
.deploy/docker/supervisord.conf
Normal file
30
.deploy/docker/supervisord.conf
Normal file
@@ -0,0 +1,30 @@
|
||||
# supervisor config file
|
||||
# Adapted from the config file distributed with the supervisor package on Debian
|
||||
# Jessie
|
||||
|
||||
# Enable supervisord in non-daemon mode. Disable the logfile as we receive
|
||||
# log messages via stdout/err. Set up the child process log directory in case
|
||||
# the user doesn't set logging to stdout/err.
|
||||
[supervisord]
|
||||
nodaemon = true
|
||||
logfile = NONE
|
||||
pidfile = /var/run/supervisord.pid
|
||||
childlogdir = /var/log/supervisor
|
||||
loglevel=debug
|
||||
|
||||
# Enable supervisorctl via RPC interface over Unix socket
|
||||
[unix_http_server]
|
||||
file = /var/run/supervisor.sock
|
||||
chmod = 0700
|
||||
|
||||
[rpcinterface:supervisor]
|
||||
supervisor.rpcinterface_factory = supervisor.rpcinterface:make_main_rpcinterface
|
||||
|
||||
[supervisorctl]
|
||||
serverurl = unix:///var/run/supervisor.sock
|
||||
|
||||
|
||||
# Include conf files for child processes
|
||||
# Debian/Ubuntu packages use /etc/supervisor/conf.d
|
||||
[include]
|
||||
files = /etc/supervisor/conf.d/*.conf
|
||||
26
.deploy/docker/vhost.conf
Normal file
26
.deploy/docker/vhost.conf
Normal file
@@ -0,0 +1,26 @@
|
||||
server {
|
||||
listen 80 default_server;
|
||||
|
||||
server_name _ *.vm docker;
|
||||
|
||||
root "/app/public";
|
||||
index index.php;
|
||||
|
||||
include /opt/docker/etc/nginx/vhost.common.d/*.conf;
|
||||
}
|
||||
|
||||
##############
|
||||
# SSL
|
||||
##############
|
||||
|
||||
server {
|
||||
listen 443 default_server;
|
||||
|
||||
server_name _ *.vm docker;
|
||||
|
||||
root "/app/public";
|
||||
index index.php;
|
||||
|
||||
include /opt/docker/etc/nginx/vhost.common.d/*.conf;
|
||||
include /opt/docker/etc/nginx/vhost.ssl.conf;
|
||||
}
|
||||
@@ -1,4 +1,3 @@
|
||||
# Ignore composer specific files and vendor folder
|
||||
composer.phar
|
||||
composer.lock
|
||||
vendor
|
||||
|
||||
36
.env.docker
36
.env.docker
@@ -13,15 +13,31 @@ SITE_OWNER=${SITE_OWNER}
|
||||
# Change it to a string of exactly 32 chars or use command `php artisan key:generate` to generate it
|
||||
APP_KEY=${FF_APP_KEY}
|
||||
|
||||
# APP_URL and TRUSTED_PROXIES are useful when using Docker and/or a reverse proxy.
|
||||
# Change this value to your preferred time zone.
|
||||
# Example: Europe/Amsterdam
|
||||
TZ=${TZ}
|
||||
|
||||
# This variable must match your installation's external address but keep in mind that
|
||||
# it's only used on the command line as a fallback value.
|
||||
APP_URL=${APP_URL}
|
||||
|
||||
# TRUSTED_PROXIES is a useful variable when using Docker and/or a reverse proxy.
|
||||
TRUSTED_PROXIES=${TRUSTED_PROXIES}
|
||||
|
||||
# The log channel defines where your log entries go to.
|
||||
LOG_CHANNEL=${LOG_CHANNEL}
|
||||
# 'daily' is the default logging mode giving you 5 daily rotated log files in /storage/logs/.
|
||||
# Several other options exist. You can use 'single' for one big fat error log (not recommended).
|
||||
# Also available are 'syslog', 'errorlog' and 'stdout' which will log to the system itself.
|
||||
LOG_CHANNEL=stdout
|
||||
|
||||
# Log level. You can set this from least severe to most severe:
|
||||
# debug, info, notice, warning, error, critical, alert, emergency
|
||||
# If you set it to debug your logs will grow large, and fast. If you set it to emergency probably
|
||||
# nothing will get logged, ever.
|
||||
APP_LOG_LEVEL=${APP_LOG_LEVEL}
|
||||
|
||||
# Database credentials. Make sure the database exists. I recommend a dedicated user for Firefly III
|
||||
# If you use SQLite, set connection to `sqlite` and remove the database, username and password settings.
|
||||
# For other database types, please see the FAQ: http://firefly-iii.readthedocs.io/en/latest/support/faq.html
|
||||
DB_CONNECTION=${FF_DB_CONNECTION}
|
||||
DB_HOST=${FF_DB_HOST}
|
||||
DB_PORT=${FF_DB_PORT}
|
||||
@@ -29,17 +45,6 @@ DB_DATABASE=${FF_DB_NAME}
|
||||
DB_USERNAME=${FF_DB_USER}
|
||||
DB_PASSWORD=${FF_DB_PASSWORD}
|
||||
|
||||
# 'daily' is the default logging mode giving you 5 daily rotated log files in /storage/logs/.
|
||||
# Several other options exist. You can use 'single' for one big fat error log (not recommended).
|
||||
# Also available are 'syslog' and 'errorlog' which will log to the system itself.
|
||||
APP_LOG=syslog
|
||||
|
||||
# Log level. You can set this from least severe to most severe:
|
||||
# debug, info, notice, warning, error, critical, alert, emergency
|
||||
# If you set it to debug your logs will grow large, and fast. If you set it to emergency probably
|
||||
# nothing will get logged, ever.
|
||||
APP_LOG_LEVEL=info
|
||||
|
||||
# If you're looking for performance improvements, you could install memcached.
|
||||
CACHE_DRIVER=file
|
||||
SESSION_DRIVER=file
|
||||
@@ -103,4 +108,5 @@ IS_DOCKER=true
|
||||
IS_SANDSTORM=false
|
||||
IS_HEROKU=false
|
||||
BUNQ_USE_SANDBOX=false
|
||||
TZ=${TZ}
|
||||
MAILGUN_DOMAIN=
|
||||
MAILGUN_SECRET=
|
||||
|
||||
29
.env.example
29
.env.example
@@ -15,15 +15,27 @@ APP_KEY=SomeRandomStringOf32CharsExactly
|
||||
|
||||
# Change this value to your preferred time zone.
|
||||
# Example: Europe/Amsterdam
|
||||
TZ=UTC
|
||||
TZ=Europe/Amsterdam
|
||||
|
||||
# APP_URL and TRUSTED_PROXIES are useful when using Docker and/or a reverse proxy.
|
||||
# This variable must match your installation's external address but keep in mind that
|
||||
# it's only used on the command line as a fallback value.
|
||||
APP_URL=http://localhost
|
||||
|
||||
# TRUSTED_PROXIES is a useful variable when using Docker and/or a reverse proxy.
|
||||
TRUSTED_PROXIES=
|
||||
|
||||
# The log channel defines where your log entries go to.
|
||||
# 'daily' is the default logging mode giving you 5 daily rotated log files in /storage/logs/.
|
||||
# Several other options exist. You can use 'single' for one big fat error log (not recommended).
|
||||
# Also available are 'syslog', 'errorlog' and 'stdout' which will log to the system itself.
|
||||
LOG_CHANNEL=daily
|
||||
|
||||
# Log level. You can set this from least severe to most severe:
|
||||
# debug, info, notice, warning, error, critical, alert, emergency
|
||||
# If you set it to debug your logs will grow large, and fast. If you set it to emergency probably
|
||||
# nothing will get logged, ever.
|
||||
APP_LOG_LEVEL=notice
|
||||
|
||||
# Database credentials. Make sure the database exists. I recommend a dedicated user for Firefly III
|
||||
# For other database types, please see the FAQ: http://firefly-iii.readthedocs.io/en/latest/support/faq.html
|
||||
DB_CONNECTION=mysql
|
||||
@@ -33,17 +45,6 @@ DB_DATABASE=homestead
|
||||
DB_USERNAME=homestead
|
||||
DB_PASSWORD=secret
|
||||
|
||||
# 'daily' is the default logging mode giving you 5 daily rotated log files in /storage/logs/.
|
||||
# Several other options exist. You can use 'single' for one big fat error log (not recommended).
|
||||
# Also available are 'syslog' and 'errorlog' which will log to the system itself.
|
||||
APP_LOG=daily
|
||||
|
||||
# Log level. You can set this from least severe to most severe:
|
||||
# debug, info, notice, warning, error, critical, alert, emergency
|
||||
# If you set it to debug your logs will grow large, and fast. If you set it to emergency probably
|
||||
# nothing will get logged, ever.
|
||||
APP_LOG_LEVEL=notice
|
||||
|
||||
# If you're looking for performance improvements, you could install memcached.
|
||||
CACHE_DRIVER=file
|
||||
SESSION_DRIVER=file
|
||||
@@ -105,7 +106,7 @@ DEMO_USERNAME=
|
||||
DEMO_PASSWORD=
|
||||
IS_DOCKER=false
|
||||
IS_SANDSTORM=false
|
||||
BUNQ_USE_SANDBOX=false
|
||||
IS_HEROKU=false
|
||||
BUNQ_USE_SANDBOX=false
|
||||
MAILGUN_DOMAIN=
|
||||
MAILGUN_SECRET=
|
||||
|
||||
31
.env.heroku
31
.env.heroku
@@ -17,12 +17,24 @@ APP_KEY=7ahyYVPVsmxjdhsweWCauGeJfwc92NP2
|
||||
# Example: Europe/Amsterdam
|
||||
TZ=UTC
|
||||
|
||||
# APP_URL and TRUSTED_PROXIES are useful when using Docker and/or a reverse proxy.
|
||||
# This variable must match your installation's external address but keep in mind that
|
||||
# it's only used on the command line as a fallback value.
|
||||
APP_URL=http://localhost
|
||||
TRUSTED_PROXIES=
|
||||
|
||||
# TRUSTED_PROXIES is a useful variable when using Docker and/or a reverse proxy.
|
||||
TRUSTED_PROXIES=**
|
||||
|
||||
# The log channel defines where your log entries go to.
|
||||
LOG_CHANNEL=syslog
|
||||
# 'daily' is the default logging mode giving you 5 daily rotated log files in /storage/logs/.
|
||||
# Several other options exist. You can use 'single' for one big fat error log (not recommended).
|
||||
# Also available are 'syslog', 'errorlog' and 'stdout' which will log to the system itself.
|
||||
LOG_CHANNEL=stdout
|
||||
|
||||
# Log level. You can set this from least severe to most severe:
|
||||
# debug, info, notice, warning, error, critical, alert, emergency
|
||||
# If you set it to debug your logs will grow large, and fast. If you set it to emergency probably
|
||||
# nothing will get logged, ever.
|
||||
APP_LOG_LEVEL=debug
|
||||
|
||||
# Database credentials. Make sure the database exists. I recommend a dedicated user for Firefly III
|
||||
# If you use SQLite, set connection to `sqlite` and remove the database, username and password settings.
|
||||
@@ -33,17 +45,6 @@ DB_CONNECTION=pgsql
|
||||
|
||||
|
||||
|
||||
# 'daily' is the default logging mode giving you 5 daily rotated log files in /storage/logs/.
|
||||
# Several other options exist. You can use 'single' for one big fat error log (not recommended).
|
||||
# Also available are 'syslog' and 'errorlog' which will log to the system itself.
|
||||
APP_LOG=errorlog
|
||||
|
||||
# Log level. You can set this from least severe to most severe:
|
||||
# debug, info, notice, warning, error, critical, alert, emergency
|
||||
# If you set it to debug your logs will grow large, and fast. If you set it to emergency probably
|
||||
# nothing will get logged, ever.
|
||||
APP_LOG_LEVEL=debug
|
||||
|
||||
# If you're looking for performance improvements, you could install memcached.
|
||||
CACHE_DRIVER=file
|
||||
SESSION_DRIVER=file
|
||||
@@ -105,7 +106,7 @@ DEMO_USERNAME=
|
||||
DEMO_PASSWORD=
|
||||
IS_DOCKER=false
|
||||
IS_SANDSTORM=false
|
||||
BUNQ_USE_SANDBOX=false
|
||||
IS_HEROKU=true
|
||||
BUNQ_USE_SANDBOX=false
|
||||
MAILGUN_DOMAIN=
|
||||
MAILGUN_SECRET=
|
||||
|
||||
@@ -17,12 +17,24 @@ APP_KEY=SomeRandomStringOf32CharsExactly
|
||||
# Example: Europe/Amsterdam
|
||||
TZ=UTC
|
||||
|
||||
# APP_URL and TRUSTED_PROXIES are useful when using Docker and/or a reverse proxy.
|
||||
# This variable must match your installation's external address but keep in mind that
|
||||
# it's only used on the command line as a fallback value.
|
||||
APP_URL=http://localhost
|
||||
|
||||
# TRUSTED_PROXIES is a useful variable when using Docker and/or a reverse proxy.
|
||||
TRUSTED_PROXIES=
|
||||
|
||||
# The log channel defines where your log entries go to.
|
||||
LOG_CHANNEL=syslog
|
||||
# 'daily' is the default logging mode giving you 5 daily rotated log files in /storage/logs/.
|
||||
# Several other options exist. You can use 'single' for one big fat error log (not recommended).
|
||||
# Also available are 'syslog', 'errorlog' and 'stdout' which will log to the system itself.
|
||||
LOG_CHANNEL=stdout
|
||||
|
||||
# Log level. You can set this from least severe to most severe:
|
||||
# debug, info, notice, warning, error, critical, alert, emergency
|
||||
# If you set it to debug your logs will grow large, and fast. If you set it to emergency probably
|
||||
# nothing will get logged, ever.
|
||||
APP_LOG_LEVEL=debug
|
||||
|
||||
# Database credentials. Make sure the database exists. I recommend a dedicated user for Firefly III
|
||||
# If you use SQLite, set connection to `sqlite` and remove the database, username and password settings.
|
||||
@@ -33,17 +45,6 @@ DB_DATABASE=firefly
|
||||
DB_USERNAME=firefly
|
||||
DB_PASSWORD=firefly
|
||||
|
||||
# 'daily' is the default logging mode giving you 5 daily rotated log files in /storage/logs/.
|
||||
# Several other options exist. You can use 'single' for one big fat error log (not recommended).
|
||||
# Also available are 'syslog' and 'errorlog' which will log to the system itself.
|
||||
APP_LOG=syslog
|
||||
|
||||
# Log level. You can set this from least severe to most severe:
|
||||
# debug, info, notice, warning, error, critical, alert, emergency
|
||||
# If you set it to debug your logs will grow large, and fast. If you set it to emergency probably
|
||||
# nothing will get logged, ever.
|
||||
APP_LOG_LEVEL=info
|
||||
|
||||
# If you're looking for performance improvements, you could install memcached.
|
||||
CACHE_DRIVER=file
|
||||
SESSION_DRIVER=file
|
||||
@@ -105,7 +106,7 @@ DEMO_USERNAME=
|
||||
DEMO_PASSWORD=
|
||||
IS_DOCKER=false
|
||||
IS_SANDSTORM=true
|
||||
BUNQ_USE_SANDBOX=false
|
||||
IS_HEROKU=false
|
||||
BUNQ_USE_SANDBOX=false
|
||||
MAILGUN_DOMAIN=
|
||||
MAILGUN_SECRET=
|
||||
|
||||
31
.env.testing
31
.env.testing
@@ -17,27 +17,33 @@ APP_KEY=TestTestTestTestTestTestTestTest
|
||||
# Example: Europe/Amsterdam
|
||||
TZ=Europe/Amsterdam
|
||||
|
||||
# APP_URL and TRUSTED_PROXIES are useful when using Docker and/or a reverse proxy.
|
||||
# This variable must match your installation's external address but keep in mind that
|
||||
# it's only used on the command line as a fallback value.
|
||||
APP_URL=http://localhost
|
||||
|
||||
# TRUSTED_PROXIES is a useful variable when using Docker and/or a reverse proxy.
|
||||
TRUSTED_PROXIES=
|
||||
|
||||
# The log channel defines where your log entries go to.
|
||||
LOG_CHANNEL=dailytest
|
||||
|
||||
# Database credentials. Make sure the database exists. I recommend a dedicated user for Firefly III
|
||||
# For other database types, please see the FAQ: http://firefly-iii.readthedocs.io/en/latest/support/faq.html
|
||||
DB_CONNECTION=sqlite
|
||||
|
||||
# 'daily' is the default logging mode giving you 5 daily rotated log files in /storage/logs/.
|
||||
# Several other options exist. You can use 'single' for one big fat error log (not recommended).
|
||||
# Also available are 'syslog' and 'errorlog' which will log to the system itself.
|
||||
APP_LOG=daily
|
||||
# Also available are 'syslog', 'errorlog' and 'stdout' which will log to the system itself.
|
||||
LOG_CHANNEL=dailytest
|
||||
|
||||
# Log level. You can set this from least severe to most severe:
|
||||
# debug, info, notice, warning, error, critical, alert, emergency
|
||||
# If you set it to debug your logs will grow large, and fast. If you set it to emergency probably
|
||||
# nothing will get logged, ever.
|
||||
APP_LOG_LEVEL=debug
|
||||
APP_LOG_LEVEL=info
|
||||
|
||||
# Database credentials. Make sure the database exists. I recommend a dedicated user for Firefly III
|
||||
# For other database types, please see the FAQ: http://firefly-iii.readthedocs.io/en/latest/support/faq.html
|
||||
DB_CONNECTION=sqlite
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# If you're looking for performance improvements, you could install memcached.
|
||||
CACHE_DRIVER=file
|
||||
@@ -64,6 +70,9 @@ MAILGUN_SECRET=
|
||||
MANDRILL_SECRET=
|
||||
SPARKPOST_SECRET=
|
||||
|
||||
# Firefly III can send you the following messages
|
||||
SEND_REGISTRATION_MAIL=true
|
||||
SEND_ERROR_MESSAGE=false
|
||||
|
||||
# Set a Mapbox API key here (see mapbox.com) so there might be a map available at various places.
|
||||
MAPBOX_API_KEY=
|
||||
@@ -97,7 +106,7 @@ DEMO_USERNAME=
|
||||
DEMO_PASSWORD=
|
||||
IS_DOCKER=false
|
||||
IS_SANDSTORM=false
|
||||
BUNQ_USE_SANDBOX=true
|
||||
IS_HEROKU=false
|
||||
BUNQ_USE_SANDBOX=true
|
||||
MAILGUN_DOMAIN=
|
||||
MAILGUN_SECRET=
|
||||
|
||||
9
.sandstorm/Vagrantfile
vendored
9
.sandstorm/Vagrantfile
vendored
@@ -9,9 +9,16 @@ VM_NAME = File.basename(File.dirname(File.dirname(__FILE__))) + "_sandstorm_#{Ti
|
||||
# Vagrantfile API/syntax version. Don't touch unless you know what you're doing!
|
||||
VAGRANTFILE_API_VERSION = "2"
|
||||
|
||||
# ugly hack to prevent hashicorp's bitrot. See https://github.com/hashicorp/vagrant/issues/9442
|
||||
# this setting is required for pre-2.0 vagrant, but causes an error as of 2.0.3,
|
||||
# remove entirely when confident nobody uses vagrant 1.x for anything.
|
||||
unless Vagrant::DEFAULT_SERVER_URL.frozen?
|
||||
Vagrant::DEFAULT_SERVER_URL.replace('https://vagrantcloud.com')
|
||||
end
|
||||
|
||||
Vagrant.configure(VAGRANTFILE_API_VERSION) do |config|
|
||||
# Base on the Sandstorm snapshots of the official Debian 8 (jessie) box.
|
||||
config.vm.box = "sandstorm/debian-jessie64"
|
||||
config.vm.box = "debian/contrib-jessie64"
|
||||
|
||||
if Vagrant.has_plugin?("vagrant-vbguest") then
|
||||
# vagrant-vbguest is a Vagrant plugin that upgrades
|
||||
|
||||
@@ -1,3 +1,78 @@
|
||||
# 4.7.6.2
|
||||
- Docker file builds again.
|
||||
- Fix CSS of OAuth2 authorization view.
|
||||
|
||||
# 4.7.6.1
|
||||
- An issue where I switched variables from the Docker `.env` file to the normal `.env` file and vice versa -- breaking both.
|
||||
- [Issue 1649](https://github.com/firefly-iii/firefly-iii/issues/1649) 2FA QR code would not show up due to very strict security policy headers
|
||||
- Docker build gave a cURL error whenever it runs PHP commands.
|
||||
|
||||
# 4.7.6
|
||||
- [Issue 145](https://github.com/firefly-iii/firefly-iii/issues/145) You can now download transactions from YNAB.
|
||||
- [Issue 306](https://github.com/firefly-iii/firefly-iii/issues/306) You can now add liabilities to Firefly III.
|
||||
- [Issue 740](https://github.com/firefly-iii/firefly-iii/issues/740) Various charts are now currency aware.
|
||||
- [Issue 833](https://github.com/firefly-iii/firefly-iii/issues/833) Bills can use non-default currencies.
|
||||
- [Issue 1578](https://github.com/firefly-iii/firefly-iii/issues/1578) Firefly III will notify you if the cron job hasn't fired.
|
||||
- [Issue 1623](https://github.com/firefly-iii/firefly-iii/issues/1623) New transactions will link back from the success message.
|
||||
- [Issue 1624](https://github.com/firefly-iii/firefly-iii/issues/1624) transactions will link to the object.
|
||||
- You can call the cron job over the web now (see docs).
|
||||
- You don't need to call the cron job every minute any more.
|
||||
- Various charts are now red/green to signify income and expenses.
|
||||
- Option to add or remove accounts from the net worth calculations.
|
||||
- This will be the last release on PHP 7.1. Future versions will require PHP 7.2.
|
||||
- [Issue 1460](https://github.com/firefly-iii/firefly-iii/issues/1460) Downloading transactions from bunq should go more smoothly.
|
||||
- [Issue 1464](https://github.com/firefly-iii/firefly-iii/issues/1464) Fixed the docker file to work on Raspberry Pi's.
|
||||
- [Issue 1540](https://github.com/firefly-iii/firefly-iii/issues/1540) The Docker file now has a working cron job for recurring transactions.
|
||||
- [Issue 1564](https://github.com/firefly-iii/firefly-iii/issues/1564) Fix double transfers when importing from bunq.
|
||||
- [Issue 1575](https://github.com/firefly-iii/firefly-iii/issues/1575) Some views would give a XSRF token warning
|
||||
- [Issue 1576](https://github.com/firefly-iii/firefly-iii/issues/1576) Fix assigning budgets
|
||||
- [Issue 1580](https://github.com/firefly-iii/firefly-iii/issues/1580) Missing string for translation
|
||||
- [Issue 1581](https://github.com/firefly-iii/firefly-iii/issues/1581) Expand help text
|
||||
- [Issue 1584](https://github.com/firefly-iii/firefly-iii/issues/1584) Link to administration is back.
|
||||
- [Issue 1586](https://github.com/firefly-iii/firefly-iii/issues/1586) Date fields in import were mislabeled.
|
||||
- [Issue 1593](https://github.com/firefly-iii/firefly-iii/issues/1593) Link types are translatable.
|
||||
- [Issue 1594](https://github.com/firefly-iii/firefly-iii/issues/1594) Very long breadcrumbs are weird.
|
||||
- [Issue 1598](https://github.com/firefly-iii/firefly-iii/issues/1598) Fix budget calculations.
|
||||
- [Issue 1597](https://github.com/firefly-iii/firefly-iii/issues/1597) Piggy banks are always inactive.
|
||||
- [Issue 1605](https://github.com/firefly-iii/firefly-iii/issues/1605) System will ignore foreign currency setting if user doesn't indicate the amount.
|
||||
- [Issue 1608](https://github.com/firefly-iii/firefly-iii/issues/1608) Spelling error in command line import.
|
||||
- [Issue 1609](https://github.com/firefly-iii/firefly-iii/issues/1609) Link to budgets page was absolute.
|
||||
- [Issue 1615](https://github.com/firefly-iii/firefly-iii/issues/1615) Fix currency bug in transactions.
|
||||
- [Issue 1616](https://github.com/firefly-iii/firefly-iii/issues/1616) Fix null pointer exception in pie charts.
|
||||
- [Issue 1617](https://github.com/firefly-iii/firefly-iii/issues/1617) Fix for complex tag names in URL's.
|
||||
- [Issue 1620](https://github.com/firefly-iii/firefly-iii/issues/1620) Fixed index reference in API.
|
||||
- [Issue 1639](https://github.com/firefly-iii/firefly-iii/issues/1639) Firefly III trusts the Heroku load balancer, fixing deployment on Heroku.
|
||||
- [Issue 1642](https://github.com/firefly-iii/firefly-iii/issues/1642) Fix issue with split journals.
|
||||
- [Issue 1643](https://github.com/firefly-iii/firefly-iii/issues/1643) Fix reconciliation issue.
|
||||
- Users can no longer give expenses a budget.
|
||||
- Fix bug in Spectre import.
|
||||
- Heroku would not make you owner.
|
||||
- Add `.htaccess` files to all public directories.
|
||||
- New secure headers will make Firefly III slightly more secure.
|
||||
|
||||
# 4.7.5.3
|
||||
- [Issue 1527](https://github.com/firefly-iii/firefly-iii/issues/1527), fixed views for transactions without a budget.
|
||||
- [Issue 1553](https://github.com/firefly-iii/firefly-iii/issues/1553), report could not handle transactions before the first one in the system.
|
||||
- [Issue 1549](https://github.com/firefly-iii/firefly-iii/issues/1549) update a budget will also update any rules that refer to that budget.
|
||||
- [Issue 1530](https://github.com/firefly-iii/firefly-iii/issues/1530), fix issue with bill chart.
|
||||
- [Issue 1563](https://github.com/firefly-iii/firefly-iii/issues/1563), fix piggy bank suggested amount
|
||||
- [Issue 1571](https://github.com/firefly-iii/firefly-iii/issues/1571), fix OAuth in Sandstorm
|
||||
- [Issue 1568](https://github.com/firefly-iii/firefly-iii/issues/1568), bug in Sandstorm user code.
|
||||
- [Issue 1569](https://github.com/firefly-iii/firefly-iii/issues/1569), optimized Sandstorm build by [ocdtrekkie](https://github.com/ocdtrekkie)
|
||||
- Fixed a bug where transfers would be stored inversely when using the CSV import.
|
||||
- Retired the "Rabobank description"-fix, because it is no longer necessary.
|
||||
- Fixed a bug where users could not delete budget limits in the API.
|
||||
- Piggy bank notes are visible again.
|
||||
|
||||
# 4.7.5.1
|
||||
- [Issue 1531](https://github.com/firefly-iii/firefly-iii/issues/1531), the database routine incorrectly reports empty categories.
|
||||
- [Issue 1532](https://github.com/firefly-iii/firefly-iii/issues/1532), broken dropdown for autosuggest things.
|
||||
- [Issue 1533](https://github.com/firefly-iii/firefly-iii/issues/1533), fix where the import could not import category names.
|
||||
- [Issue 1538](https://github.com/firefly-iii/firefly-iii/issues/1538), fix a bug where Spectre would not work when ignoring rules.
|
||||
- [Issue 1542](https://github.com/firefly-iii/firefly-iii/issues/1542), fix a bug where the importer was incapable of generating new currencies.
|
||||
- [Issue 1541](https://github.com/firefly-iii/firefly-iii/issues/1541), no longer ignore composer.lock in Docker ignore.
|
||||
- Bills are stored inactive.
|
||||
|
||||
# 4.7.5
|
||||
- A new feature called "recurring transactions" that will make Firefly III automatically create transactions for you.
|
||||
- New API end points for attachments, available budgets, budgets, budget limits, categories, configuration, currency exchange rates, journal links, link types, piggy banks, preferences, recurring transactions, rules, rule groups and tags.
|
||||
|
||||
@@ -9,6 +9,10 @@ CURL_OPTS="--silent --show-error"
|
||||
echo localhost > /etc/hostname
|
||||
hostname localhost
|
||||
|
||||
# Install curl that is needed below.
|
||||
apt-get update
|
||||
apt-get install -y curl
|
||||
|
||||
# The following line copies stderr through stderr to cat without accidentally leaving it in the
|
||||
# output file. Be careful when changing. See: https://github.com/sandstorm-io/vagrant-spk/pull/159
|
||||
curl $CURL_OPTS https://install.sandstorm.io/ 2>&1 > /host-dot-sandstorm/caches/install.sh | cat
|
||||
|
||||
@@ -209,13 +209,6 @@ opt/app/.env.sandstorm
|
||||
opt/app/.gitattributes
|
||||
opt/app/.htaccess
|
||||
opt/app/.sandstorm/.gitattributes
|
||||
opt/app/.sandstorm/.vagrant/machines/default/virtualbox/action_provision
|
||||
opt/app/.sandstorm/.vagrant/machines/default/virtualbox/action_set_name
|
||||
opt/app/.sandstorm/.vagrant/machines/default/virtualbox/creator_uid
|
||||
opt/app/.sandstorm/.vagrant/machines/default/virtualbox/id
|
||||
opt/app/.sandstorm/.vagrant/machines/default/virtualbox/index_uuid
|
||||
opt/app/.sandstorm/.vagrant/machines/default/virtualbox/private_key
|
||||
opt/app/.sandstorm/.vagrant/machines/default/virtualbox/synced_folders
|
||||
opt/app/.sandstorm/.vagrant/machines/default/virtualbox/vagrant_cwd
|
||||
opt/app/.sandstorm/Vagrantfile
|
||||
opt/app/.sandstorm/app-graphics/firefly-iii-128.png
|
||||
@@ -242,15 +235,41 @@ opt/app/LICENSE
|
||||
opt/app/app.json
|
||||
opt/app/app/Api/V1/Controllers/AboutController.php
|
||||
opt/app/app/Api/V1/Controllers/AccountController.php
|
||||
opt/app/app/Api/V1/Controllers/AttachmentController.php
|
||||
opt/app/app/Api/V1/Controllers/AvailableBudgetController.php
|
||||
opt/app/app/Api/V1/Controllers/BillController.php
|
||||
opt/app/app/Api/V1/Controllers/BudgetController.php
|
||||
opt/app/app/Api/V1/Controllers/BudgetLimitController.php
|
||||
opt/app/app/Api/V1/Controllers/CategoryController.php
|
||||
opt/app/app/Api/V1/Controllers/ConfigurationController.php
|
||||
opt/app/app/Api/V1/Controllers/Controller.php
|
||||
opt/app/app/Api/V1/Controllers/CurrencyController.php
|
||||
opt/app/app/Api/V1/Controllers/CurrencyExchangeRateController.php
|
||||
opt/app/app/Api/V1/Controllers/JournalLinkController.php
|
||||
opt/app/app/Api/V1/Controllers/LinkTypeController.php
|
||||
opt/app/app/Api/V1/Controllers/PiggyBankController.php
|
||||
opt/app/app/Api/V1/Controllers/PreferenceController.php
|
||||
opt/app/app/Api/V1/Controllers/RecurrenceController.php
|
||||
opt/app/app/Api/V1/Controllers/RuleController.php
|
||||
opt/app/app/Api/V1/Controllers/RuleGroupController.php
|
||||
opt/app/app/Api/V1/Controllers/TransactionController.php
|
||||
opt/app/app/Api/V1/Controllers/UserController.php
|
||||
opt/app/app/Api/V1/Requests/AccountRequest.php
|
||||
opt/app/app/Api/V1/Requests/AttachmentRequest.php
|
||||
opt/app/app/Api/V1/Requests/AvailableBudgetRequest.php
|
||||
opt/app/app/Api/V1/Requests/BillRequest.php
|
||||
opt/app/app/Api/V1/Requests/BudgetLimitRequest.php
|
||||
opt/app/app/Api/V1/Requests/BudgetRequest.php
|
||||
opt/app/app/Api/V1/Requests/CategoryRequest.php
|
||||
opt/app/app/Api/V1/Requests/CurrencyRequest.php
|
||||
opt/app/app/Api/V1/Requests/JournalLinkRequest.php
|
||||
opt/app/app/Api/V1/Requests/LinkTypeRequest.php
|
||||
opt/app/app/Api/V1/Requests/PiggyBankRequest.php
|
||||
opt/app/app/Api/V1/Requests/PreferenceRequest.php
|
||||
opt/app/app/Api/V1/Requests/RecurrenceRequest.php
|
||||
opt/app/app/Api/V1/Requests/Request.php
|
||||
opt/app/app/Api/V1/Requests/RuleGroupRequest.php
|
||||
opt/app/app/Api/V1/Requests/RuleRequest.php
|
||||
opt/app/app/Api/V1/Requests/TransactionRequest.php
|
||||
opt/app/app/Api/V1/Requests/UserRequest.php
|
||||
opt/app/app/Console/Commands/CreateExport.php
|
||||
@@ -269,6 +288,7 @@ opt/app/app/Events/AdminRequestedTestMessage.php
|
||||
opt/app/app/Events/Event.php
|
||||
opt/app/app/Events/RegisteredUser.php
|
||||
opt/app/app/Events/RequestedNewPassword.php
|
||||
opt/app/app/Events/RequestedReportOnJournals.php
|
||||
opt/app/app/Events/RequestedVersionCheckStatus.php
|
||||
opt/app/app/Events/StoredTransactionJournal.php
|
||||
opt/app/app/Events/UpdatedTransactionJournal.php
|
||||
@@ -289,11 +309,13 @@ opt/app/app/Export/Exporter/ExporterInterface.php
|
||||
opt/app/app/Export/ProcessorInterface.php
|
||||
opt/app/app/Factory/AccountFactory.php
|
||||
opt/app/app/Factory/AccountMetaFactory.php
|
||||
opt/app/app/Factory/AttachmentFactory.php
|
||||
opt/app/app/Factory/BillFactory.php
|
||||
opt/app/app/Factory/BudgetFactory.php
|
||||
opt/app/app/Factory/CategoryFactory.php
|
||||
opt/app/app/Factory/PiggyBankEventFactory.php
|
||||
opt/app/app/Factory/PiggyBankFactory.php
|
||||
opt/app/app/Factory/RecurrenceFactory.php
|
||||
opt/app/app/Factory/TagFactory.php
|
||||
opt/app/app/Factory/TransactionCurrencyFactory.php
|
||||
opt/app/app/Factory/TransactionFactory.php
|
||||
@@ -325,6 +347,7 @@ opt/app/app/Generator/Report/Tag/MultiYearReportGenerator.php
|
||||
opt/app/app/Generator/Report/Tag/YearReportGenerator.php
|
||||
opt/app/app/Handlers/Events/APIEventHandler.php
|
||||
opt/app/app/Handlers/Events/AdminEventHandler.php
|
||||
opt/app/app/Handlers/Events/AutomationHandler.php
|
||||
opt/app/app/Handlers/Events/StoredJournalEventHandler.php
|
||||
opt/app/app/Handlers/Events/UpdatedJournalEventHandler.php
|
||||
opt/app/app/Handlers/Events/UserEventHandler.php
|
||||
@@ -365,8 +388,13 @@ opt/app/app/Helpers/Report/PopupReport.php
|
||||
opt/app/app/Helpers/Report/PopupReportInterface.php
|
||||
opt/app/app/Helpers/Report/ReportHelper.php
|
||||
opt/app/app/Helpers/Report/ReportHelperInterface.php
|
||||
opt/app/app/Helpers/Update/UpdateTrait.php
|
||||
opt/app/app/Http/Controllers/Account/CreateController.php
|
||||
opt/app/app/Http/Controllers/Account/DeleteController.php
|
||||
opt/app/app/Http/Controllers/Account/EditController.php
|
||||
opt/app/app/Http/Controllers/Account/IndexController.php
|
||||
opt/app/app/Http/Controllers/Account/ReconcileController.php
|
||||
opt/app/app/Http/Controllers/AccountController.php
|
||||
opt/app/app/Http/Controllers/Account/ShowController.php
|
||||
opt/app/app/Http/Controllers/Admin/ConfigurationController.php
|
||||
opt/app/app/Http/Controllers/Admin/HomeController.php
|
||||
opt/app/app/Http/Controllers/Admin/LinkController.php
|
||||
@@ -379,7 +407,14 @@ opt/app/app/Http/Controllers/Auth/RegisterController.php
|
||||
opt/app/app/Http/Controllers/Auth/ResetPasswordController.php
|
||||
opt/app/app/Http/Controllers/Auth/TwoFactorController.php
|
||||
opt/app/app/Http/Controllers/BillController.php
|
||||
opt/app/app/Http/Controllers/BudgetController.php
|
||||
opt/app/app/Http/Controllers/Budget/AmountController.php
|
||||
opt/app/app/Http/Controllers/Budget/CreateController.php
|
||||
opt/app/app/Http/Controllers/Budget/DeleteController.php
|
||||
opt/app/app/Http/Controllers/Budget/EditController.php
|
||||
opt/app/app/Http/Controllers/Budget/IndexController.php
|
||||
opt/app/app/Http/Controllers/Budget/ShowController.php
|
||||
opt/app/app/Http/Controllers/Category/NoCategoryController.php
|
||||
opt/app/app/Http/Controllers/Category/ShowController.php
|
||||
opt/app/app/Http/Controllers/CategoryController.php
|
||||
opt/app/app/Http/Controllers/Chart/AccountController.php
|
||||
opt/app/app/Http/Controllers/Chart/BillController.php
|
||||
@@ -407,12 +442,18 @@ opt/app/app/Http/Controllers/Json/BoxController.php
|
||||
opt/app/app/Http/Controllers/Json/ExchangeController.php
|
||||
opt/app/app/Http/Controllers/Json/FrontpageController.php
|
||||
opt/app/app/Http/Controllers/Json/IntroController.php
|
||||
opt/app/app/Http/Controllers/Json/ReconcileController.php
|
||||
opt/app/app/Http/Controllers/Json/RecurrenceController.php
|
||||
opt/app/app/Http/Controllers/JsonController.php
|
||||
opt/app/app/Http/Controllers/NewUserController.php
|
||||
opt/app/app/Http/Controllers/PiggyBankController.php
|
||||
opt/app/app/Http/Controllers/Popup/ReportController.php
|
||||
opt/app/app/Http/Controllers/PreferencesController.php
|
||||
opt/app/app/Http/Controllers/ProfileController.php
|
||||
opt/app/app/Http/Controllers/Recurring/CreateController.php
|
||||
opt/app/app/Http/Controllers/Recurring/DeleteController.php
|
||||
opt/app/app/Http/Controllers/Recurring/EditController.php
|
||||
opt/app/app/Http/Controllers/Recurring/IndexController.php
|
||||
opt/app/app/Http/Controllers/Report/AccountController.php
|
||||
opt/app/app/Http/Controllers/Report/BalanceController.php
|
||||
opt/app/app/Http/Controllers/Report/BudgetController.php
|
||||
@@ -420,7 +461,11 @@ opt/app/app/Http/Controllers/Report/CategoryController.php
|
||||
opt/app/app/Http/Controllers/Report/ExpenseController.php
|
||||
opt/app/app/Http/Controllers/Report/OperationsController.php
|
||||
opt/app/app/Http/Controllers/ReportController.php
|
||||
opt/app/app/Http/Controllers/RuleController.php
|
||||
opt/app/app/Http/Controllers/Rule/CreateController.php
|
||||
opt/app/app/Http/Controllers/Rule/DeleteController.php
|
||||
opt/app/app/Http/Controllers/Rule/EditController.php
|
||||
opt/app/app/Http/Controllers/Rule/IndexController.php
|
||||
opt/app/app/Http/Controllers/Rule/SelectController.php
|
||||
opt/app/app/Http/Controllers/RuleGroupController.php
|
||||
opt/app/app/Http/Controllers/SearchController.php
|
||||
opt/app/app/Http/Controllers/System/InstallController.php
|
||||
@@ -471,6 +516,7 @@ opt/app/app/Http/Requests/PiggyBankFormRequest.php
|
||||
opt/app/app/Http/Requests/ProfileFormRequest.php
|
||||
opt/app/app/Http/Requests/ReconciliationStoreRequest.php
|
||||
opt/app/app/Http/Requests/ReconciliationUpdateRequest.php
|
||||
opt/app/app/Http/Requests/RecurrenceFormRequest.php
|
||||
opt/app/app/Http/Requests/ReportFormRequest.php
|
||||
opt/app/app/Http/Requests/Request.php
|
||||
opt/app/app/Http/Requests/RuleFormRequest.php
|
||||
@@ -482,8 +528,6 @@ opt/app/app/Http/Requests/TestRuleFormRequest.php
|
||||
opt/app/app/Http/Requests/TokenFormRequest.php
|
||||
opt/app/app/Http/Requests/UserFormRequest.php
|
||||
opt/app/app/Http/Requests/UserRegistrationRequest.php
|
||||
opt/app/app/Import/Configuration/BunqConfigurator.php
|
||||
opt/app/app/Import/Configuration/ConfiguratorInterface.php
|
||||
opt/app/app/Import/Converter/Amount.php
|
||||
opt/app/app/Import/Converter/AmountCredit.php
|
||||
opt/app/app/Import/Converter/AmountDebit.php
|
||||
@@ -508,12 +552,6 @@ opt/app/app/Import/Mapper/TransactionCurrencies.php
|
||||
opt/app/app/Import/MapperPreProcess/PreProcessorInterface.php
|
||||
opt/app/app/Import/MapperPreProcess/TagsComma.php
|
||||
opt/app/app/Import/MapperPreProcess/TagsSpace.php
|
||||
opt/app/app/Import/Object/ImportAccount.php
|
||||
opt/app/app/Import/Object/ImportBill.php
|
||||
opt/app/app/Import/Object/ImportBudget.php
|
||||
opt/app/app/Import/Object/ImportCategory.php
|
||||
opt/app/app/Import/Object/ImportCurrency.php
|
||||
opt/app/app/Import/Object/ImportJournal.php
|
||||
opt/app/app/Import/Prerequisites/BunqPrerequisites.php
|
||||
opt/app/app/Import/Prerequisites/FakePrerequisites.php
|
||||
opt/app/app/Import/Prerequisites/FilePrerequisites.php
|
||||
@@ -531,6 +569,7 @@ opt/app/app/Import/Specifics/RabobankDescription.php
|
||||
opt/app/app/Import/Specifics/SnsDescription.php
|
||||
opt/app/app/Import/Specifics/SpecificInterface.php
|
||||
opt/app/app/Import/Storage/ImportArrayStorage.php
|
||||
opt/app/app/Jobs/CreateRecurringTransactions.php
|
||||
opt/app/app/Jobs/ExecuteRuleGroupOnExistingTransactions.php
|
||||
opt/app/app/Jobs/ExecuteRuleOnExistingTransactions.php
|
||||
opt/app/app/Jobs/Job.php
|
||||
@@ -540,6 +579,7 @@ opt/app/app/Mail/AdminTestMail.php
|
||||
opt/app/app/Mail/ConfirmEmailChangeMail.php
|
||||
opt/app/app/Mail/OAuthTokenCreatedMail.php
|
||||
opt/app/app/Mail/RegisteredUser.php
|
||||
opt/app/app/Mail/ReportNewJournalsMail.php
|
||||
opt/app/app/Mail/RequestedNewPassword.php
|
||||
opt/app/app/Mail/UndoEmailChangeMail.php
|
||||
opt/app/app/Models/Account.php
|
||||
@@ -561,6 +601,11 @@ opt/app/app/Models/PiggyBank.php
|
||||
opt/app/app/Models/PiggyBankEvent.php
|
||||
opt/app/app/Models/PiggyBankRepetition.php
|
||||
opt/app/app/Models/Preference.php
|
||||
opt/app/app/Models/Recurrence.php
|
||||
opt/app/app/Models/RecurrenceMeta.php
|
||||
opt/app/app/Models/RecurrenceRepetition.php
|
||||
opt/app/app/Models/RecurrenceTransaction.php
|
||||
opt/app/app/Models/RecurrenceTransactionMeta.php
|
||||
opt/app/app/Models/Role.php
|
||||
opt/app/app/Models/Rule.php
|
||||
opt/app/app/Models/RuleAction.php
|
||||
@@ -588,8 +633,8 @@ opt/app/app/Providers/ExportJobServiceProvider.php
|
||||
opt/app/app/Providers/FireflyServiceProvider.php
|
||||
opt/app/app/Providers/FireflySessionProvider.php
|
||||
opt/app/app/Providers/JournalServiceProvider.php
|
||||
opt/app/app/Providers/LogServiceProvider.php
|
||||
opt/app/app/Providers/PiggyBankServiceProvider.php
|
||||
opt/app/app/Providers/RecurringServiceProvider.php
|
||||
opt/app/app/Providers/RouteServiceProvider.php
|
||||
opt/app/app/Providers/RuleGroupServiceProvider.php
|
||||
opt/app/app/Providers/RuleServiceProvider.php
|
||||
@@ -600,7 +645,6 @@ opt/app/app/Repositories/Account/AccountRepository.php
|
||||
opt/app/app/Repositories/Account/AccountRepositoryInterface.php
|
||||
opt/app/app/Repositories/Account/AccountTasker.php
|
||||
opt/app/app/Repositories/Account/AccountTaskerInterface.php
|
||||
opt/app/app/Repositories/Account/FindAccountsTrait.php
|
||||
opt/app/app/Repositories/Attachment/AttachmentRepository.php
|
||||
opt/app/app/Repositories/Attachment/AttachmentRepositoryInterface.php
|
||||
opt/app/app/Repositories/Bill/BillRepository.php
|
||||
@@ -621,18 +665,22 @@ opt/app/app/Repositories/LinkType/LinkTypeRepository.php
|
||||
opt/app/app/Repositories/LinkType/LinkTypeRepositoryInterface.php
|
||||
opt/app/app/Repositories/PiggyBank/PiggyBankRepository.php
|
||||
opt/app/app/Repositories/PiggyBank/PiggyBankRepositoryInterface.php
|
||||
opt/app/app/Repositories/Recurring/RecurringRepository.php
|
||||
opt/app/app/Repositories/Recurring/RecurringRepositoryInterface.php
|
||||
opt/app/app/Repositories/Rule/RuleRepository.php
|
||||
opt/app/app/Repositories/Rule/RuleRepositoryInterface.php
|
||||
opt/app/app/Repositories/RuleGroup/RuleGroupRepository.php
|
||||
opt/app/app/Repositories/RuleGroup/RuleGroupRepositoryInterface.php
|
||||
opt/app/app/Repositories/Tag/TagRepository.php
|
||||
opt/app/app/Repositories/Tag/TagRepositoryInterface.php
|
||||
opt/app/app/Repositories/TransactionType/TransactionTypeRepository.php
|
||||
opt/app/app/Repositories/TransactionType/TransactionTypeRepositoryInterface.php
|
||||
opt/app/app/Repositories/User/UserRepository.php
|
||||
opt/app/app/Repositories/User/UserRepositoryInterface.php
|
||||
opt/app/app/Rules/BelongsUser.php
|
||||
opt/app/app/Rules/IsAssetAccountId.php
|
||||
opt/app/app/Rules/IsValidAttachmentModel.php
|
||||
opt/app/app/Rules/UniqueIban.php
|
||||
opt/app/app/Rules/ValidRecurrenceRepetitionType.php
|
||||
opt/app/app/Rules/ValidRecurrenceRepetitionValue.php
|
||||
opt/app/app/Rules/ValidTransactions.php
|
||||
opt/app/app/Services/Bunq/ApiContext.php
|
||||
opt/app/app/Services/Bunq/MonetaryAccount.php
|
||||
@@ -650,16 +698,20 @@ opt/app/app/Services/Internal/Destroy/BillDestroyService.php
|
||||
opt/app/app/Services/Internal/Destroy/CategoryDestroyService.php
|
||||
opt/app/app/Services/Internal/Destroy/CurrencyDestroyService.php
|
||||
opt/app/app/Services/Internal/Destroy/JournalDestroyService.php
|
||||
opt/app/app/Services/Internal/Destroy/RecurrenceDestroyService.php
|
||||
opt/app/app/Services/Internal/File/EncryptService.php
|
||||
opt/app/app/Services/Internal/Support/AccountServiceTrait.php
|
||||
opt/app/app/Services/Internal/Support/BillServiceTrait.php
|
||||
opt/app/app/Services/Internal/Support/JournalServiceTrait.php
|
||||
opt/app/app/Services/Internal/Support/RecurringTransactionTrait.php
|
||||
opt/app/app/Services/Internal/Support/TransactionServiceTrait.php
|
||||
opt/app/app/Services/Internal/Support/TransactionTypeTrait.php
|
||||
opt/app/app/Services/Internal/Update/AccountUpdateService.php
|
||||
opt/app/app/Services/Internal/Update/BillUpdateService.php
|
||||
opt/app/app/Services/Internal/Update/CategoryUpdateService.php
|
||||
opt/app/app/Services/Internal/Update/CurrencyUpdateService.php
|
||||
opt/app/app/Services/Internal/Update/JournalUpdateService.php
|
||||
opt/app/app/Services/Internal/Update/RecurrenceUpdateService.php
|
||||
opt/app/app/Services/Internal/Update/TransactionUpdateService.php
|
||||
opt/app/app/Services/Password/PwndVerifierV2.php
|
||||
opt/app/app/Services/Password/Verifier.php
|
||||
@@ -705,10 +757,10 @@ opt/app/app/Support/Facades/Navigation.php
|
||||
opt/app/app/Support/Facades/Preferences.php
|
||||
opt/app/app/Support/Facades/Steam.php
|
||||
opt/app/app/Support/FireflyConfig.php
|
||||
opt/app/app/Support/Import/Information/BunqInformation.php
|
||||
opt/app/app/Support/Http/Controllers/DateCalculation.php
|
||||
opt/app/app/Support/Http/Controllers/RuleManagement.php
|
||||
opt/app/app/Support/Import/Information/GetSpectreCustomerTrait.php
|
||||
opt/app/app/Support/Import/Information/GetSpectreTokenTrait.php
|
||||
opt/app/app/Support/Import/Information/InformationInterface.php
|
||||
opt/app/app/Support/Import/JobConfiguration/Bunq/BunqJobConfigurationInterface.php
|
||||
opt/app/app/Support/Import/JobConfiguration/Bunq/ChooseAccountsHandler.php
|
||||
opt/app/app/Support/Import/JobConfiguration/Bunq/NewBunqJobHandler.php
|
||||
@@ -743,7 +795,6 @@ opt/app/app/Support/Import/Routine/File/OpposingAccountMapper.php
|
||||
opt/app/app/Support/Import/Routine/Spectre/StageAuthenticatedHandler.php
|
||||
opt/app/app/Support/Import/Routine/Spectre/StageImportDataHandler.php
|
||||
opt/app/app/Support/Import/Routine/Spectre/StageNewHandler.php
|
||||
opt/app/app/Support/Models/TransactionJournalTrait.php
|
||||
opt/app/app/Support/Navigation.php
|
||||
opt/app/app/Support/Preferences.php
|
||||
opt/app/app/Support/Search/Modifier.php
|
||||
@@ -759,7 +810,6 @@ opt/app/app/Support/Twig/Journal.php
|
||||
opt/app/app/Support/Twig/Loader/AccountLoader.php
|
||||
opt/app/app/Support/Twig/Loader/TransactionJournalLoader.php
|
||||
opt/app/app/Support/Twig/Loader/TransactionLoader.php
|
||||
opt/app/app/Support/Twig/PiggyBank.php
|
||||
opt/app/app/Support/Twig/Rule.php
|
||||
opt/app/app/Support/Twig/Transaction.php
|
||||
opt/app/app/Support/Twig/Translation.php
|
||||
@@ -823,18 +873,32 @@ opt/app/app/TransactionRules/Triggers/TriggerInterface.php
|
||||
opt/app/app/TransactionRules/Triggers/UserAction.php
|
||||
opt/app/app/Transformers/AccountTransformer.php
|
||||
opt/app/app/Transformers/AttachmentTransformer.php
|
||||
opt/app/app/Transformers/AvailableBudgetTransformer.php
|
||||
opt/app/app/Transformers/BillTransformer.php
|
||||
opt/app/app/Transformers/BudgetLimitTransformer.php
|
||||
opt/app/app/Transformers/BudgetTransformer.php
|
||||
opt/app/app/Transformers/CategoryTransformer.php
|
||||
opt/app/app/Transformers/CurrencyExchangeRateTransformer.php
|
||||
opt/app/app/Transformers/CurrencyTransformer.php
|
||||
opt/app/app/Transformers/JournalLinkTransformer.php
|
||||
opt/app/app/Transformers/JournalMetaTransformer.php
|
||||
opt/app/app/Transformers/LinkTypeTransformer.php
|
||||
opt/app/app/Transformers/NoteTransformer.php
|
||||
opt/app/app/Transformers/PiggyBankEventTransformer.php
|
||||
opt/app/app/Transformers/PiggyBankTransformer.php
|
||||
opt/app/app/Transformers/PreferenceTransformer.php
|
||||
opt/app/app/Transformers/RecurrenceTransformer.php
|
||||
opt/app/app/Transformers/RuleActionTransformer.php
|
||||
opt/app/app/Transformers/RuleGroupTransformer.php
|
||||
opt/app/app/Transformers/RuleTransformer.php
|
||||
opt/app/app/Transformers/RuleTriggerTransformer.php
|
||||
opt/app/app/Transformers/TagTransformer.php
|
||||
opt/app/app/Transformers/TransactionTransformer.php
|
||||
opt/app/app/Transformers/UserTransformer.php
|
||||
opt/app/app/User.php
|
||||
opt/app/app/Validation/FireflyValidator.php
|
||||
opt/app/app/Validation/RecurrenceValidation.php
|
||||
opt/app/app/Validation/TransactionValidation.php
|
||||
opt/app/artisan
|
||||
opt/app/bootstrap/app.php
|
||||
opt/app/bootstrap/cache/packages.php
|
||||
@@ -842,7 +906,6 @@ opt/app/bootstrap/cache/services.php
|
||||
opt/app/changelog.md
|
||||
opt/app/composer.json
|
||||
opt/app/composer.lock
|
||||
opt/app/composer.phar
|
||||
opt/app/config/app.php
|
||||
opt/app/config/auth.php
|
||||
opt/app/config/breadcrumbs.php
|
||||
@@ -887,6 +950,7 @@ opt/app/database/migrations/2018_01_01_000005_create_oauth_personal_access_clien
|
||||
opt/app/database/migrations/2018_03_19_141348_changes_for_v472.php
|
||||
opt/app/database/migrations/2018_04_07_210913_changes_for_v473.php
|
||||
opt/app/database/migrations/2018_04_29_174524_changes_for_v474.php
|
||||
opt/app/database/migrations/2018_06_08_200526_changes_for_v475.php
|
||||
opt/app/database/seeds/AccountTypeSeeder.php
|
||||
opt/app/database/seeds/ConfigSeeder.php
|
||||
opt/app/database/seeds/DatabaseSeeder.php
|
||||
@@ -1105,6 +1169,8 @@ opt/app/public/js/ff/piggy-banks/edit.js
|
||||
opt/app/public/js/ff/piggy-banks/index.js
|
||||
opt/app/public/js/ff/piggy-banks/show.js
|
||||
opt/app/public/js/ff/preferences/index.js
|
||||
opt/app/public/js/ff/recurring/create.js
|
||||
opt/app/public/js/ff/recurring/edit.js
|
||||
opt/app/public/js/ff/reports/account/month.js
|
||||
opt/app/public/js/ff/reports/all.js
|
||||
opt/app/public/js/ff/reports/audit/all.js
|
||||
@@ -1153,6 +1219,12 @@ opt/app/public/lib/adminlte/css/skins/skin-blue-light.min.css
|
||||
opt/app/public/lib/adminlte/img/icons.png
|
||||
opt/app/public/lib/adminlte/js/app.js
|
||||
opt/app/public/lib/adminlte/js/app.min.js
|
||||
opt/app/public/lib/fc/fullcalendar.css
|
||||
opt/app/public/lib/fc/fullcalendar.js
|
||||
opt/app/public/lib/fc/fullcalendar.min.css
|
||||
opt/app/public/lib/fc/fullcalendar.min.js
|
||||
opt/app/public/lib/fc/fullcalendar.print.css
|
||||
opt/app/public/lib/fc/fullcalendar.print.min.css
|
||||
opt/app/public/lib/intro/intro.min.js
|
||||
opt/app/public/lib/intro/introjs-rtl.min.css
|
||||
opt/app/public/lib/intro/introjs.min.css
|
||||
@@ -1419,6 +1491,8 @@ opt/app/resources/views/demo/import/index.twig
|
||||
opt/app/resources/views/demo/index.twig
|
||||
opt/app/resources/views/demo/no-demo-text.twig
|
||||
opt/app/resources/views/demo/piggy-banks/index.twig
|
||||
opt/app/resources/views/demo/recurring/index.twig
|
||||
opt/app/resources/views/demo/recurring/recurring-create.twig
|
||||
opt/app/resources/views/demo/reports/index.twig
|
||||
opt/app/resources/views/demo/transactions/index.twig
|
||||
opt/app/resources/views/emails/access-token-created-html.twig
|
||||
@@ -1441,6 +1515,8 @@ opt/app/resources/views/emails/password-html.twig
|
||||
opt/app/resources/views/emails/password-text.twig
|
||||
opt/app/resources/views/emails/registered-html.twig
|
||||
opt/app/resources/views/emails/registered-text.twig
|
||||
opt/app/resources/views/emails/report-new-journals-html.twig
|
||||
opt/app/resources/views/emails/report-new-journals-text.twig
|
||||
opt/app/resources/views/emails/undo-email-change-html.twig
|
||||
opt/app/resources/views/emails/undo-email-change-text.twig
|
||||
opt/app/resources/views/error.twig
|
||||
@@ -1461,7 +1537,6 @@ opt/app/resources/views/form/file.twig
|
||||
opt/app/resources/views/form/help.twig
|
||||
opt/app/resources/views/form/integer.twig
|
||||
opt/app/resources/views/form/location.twig
|
||||
opt/app/resources/views/form/multiRadio.twig
|
||||
opt/app/resources/views/form/non-selectable-amount.twig
|
||||
opt/app/resources/views/form/number.twig
|
||||
opt/app/resources/views/form/options.twig
|
||||
@@ -1538,6 +1613,11 @@ opt/app/resources/views/profile/change-password.twig
|
||||
opt/app/resources/views/profile/code.twig
|
||||
opt/app/resources/views/profile/delete-account.twig
|
||||
opt/app/resources/views/profile/index.twig
|
||||
opt/app/resources/views/recurring/create.twig
|
||||
opt/app/resources/views/recurring/delete.twig
|
||||
opt/app/resources/views/recurring/edit.twig
|
||||
opt/app/resources/views/recurring/index.twig
|
||||
opt/app/resources/views/recurring/show.twig
|
||||
opt/app/resources/views/reports/account/report.twig
|
||||
opt/app/resources/views/reports/audit/report.twig
|
||||
opt/app/resources/views/reports/budget/month.twig
|
||||
@@ -2060,30 +2140,6 @@ opt/app/vendor/defuse/php-encryption/src/Key.php
|
||||
opt/app/vendor/defuse/php-encryption/src/KeyOrPassword.php
|
||||
opt/app/vendor/defuse/php-encryption/src/KeyProtectedByPassword.php
|
||||
opt/app/vendor/defuse/php-encryption/src/RuntimeTests.php
|
||||
opt/app/vendor/doctrine/annotations/CHANGELOG.md
|
||||
opt/app/vendor/doctrine/annotations/LICENSE
|
||||
opt/app/vendor/doctrine/annotations/README.md
|
||||
opt/app/vendor/doctrine/annotations/composer.json
|
||||
opt/app/vendor/doctrine/annotations/lib/Doctrine/Common/Annotations/Annotation.php
|
||||
opt/app/vendor/doctrine/annotations/lib/Doctrine/Common/Annotations/Annotation/Attribute.php
|
||||
opt/app/vendor/doctrine/annotations/lib/Doctrine/Common/Annotations/Annotation/Attributes.php
|
||||
opt/app/vendor/doctrine/annotations/lib/Doctrine/Common/Annotations/Annotation/Enum.php
|
||||
opt/app/vendor/doctrine/annotations/lib/Doctrine/Common/Annotations/Annotation/IgnoreAnnotation.php
|
||||
opt/app/vendor/doctrine/annotations/lib/Doctrine/Common/Annotations/Annotation/Required.php
|
||||
opt/app/vendor/doctrine/annotations/lib/Doctrine/Common/Annotations/Annotation/Target.php
|
||||
opt/app/vendor/doctrine/annotations/lib/Doctrine/Common/Annotations/AnnotationException.php
|
||||
opt/app/vendor/doctrine/annotations/lib/Doctrine/Common/Annotations/AnnotationReader.php
|
||||
opt/app/vendor/doctrine/annotations/lib/Doctrine/Common/Annotations/AnnotationRegistry.php
|
||||
opt/app/vendor/doctrine/annotations/lib/Doctrine/Common/Annotations/CachedReader.php
|
||||
opt/app/vendor/doctrine/annotations/lib/Doctrine/Common/Annotations/DocLexer.php
|
||||
opt/app/vendor/doctrine/annotations/lib/Doctrine/Common/Annotations/DocParser.php
|
||||
opt/app/vendor/doctrine/annotations/lib/Doctrine/Common/Annotations/FileCacheReader.php
|
||||
opt/app/vendor/doctrine/annotations/lib/Doctrine/Common/Annotations/IndexedReader.php
|
||||
opt/app/vendor/doctrine/annotations/lib/Doctrine/Common/Annotations/PhpParser.php
|
||||
opt/app/vendor/doctrine/annotations/lib/Doctrine/Common/Annotations/Reader.php
|
||||
opt/app/vendor/doctrine/annotations/lib/Doctrine/Common/Annotations/SimpleAnnotationReader.php
|
||||
opt/app/vendor/doctrine/annotations/lib/Doctrine/Common/Annotations/TokenParser.php
|
||||
opt/app/vendor/doctrine/annotations/phpstan.neon
|
||||
opt/app/vendor/doctrine/cache/LICENSE
|
||||
opt/app/vendor/doctrine/cache/README.md
|
||||
opt/app/vendor/doctrine/cache/UPGRADE.md
|
||||
@@ -2118,89 +2174,11 @@ opt/app/vendor/doctrine/cache/lib/Doctrine/Common/Cache/VoidCache.php
|
||||
opt/app/vendor/doctrine/cache/lib/Doctrine/Common/Cache/WinCacheCache.php
|
||||
opt/app/vendor/doctrine/cache/lib/Doctrine/Common/Cache/XcacheCache.php
|
||||
opt/app/vendor/doctrine/cache/lib/Doctrine/Common/Cache/ZendDataCache.php
|
||||
opt/app/vendor/doctrine/collections/CONTRIBUTING.md
|
||||
opt/app/vendor/doctrine/collections/LICENSE
|
||||
opt/app/vendor/doctrine/collections/README.md
|
||||
opt/app/vendor/doctrine/collections/composer.json
|
||||
opt/app/vendor/doctrine/collections/lib/Doctrine/Common/Collections/AbstractLazyCollection.php
|
||||
opt/app/vendor/doctrine/collections/lib/Doctrine/Common/Collections/ArrayCollection.php
|
||||
opt/app/vendor/doctrine/collections/lib/Doctrine/Common/Collections/Collection.php
|
||||
opt/app/vendor/doctrine/collections/lib/Doctrine/Common/Collections/Criteria.php
|
||||
opt/app/vendor/doctrine/collections/lib/Doctrine/Common/Collections/Expr/ClosureExpressionVisitor.php
|
||||
opt/app/vendor/doctrine/collections/lib/Doctrine/Common/Collections/Expr/Comparison.php
|
||||
opt/app/vendor/doctrine/collections/lib/Doctrine/Common/Collections/Expr/CompositeExpression.php
|
||||
opt/app/vendor/doctrine/collections/lib/Doctrine/Common/Collections/Expr/Expression.php
|
||||
opt/app/vendor/doctrine/collections/lib/Doctrine/Common/Collections/Expr/ExpressionVisitor.php
|
||||
opt/app/vendor/doctrine/collections/lib/Doctrine/Common/Collections/Expr/Value.php
|
||||
opt/app/vendor/doctrine/collections/lib/Doctrine/Common/Collections/ExpressionBuilder.php
|
||||
opt/app/vendor/doctrine/collections/lib/Doctrine/Common/Collections/Selectable.php
|
||||
opt/app/vendor/doctrine/common/LICENSE
|
||||
opt/app/vendor/doctrine/common/README.md
|
||||
opt/app/vendor/doctrine/common/UPGRADE_TO_2_1
|
||||
opt/app/vendor/doctrine/common/UPGRADE_TO_2_2
|
||||
opt/app/vendor/doctrine/common/composer.json
|
||||
opt/app/vendor/doctrine/common/humbug.json.dist
|
||||
opt/app/vendor/doctrine/common/lib/Doctrine/Common/ClassLoader.php
|
||||
opt/app/vendor/doctrine/common/lib/Doctrine/Common/CommonException.php
|
||||
opt/app/vendor/doctrine/common/lib/Doctrine/Common/Comparable.php
|
||||
opt/app/vendor/doctrine/common/lib/Doctrine/Common/EventArgs.php
|
||||
opt/app/vendor/doctrine/common/lib/Doctrine/Common/EventManager.php
|
||||
opt/app/vendor/doctrine/common/lib/Doctrine/Common/EventSubscriber.php
|
||||
opt/app/vendor/doctrine/common/lib/Doctrine/Common/Lexer.php
|
||||
opt/app/vendor/doctrine/common/lib/Doctrine/Common/NotifyPropertyChanged.php
|
||||
opt/app/vendor/doctrine/common/lib/Doctrine/Common/Persistence/AbstractManagerRegistry.php
|
||||
opt/app/vendor/doctrine/common/lib/Doctrine/Common/Persistence/ConnectionRegistry.php
|
||||
opt/app/vendor/doctrine/common/lib/Doctrine/Common/Persistence/Event/LifecycleEventArgs.php
|
||||
opt/app/vendor/doctrine/common/lib/Doctrine/Common/Persistence/Event/LoadClassMetadataEventArgs.php
|
||||
opt/app/vendor/doctrine/common/lib/Doctrine/Common/Persistence/Event/ManagerEventArgs.php
|
||||
opt/app/vendor/doctrine/common/lib/Doctrine/Common/Persistence/Event/OnClearEventArgs.php
|
||||
opt/app/vendor/doctrine/common/lib/Doctrine/Common/Persistence/Event/PreUpdateEventArgs.php
|
||||
opt/app/vendor/doctrine/common/lib/Doctrine/Common/Persistence/ManagerRegistry.php
|
||||
opt/app/vendor/doctrine/common/lib/Doctrine/Common/Persistence/Mapping/AbstractClassMetadataFactory.php
|
||||
opt/app/vendor/doctrine/common/lib/Doctrine/Common/Persistence/Mapping/ClassMetadata.php
|
||||
opt/app/vendor/doctrine/common/lib/Doctrine/Common/Persistence/Mapping/ClassMetadataFactory.php
|
||||
opt/app/vendor/doctrine/common/lib/Doctrine/Common/Persistence/Mapping/Driver/AnnotationDriver.php
|
||||
opt/app/vendor/doctrine/common/lib/Doctrine/Common/Persistence/Mapping/Driver/DefaultFileLocator.php
|
||||
opt/app/vendor/doctrine/common/lib/Doctrine/Common/Persistence/Mapping/Driver/FileDriver.php
|
||||
opt/app/vendor/doctrine/common/lib/Doctrine/Common/Persistence/Mapping/Driver/FileLocator.php
|
||||
opt/app/vendor/doctrine/common/lib/Doctrine/Common/Persistence/Mapping/Driver/MappingDriver.php
|
||||
opt/app/vendor/doctrine/common/lib/Doctrine/Common/Persistence/Mapping/Driver/MappingDriverChain.php
|
||||
opt/app/vendor/doctrine/common/lib/Doctrine/Common/Persistence/Mapping/Driver/PHPDriver.php
|
||||
opt/app/vendor/doctrine/common/lib/Doctrine/Common/Persistence/Mapping/Driver/StaticPHPDriver.php
|
||||
opt/app/vendor/doctrine/common/lib/Doctrine/Common/Persistence/Mapping/Driver/SymfonyFileLocator.php
|
||||
opt/app/vendor/doctrine/common/lib/Doctrine/Common/Persistence/Mapping/MappingException.php
|
||||
opt/app/vendor/doctrine/common/lib/Doctrine/Common/Persistence/Mapping/ReflectionService.php
|
||||
opt/app/vendor/doctrine/common/lib/Doctrine/Common/Persistence/Mapping/RuntimeReflectionService.php
|
||||
opt/app/vendor/doctrine/common/lib/Doctrine/Common/Persistence/Mapping/StaticReflectionService.php
|
||||
opt/app/vendor/doctrine/common/lib/Doctrine/Common/Persistence/ObjectManager.php
|
||||
opt/app/vendor/doctrine/common/lib/Doctrine/Common/Persistence/ObjectManagerAware.php
|
||||
opt/app/vendor/doctrine/common/lib/Doctrine/Common/Persistence/ObjectManagerDecorator.php
|
||||
opt/app/vendor/doctrine/common/lib/Doctrine/Common/Persistence/ObjectRepository.php
|
||||
opt/app/vendor/doctrine/common/lib/Doctrine/Common/Persistence/PersistentObject.php
|
||||
opt/app/vendor/doctrine/common/lib/Doctrine/Common/Persistence/Proxy.php
|
||||
opt/app/vendor/doctrine/common/lib/Doctrine/Common/PropertyChangedListener.php
|
||||
opt/app/vendor/doctrine/common/lib/Doctrine/Common/Proxy/AbstractProxyFactory.php
|
||||
opt/app/vendor/doctrine/common/lib/Doctrine/Common/Proxy/Autoloader.php
|
||||
opt/app/vendor/doctrine/common/lib/Doctrine/Common/Proxy/Exception/InvalidArgumentException.php
|
||||
opt/app/vendor/doctrine/common/lib/Doctrine/Common/Proxy/Exception/OutOfBoundsException.php
|
||||
opt/app/vendor/doctrine/common/lib/Doctrine/Common/Proxy/Exception/ProxyException.php
|
||||
opt/app/vendor/doctrine/common/lib/Doctrine/Common/Proxy/Exception/UnexpectedValueException.php
|
||||
opt/app/vendor/doctrine/common/lib/Doctrine/Common/Proxy/Proxy.php
|
||||
opt/app/vendor/doctrine/common/lib/Doctrine/Common/Proxy/ProxyDefinition.php
|
||||
opt/app/vendor/doctrine/common/lib/Doctrine/Common/Proxy/ProxyGenerator.php
|
||||
opt/app/vendor/doctrine/common/lib/Doctrine/Common/Reflection/ClassFinderInterface.php
|
||||
opt/app/vendor/doctrine/common/lib/Doctrine/Common/Reflection/Psr0FindFile.php
|
||||
opt/app/vendor/doctrine/common/lib/Doctrine/Common/Reflection/ReflectionProviderInterface.php
|
||||
opt/app/vendor/doctrine/common/lib/Doctrine/Common/Reflection/RuntimePublicReflectionProperty.php
|
||||
opt/app/vendor/doctrine/common/lib/Doctrine/Common/Reflection/StaticReflectionClass.php
|
||||
opt/app/vendor/doctrine/common/lib/Doctrine/Common/Reflection/StaticReflectionMethod.php
|
||||
opt/app/vendor/doctrine/common/lib/Doctrine/Common/Reflection/StaticReflectionParser.php
|
||||
opt/app/vendor/doctrine/common/lib/Doctrine/Common/Reflection/StaticReflectionProperty.php
|
||||
opt/app/vendor/doctrine/common/lib/Doctrine/Common/Util/ClassUtils.php
|
||||
opt/app/vendor/doctrine/common/lib/Doctrine/Common/Util/Debug.php
|
||||
opt/app/vendor/doctrine/common/lib/Doctrine/Common/Util/Inflector.php
|
||||
opt/app/vendor/doctrine/common/lib/Doctrine/Common/Version.php
|
||||
opt/app/vendor/doctrine/common/phpstan.neon
|
||||
opt/app/vendor/doctrine/dbal/.github/ISSUE_TEMPLATE/BC_Break.md
|
||||
opt/app/vendor/doctrine/dbal/.github/ISSUE_TEMPLATE/Bug.md
|
||||
opt/app/vendor/doctrine/dbal/.github/ISSUE_TEMPLATE/Feature_Request.md
|
||||
opt/app/vendor/doctrine/dbal/.github/ISSUE_TEMPLATE/Support_Question.md
|
||||
opt/app/vendor/doctrine/dbal/.github/PULL_REQUEST_TEMPLATE.md
|
||||
opt/app/vendor/doctrine/dbal/LICENSE
|
||||
opt/app/vendor/doctrine/dbal/README.md
|
||||
opt/app/vendor/doctrine/dbal/SECURITY.md
|
||||
@@ -2324,6 +2302,7 @@ opt/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Platforms/Keywords/KeywordList.ph
|
||||
opt/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Platforms/Keywords/MariaDb102Keywords.php
|
||||
opt/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Platforms/Keywords/MsSQLKeywords.php
|
||||
opt/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Platforms/Keywords/MySQL57Keywords.php
|
||||
opt/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Platforms/Keywords/MySQL80Keywords.php
|
||||
opt/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Platforms/Keywords/MySQLKeywords.php
|
||||
opt/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Platforms/Keywords/OracleKeywords.php
|
||||
opt/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Platforms/Keywords/PostgreSQL100Keywords.php
|
||||
@@ -2343,6 +2322,7 @@ opt/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Platforms/Keywords/SQLServerKeywo
|
||||
opt/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Platforms/Keywords/SQLiteKeywords.php
|
||||
opt/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Platforms/MariaDb1027Platform.php
|
||||
opt/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Platforms/MySQL57Platform.php
|
||||
opt/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Platforms/MySQL80Platform.php
|
||||
opt/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Platforms/MySqlPlatform.php
|
||||
opt/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Platforms/OraclePlatform.php
|
||||
opt/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Platforms/PostgreSQL100Platform.php
|
||||
@@ -2367,7 +2347,6 @@ opt/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Query/Expression/CompositeExpress
|
||||
opt/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Query/Expression/ExpressionBuilder.php
|
||||
opt/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Query/QueryBuilder.php
|
||||
opt/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Query/QueryException.php
|
||||
opt/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/README.markdown
|
||||
opt/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/SQLParserUtils.php
|
||||
opt/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/SQLParserUtilsException.php
|
||||
opt/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Schema/AbstractAsset.php
|
||||
@@ -2421,6 +2400,7 @@ opt/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Tools/Console/Command/ReservedWor
|
||||
opt/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Tools/Console/Command/RunSqlCommand.php
|
||||
opt/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Tools/Console/ConsoleRunner.php
|
||||
opt/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Tools/Console/Helper/ConnectionHelper.php
|
||||
opt/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Tools/Dumper.php
|
||||
opt/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/TransactionIsolationLevel.php
|
||||
opt/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Types/ArrayType.php
|
||||
opt/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Types/BigIntType.php
|
||||
@@ -2455,6 +2435,16 @@ opt/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Types/VarDateTimeImmutableType.ph
|
||||
opt/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Types/VarDateTimeType.php
|
||||
opt/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Version.php
|
||||
opt/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/VersionAwarePlatformDriver.php
|
||||
opt/app/vendor/doctrine/dbal/phpstan.neon.dist
|
||||
opt/app/vendor/doctrine/event-manager/LICENSE
|
||||
opt/app/vendor/doctrine/event-manager/README.md
|
||||
opt/app/vendor/doctrine/event-manager/composer.json
|
||||
opt/app/vendor/doctrine/event-manager/docs/en/index.rst
|
||||
opt/app/vendor/doctrine/event-manager/docs/en/reference/index.rst
|
||||
opt/app/vendor/doctrine/event-manager/docs/en/sidebar.rst
|
||||
opt/app/vendor/doctrine/event-manager/lib/Doctrine/Common/EventArgs.php
|
||||
opt/app/vendor/doctrine/event-manager/lib/Doctrine/Common/EventManager.php
|
||||
opt/app/vendor/doctrine/event-manager/lib/Doctrine/Common/EventSubscriber.php
|
||||
opt/app/vendor/doctrine/inflector/LICENSE
|
||||
opt/app/vendor/doctrine/inflector/README.md
|
||||
opt/app/vendor/doctrine/inflector/composer.json
|
||||
@@ -2904,6 +2894,7 @@ opt/app/vendor/laravel/framework/src/Illuminate/Database/Console/Migrations/Refr
|
||||
opt/app/vendor/laravel/framework/src/Illuminate/Database/Console/Migrations/ResetCommand.php
|
||||
opt/app/vendor/laravel/framework/src/Illuminate/Database/Console/Migrations/RollbackCommand.php
|
||||
opt/app/vendor/laravel/framework/src/Illuminate/Database/Console/Migrations/StatusCommand.php
|
||||
opt/app/vendor/laravel/framework/src/Illuminate/Database/Console/Migrations/TableGuesser.php
|
||||
opt/app/vendor/laravel/framework/src/Illuminate/Database/Console/Seeds/SeedCommand.php
|
||||
opt/app/vendor/laravel/framework/src/Illuminate/Database/Console/Seeds/SeederMakeCommand.php
|
||||
opt/app/vendor/laravel/framework/src/Illuminate/Database/Console/Seeds/stubs/seeder.stub
|
||||
@@ -3176,6 +3167,7 @@ opt/app/vendor/laravel/framework/src/Illuminate/Foundation/Testing/WithoutMiddle
|
||||
opt/app/vendor/laravel/framework/src/Illuminate/Foundation/Validation/ValidatesRequests.php
|
||||
opt/app/vendor/laravel/framework/src/Illuminate/Foundation/helpers.php
|
||||
opt/app/vendor/laravel/framework/src/Illuminate/Foundation/stubs/facade.stub
|
||||
opt/app/vendor/laravel/framework/src/Illuminate/Hashing/AbstractHasher.php
|
||||
opt/app/vendor/laravel/framework/src/Illuminate/Hashing/ArgonHasher.php
|
||||
opt/app/vendor/laravel/framework/src/Illuminate/Hashing/BcryptHasher.php
|
||||
opt/app/vendor/laravel/framework/src/Illuminate/Hashing/HashManager.php
|
||||
@@ -3383,6 +3375,7 @@ opt/app/vendor/laravel/framework/src/Illuminate/Redis/composer.json
|
||||
opt/app/vendor/laravel/framework/src/Illuminate/Routing/Console/ControllerMakeCommand.php
|
||||
opt/app/vendor/laravel/framework/src/Illuminate/Routing/Console/MiddlewareMakeCommand.php
|
||||
opt/app/vendor/laravel/framework/src/Illuminate/Routing/Console/stubs/controller.api.stub
|
||||
opt/app/vendor/laravel/framework/src/Illuminate/Routing/Console/stubs/controller.invokable.stub
|
||||
opt/app/vendor/laravel/framework/src/Illuminate/Routing/Console/stubs/controller.model.api.stub
|
||||
opt/app/vendor/laravel/framework/src/Illuminate/Routing/Console/stubs/controller.model.stub
|
||||
opt/app/vendor/laravel/framework/src/Illuminate/Routing/Console/stubs/controller.nested.api.stub
|
||||
@@ -4432,9 +4425,6 @@ opt/app/vendor/ramsey/uuid/CONTRIBUTING.md
|
||||
opt/app/vendor/ramsey/uuid/LICENSE
|
||||
opt/app/vendor/ramsey/uuid/README.md
|
||||
opt/app/vendor/ramsey/uuid/composer.json
|
||||
opt/app/vendor/ramsey/uuid/docs/Makefile
|
||||
opt/app/vendor/ramsey/uuid/docs/conf.py
|
||||
opt/app/vendor/ramsey/uuid/docs/index.rst
|
||||
opt/app/vendor/ramsey/uuid/src/BinaryUtils.php
|
||||
opt/app/vendor/ramsey/uuid/src/Builder/DefaultUuidBuilder.php
|
||||
opt/app/vendor/ramsey/uuid/src/Builder/DegradedUuidBuilder.php
|
||||
@@ -4532,6 +4522,10 @@ opt/app/vendor/swiftmailer/swiftmailer/doc/messages.rst
|
||||
opt/app/vendor/swiftmailer/swiftmailer/doc/plugins.rst
|
||||
opt/app/vendor/swiftmailer/swiftmailer/doc/sending.rst
|
||||
opt/app/vendor/swiftmailer/swiftmailer/lib/classes/Swift.php
|
||||
opt/app/vendor/swiftmailer/swiftmailer/lib/classes/Swift/AddressEncoder.php
|
||||
opt/app/vendor/swiftmailer/swiftmailer/lib/classes/Swift/AddressEncoder/IdnAddressEncoder.php
|
||||
opt/app/vendor/swiftmailer/swiftmailer/lib/classes/Swift/AddressEncoder/Utf8AddressEncoder.php
|
||||
opt/app/vendor/swiftmailer/swiftmailer/lib/classes/Swift/AddressEncoderException.php
|
||||
opt/app/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Attachment.php
|
||||
opt/app/vendor/swiftmailer/swiftmailer/lib/classes/Swift/ByteStream/AbstractFilterableInputStream.php
|
||||
opt/app/vendor/swiftmailer/swiftmailer/lib/classes/Swift/ByteStream/ArrayByteStream.php
|
||||
@@ -4594,6 +4588,7 @@ opt/app/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Mime/CharsetObserver.ph
|
||||
opt/app/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Mime/ContentEncoder.php
|
||||
opt/app/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Mime/ContentEncoder/Base64ContentEncoder.php
|
||||
opt/app/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Mime/ContentEncoder/NativeQpContentEncoder.php
|
||||
opt/app/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Mime/ContentEncoder/NullContentEncoder.php
|
||||
opt/app/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Mime/ContentEncoder/PlainContentEncoder.php
|
||||
opt/app/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Mime/ContentEncoder/QpContentEncoder.php
|
||||
opt/app/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Mime/ContentEncoder/QpContentEncoderProxy.php
|
||||
@@ -4670,6 +4665,8 @@ opt/app/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Transport/Esmtp/Auth/Pl
|
||||
opt/app/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Transport/Esmtp/Auth/XOAuth2Authenticator.php
|
||||
opt/app/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Transport/Esmtp/AuthHandler.php
|
||||
opt/app/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Transport/Esmtp/Authenticator.php
|
||||
opt/app/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Transport/Esmtp/EightBitMimeHandler.php
|
||||
opt/app/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Transport/Esmtp/SmtpUtf8Handler.php
|
||||
opt/app/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Transport/EsmtpHandler.php
|
||||
opt/app/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Transport/EsmtpTransport.php
|
||||
opt/app/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Transport/FailoverTransport.php
|
||||
@@ -6327,6 +6324,7 @@ opt/app/vendor/symfony/var-dumper/Resources/bin/var-dump-server
|
||||
opt/app/vendor/symfony/var-dumper/Resources/css/htmlDescriptor.css
|
||||
opt/app/vendor/symfony/var-dumper/Resources/functions/dump.php
|
||||
opt/app/vendor/symfony/var-dumper/Resources/js/htmlDescriptor.js
|
||||
opt/app/vendor/symfony/var-dumper/Server/Connection.php
|
||||
opt/app/vendor/symfony/var-dumper/Server/DumpServer.php
|
||||
opt/app/vendor/symfony/var-dumper/Test/VarDumperTestTrait.php
|
||||
opt/app/vendor/symfony/var-dumper/Tests/Caster/CasterTest.php
|
||||
@@ -6351,6 +6349,7 @@ opt/app/vendor/symfony/var-dumper/Tests/Fixtures/Twig.php
|
||||
opt/app/vendor/symfony/var-dumper/Tests/Fixtures/dumb-var.php
|
||||
opt/app/vendor/symfony/var-dumper/Tests/Fixtures/dump_server.php
|
||||
opt/app/vendor/symfony/var-dumper/Tests/Fixtures/xml_reader.xml
|
||||
opt/app/vendor/symfony/var-dumper/Tests/Server/ConnectionTest.php
|
||||
opt/app/vendor/symfony/var-dumper/Tests/Test/VarDumperTestTraitTest.php
|
||||
opt/app/vendor/symfony/var-dumper/VarDumper.php
|
||||
opt/app/vendor/symfony/var-dumper/composer.json
|
||||
@@ -7259,6 +7258,14 @@ opt/app/vendor/zendframework/zend-diactoros/src/ServerRequestFactory.php
|
||||
opt/app/vendor/zendframework/zend-diactoros/src/Stream.php
|
||||
opt/app/vendor/zendframework/zend-diactoros/src/UploadedFile.php
|
||||
opt/app/vendor/zendframework/zend-diactoros/src/Uri.php
|
||||
opt/app/vendor/zendframework/zend-diactoros/src/functions/create_uploaded_file.php
|
||||
opt/app/vendor/zendframework/zend-diactoros/src/functions/marshal_headers_from_sapi.php
|
||||
opt/app/vendor/zendframework/zend-diactoros/src/functions/marshal_method_from_sapi.php
|
||||
opt/app/vendor/zendframework/zend-diactoros/src/functions/marshal_protocol_version_from_sapi.php
|
||||
opt/app/vendor/zendframework/zend-diactoros/src/functions/marshal_uri_from_sapi.php
|
||||
opt/app/vendor/zendframework/zend-diactoros/src/functions/normalize_server.php
|
||||
opt/app/vendor/zendframework/zend-diactoros/src/functions/normalize_uploaded_files.php
|
||||
opt/app/vendor/zendframework/zend-diactoros/src/functions/parse_cookie_header.php
|
||||
proc/cpuinfo
|
||||
sandstorm-http-bridge
|
||||
sandstorm-http-bridge-config
|
||||
@@ -7433,14 +7440,17 @@ usr/share/zoneinfo/Africa/Libreville
|
||||
usr/share/zoneinfo/Africa/Lome
|
||||
usr/share/zoneinfo/Africa/Luanda
|
||||
usr/share/zoneinfo/Africa/Lubumbashi
|
||||
usr/share/zoneinfo/Africa/Lusaka
|
||||
usr/share/zoneinfo/Africa/Malabo
|
||||
usr/share/zoneinfo/Africa/Maputo
|
||||
usr/share/zoneinfo/Africa/Maseru
|
||||
usr/share/zoneinfo/Africa/Mbabane
|
||||
usr/share/zoneinfo/Africa/Mogadishu
|
||||
usr/share/zoneinfo/Africa/Nairobi
|
||||
usr/share/zoneinfo/Africa/Niamey
|
||||
usr/share/zoneinfo/Africa/Nouakchott
|
||||
usr/share/zoneinfo/Africa/Ouagadougou
|
||||
usr/share/zoneinfo/Africa/Porto-Novo
|
||||
usr/share/zoneinfo/Africa/Sao_Tome
|
||||
usr/share/zoneinfo/Africa/Timbuktu
|
||||
usr/share/zoneinfo/Africa/Tripoli
|
||||
@@ -7459,7 +7469,9 @@ usr/share/zoneinfo/America/Argentina/Mendoza
|
||||
usr/share/zoneinfo/America/Aruba
|
||||
usr/share/zoneinfo/America/Atikokan
|
||||
usr/share/zoneinfo/America/Atka
|
||||
usr/share/zoneinfo/America/Cayman
|
||||
usr/share/zoneinfo/America/Chicago
|
||||
usr/share/zoneinfo/America/Coral_Harbour
|
||||
usr/share/zoneinfo/America/Cordoba
|
||||
usr/share/zoneinfo/America/Curacao
|
||||
usr/share/zoneinfo/America/Denver
|
||||
@@ -7480,6 +7492,7 @@ usr/share/zoneinfo/America/Jamaica
|
||||
usr/share/zoneinfo/America/Kentucky
|
||||
usr/share/zoneinfo/America/Kentucky/Louisville
|
||||
usr/share/zoneinfo/America/Knox_IN
|
||||
usr/share/zoneinfo/America/Kralendijk
|
||||
usr/share/zoneinfo/America/Los_Angeles
|
||||
usr/share/zoneinfo/America/Lower_Princes
|
||||
usr/share/zoneinfo/America/Manaus
|
||||
@@ -7498,6 +7511,7 @@ usr/share/zoneinfo/America/Porto_Acre
|
||||
usr/share/zoneinfo/America/Puerto_Rico
|
||||
usr/share/zoneinfo/America/Regina
|
||||
usr/share/zoneinfo/America/Rio_Branco
|
||||
usr/share/zoneinfo/America/Santa_Isabel
|
||||
usr/share/zoneinfo/America/Santiago
|
||||
usr/share/zoneinfo/America/Sao_Paulo
|
||||
usr/share/zoneinfo/America/Shiprock
|
||||
@@ -7511,6 +7525,7 @@ usr/share/zoneinfo/America/Tijuana
|
||||
usr/share/zoneinfo/America/Toronto
|
||||
usr/share/zoneinfo/America/Tortola
|
||||
usr/share/zoneinfo/America/Vancouver
|
||||
usr/share/zoneinfo/America/Virgin
|
||||
usr/share/zoneinfo/America/Whitehorse
|
||||
usr/share/zoneinfo/America/Winnipeg
|
||||
usr/share/zoneinfo/Antarctica
|
||||
@@ -7521,8 +7536,10 @@ usr/share/zoneinfo/Asia
|
||||
usr/share/zoneinfo/Asia/Aden
|
||||
usr/share/zoneinfo/Asia/Ashgabat
|
||||
usr/share/zoneinfo/Asia/Bangkok
|
||||
usr/share/zoneinfo/Asia/Calcutta
|
||||
usr/share/zoneinfo/Asia/Chongqing
|
||||
usr/share/zoneinfo/Asia/Chungking
|
||||
usr/share/zoneinfo/Asia/Dacca
|
||||
usr/share/zoneinfo/Asia/Dhaka
|
||||
usr/share/zoneinfo/Asia/Dubai
|
||||
usr/share/zoneinfo/Asia/Harbin
|
||||
@@ -7530,24 +7547,31 @@ usr/share/zoneinfo/Asia/Ho_Chi_Minh
|
||||
usr/share/zoneinfo/Asia/Hong_Kong
|
||||
usr/share/zoneinfo/Asia/Istanbul
|
||||
usr/share/zoneinfo/Asia/Jerusalem
|
||||
usr/share/zoneinfo/Asia/Kashgar
|
||||
usr/share/zoneinfo/Asia/Kathmandu
|
||||
usr/share/zoneinfo/Asia/Katmandu
|
||||
usr/share/zoneinfo/Asia/Kolkata
|
||||
usr/share/zoneinfo/Asia/Macao
|
||||
usr/share/zoneinfo/Asia/Macau
|
||||
usr/share/zoneinfo/Asia/Makassar
|
||||
usr/share/zoneinfo/Asia/Nicosia
|
||||
usr/share/zoneinfo/Asia/Phnom_Penh
|
||||
usr/share/zoneinfo/Asia/Qatar
|
||||
usr/share/zoneinfo/Asia/Riyadh
|
||||
usr/share/zoneinfo/Asia/Saigon
|
||||
usr/share/zoneinfo/Asia/Seoul
|
||||
usr/share/zoneinfo/Asia/Shanghai
|
||||
usr/share/zoneinfo/Asia/Singapore
|
||||
usr/share/zoneinfo/Asia/Taipei
|
||||
usr/share/zoneinfo/Asia/Tehran
|
||||
usr/share/zoneinfo/Asia/Tel_Aviv
|
||||
usr/share/zoneinfo/Asia/Thimbu
|
||||
usr/share/zoneinfo/Asia/Thimphu
|
||||
usr/share/zoneinfo/Asia/Tokyo
|
||||
usr/share/zoneinfo/Asia/Ulaanbaatar
|
||||
usr/share/zoneinfo/Asia/Ulan_Bator
|
||||
usr/share/zoneinfo/Asia/Urumqi
|
||||
usr/share/zoneinfo/Asia/Yangon
|
||||
usr/share/zoneinfo/Atlantic
|
||||
usr/share/zoneinfo/Atlantic/Faroe
|
||||
usr/share/zoneinfo/Atlantic/Jan_Mayen
|
||||
@@ -7560,16 +7584,21 @@ usr/share/zoneinfo/Australia/Broken_Hill
|
||||
usr/share/zoneinfo/Australia/Canberra
|
||||
usr/share/zoneinfo/Australia/Darwin
|
||||
usr/share/zoneinfo/Australia/Hobart
|
||||
usr/share/zoneinfo/Australia/LHI
|
||||
usr/share/zoneinfo/Australia/Lord_Howe
|
||||
usr/share/zoneinfo/Australia/Melbourne
|
||||
usr/share/zoneinfo/Australia/NSW
|
||||
usr/share/zoneinfo/Australia/North
|
||||
usr/share/zoneinfo/Australia/Perth
|
||||
usr/share/zoneinfo/Australia/Queensland
|
||||
usr/share/zoneinfo/Australia/Sydney
|
||||
usr/share/zoneinfo/Australia/West
|
||||
usr/share/zoneinfo/Brazil
|
||||
usr/share/zoneinfo/Canada
|
||||
usr/share/zoneinfo/Canada/Atlantic
|
||||
usr/share/zoneinfo/Canada/East-Saskatchewan
|
||||
usr/share/zoneinfo/Canada/Saskatchewan
|
||||
usr/share/zoneinfo/Chile
|
||||
usr/share/zoneinfo/Chile/EasterIsland
|
||||
usr/share/zoneinfo/Etc
|
||||
usr/share/zoneinfo/Etc/GMT
|
||||
usr/share/zoneinfo/Etc/GMT+0
|
||||
@@ -7583,6 +7612,7 @@ usr/share/zoneinfo/Etc/Zulu
|
||||
usr/share/zoneinfo/Europe
|
||||
usr/share/zoneinfo/Europe/Belfast
|
||||
usr/share/zoneinfo/Europe/Belgrade
|
||||
usr/share/zoneinfo/Europe/Bratislava
|
||||
usr/share/zoneinfo/Europe/Busingen
|
||||
usr/share/zoneinfo/Europe/Chisinau
|
||||
usr/share/zoneinfo/Europe/Dublin
|
||||
@@ -7594,25 +7624,37 @@ usr/share/zoneinfo/Europe/Jersey
|
||||
usr/share/zoneinfo/Europe/Lisbon
|
||||
usr/share/zoneinfo/Europe/Ljubljana
|
||||
usr/share/zoneinfo/Europe/London
|
||||
usr/share/zoneinfo/Europe/Mariehamn
|
||||
usr/share/zoneinfo/Europe/Moscow
|
||||
usr/share/zoneinfo/Europe/Nicosia
|
||||
usr/share/zoneinfo/Europe/Oslo
|
||||
usr/share/zoneinfo/Europe/Podgorica
|
||||
usr/share/zoneinfo/Europe/Prague
|
||||
usr/share/zoneinfo/Europe/Rome
|
||||
usr/share/zoneinfo/Europe/San_Marino
|
||||
usr/share/zoneinfo/Europe/Sarajevo
|
||||
usr/share/zoneinfo/Europe/Skopje
|
||||
usr/share/zoneinfo/Europe/Tiraspol
|
||||
usr/share/zoneinfo/Europe/Vaduz
|
||||
usr/share/zoneinfo/Europe/Vatican
|
||||
usr/share/zoneinfo/Europe/Warsaw
|
||||
usr/share/zoneinfo/Europe/Zagreb
|
||||
usr/share/zoneinfo/Europe/Zurich
|
||||
usr/share/zoneinfo/GB
|
||||
usr/share/zoneinfo/GB-Eire
|
||||
usr/share/zoneinfo/GMT
|
||||
usr/share/zoneinfo/GMT+0
|
||||
usr/share/zoneinfo/GMT-0
|
||||
usr/share/zoneinfo/GMT0
|
||||
usr/share/zoneinfo/Greenwich
|
||||
usr/share/zoneinfo/Indian
|
||||
usr/share/zoneinfo/Indian/Antananarivo
|
||||
usr/share/zoneinfo/Indian/Comoro
|
||||
usr/share/zoneinfo/Indian/Mayotte
|
||||
usr/share/zoneinfo/Mexico
|
||||
usr/share/zoneinfo/Mexico/BajaNorte
|
||||
usr/share/zoneinfo/Mexico/BajaSur
|
||||
usr/share/zoneinfo/Mexico/General
|
||||
usr/share/zoneinfo/Pacific
|
||||
usr/share/zoneinfo/Pacific/Auckland
|
||||
usr/share/zoneinfo/Pacific/Chatham
|
||||
@@ -7629,18 +7671,35 @@ usr/share/zoneinfo/Pacific/Pitcairn
|
||||
usr/share/zoneinfo/Pacific/Pohnpei
|
||||
usr/share/zoneinfo/Pacific/Samoa
|
||||
usr/share/zoneinfo/Pacific/Truk
|
||||
usr/share/zoneinfo/Pacific/Yap
|
||||
usr/share/zoneinfo/SystemV
|
||||
usr/share/zoneinfo/SystemV/AST4
|
||||
usr/share/zoneinfo/SystemV/AST4ADT
|
||||
usr/share/zoneinfo/SystemV/CST6
|
||||
usr/share/zoneinfo/SystemV/CST6CDT
|
||||
usr/share/zoneinfo/SystemV/EST5
|
||||
usr/share/zoneinfo/SystemV/EST5EDT
|
||||
usr/share/zoneinfo/SystemV/HST10
|
||||
usr/share/zoneinfo/SystemV/MST7
|
||||
usr/share/zoneinfo/SystemV/MST7MDT
|
||||
usr/share/zoneinfo/SystemV/PST8
|
||||
usr/share/zoneinfo/SystemV/PST8PDT
|
||||
usr/share/zoneinfo/SystemV/YST9
|
||||
usr/share/zoneinfo/SystemV/YST9YDT
|
||||
usr/share/zoneinfo/US
|
||||
usr/share/zoneinfo/US/Alaska
|
||||
usr/share/zoneinfo/US/Aleutian
|
||||
usr/share/zoneinfo/US/Arizona
|
||||
usr/share/zoneinfo/US/Central
|
||||
usr/share/zoneinfo/US/East-Indiana
|
||||
usr/share/zoneinfo/US/Eastern
|
||||
usr/share/zoneinfo/US/Hawaii
|
||||
usr/share/zoneinfo/US/Indiana-Starke
|
||||
usr/share/zoneinfo/US/Michigan
|
||||
usr/share/zoneinfo/US/Mountain
|
||||
usr/share/zoneinfo/US/Pacific
|
||||
usr/share/zoneinfo/US/Pacific-New
|
||||
usr/share/zoneinfo/US/Samoa
|
||||
usr/share/zoneinfo/UTC
|
||||
usr/share/zoneinfo/Universal
|
||||
usr/share/zoneinfo/Zulu
|
||||
|
||||
@@ -15,8 +15,8 @@ const pkgdef :Spk.PackageDefinition = (
|
||||
|
||||
manifest = (
|
||||
appTitle = (defaultText = "Firefly III"),
|
||||
appVersion = 14,
|
||||
appMarketingVersion = (defaultText = "4.7.5"),
|
||||
appVersion = 16,
|
||||
appMarketingVersion = (defaultText = "4.7.6.2"),
|
||||
|
||||
actions = [
|
||||
# Define your "new document" handlers here.
|
||||
|
||||
@@ -14,10 +14,7 @@ apt-get install -y python-software-properties software-properties-common
|
||||
|
||||
# install all languages
|
||||
sed -i 's/# de_DE.UTF-8 UTF-8/de_DE.UTF-8 UTF-8/g' /etc/locale.gen
|
||||
|
||||
sed -i 's/# es_ES.UTF-8 UTF-8/es_ES.UTF-8 UTF-8/g' /etc/locale.gen
|
||||
sed -i 's/# fr_FR.UTF-8 UTF-8/fr_FR.UTF-8 UTF-8/g' /etc/locale.gen
|
||||
sed -i 's/# id_ID.UTF-8 UTF-8/id_ID.UTF-8 UTF-8/g' /etc/locale.gen
|
||||
sed -i 's/# it_IT.UTF-8 UTF-8/it_IT.UTF-8 UTF-8/g' /etc/locale.gen
|
||||
sed -i 's/# nl_NL.UTF-8 UTF-8/nl_NL.UTF-8 UTF-8/g' /etc/locale.gen
|
||||
sed -i 's/# pl_PL.UTF-8 UTF-8/pl_PL.UTF-8 UTF-8/g' /etc/locale.gen
|
||||
@@ -35,7 +32,7 @@ apt-key adv --keyserver keyserver.ubuntu.com --recv-keys E9C74FEEA2098A6E
|
||||
add-apt-repository "deb http://packages.dotdeb.org jessie all"
|
||||
|
||||
# add another repos
|
||||
apt-get install apt-transport-https lsb-release ca-certificates
|
||||
apt-get install -y apt-transport-https lsb-release ca-certificates
|
||||
wget -O /etc/apt/trusted.gpg.d/php.gpg https://packages.sury.org/php/apt.gpg
|
||||
echo "deb https://packages.sury.org/php/ $(lsb_release -sc) main" > /etc/apt/sources.list.d/php.list
|
||||
|
||||
|
||||
65
Dockerfile
65
Dockerfile
@@ -1,12 +1,16 @@
|
||||
# use PHP 7.1 and Apache as a base.
|
||||
FROM php:7.1-apache
|
||||
|
||||
# set working dir
|
||||
ENV FIREFLY_PATH /var/www/firefly-iii
|
||||
# If building on a RPi, use --build-arg cores=3 to use all cores when compiling
|
||||
# to speed up the image build
|
||||
ARG CORES
|
||||
ENV CORES ${CORES:-1}
|
||||
|
||||
ENV FIREFLY_PATH /var/www/firefly-iii/
|
||||
ENV CURL_VERSION 7.60.0
|
||||
ENV OPENSSL_VERSION 1.1.1-pre6
|
||||
WORKDIR $FIREFLY_PATH
|
||||
ADD . $FIREFLY_PATH
|
||||
|
||||
LABEL version="1.0" maintainer="thegrumpydictator@gmail.com"
|
||||
|
||||
|
||||
# install packages
|
||||
RUN apt-get update -y && \
|
||||
@@ -19,47 +23,60 @@ RUN apt-get update -y && \
|
||||
libedit-dev \
|
||||
libtidy-dev \
|
||||
libxml2-dev \
|
||||
unzip \
|
||||
libsqlite3-dev \
|
||||
nano \
|
||||
libpq-dev \
|
||||
libbz2-dev \
|
||||
gettext-base \
|
||||
cron \
|
||||
rsyslog \
|
||||
supervisor \
|
||||
locales && \
|
||||
apt-get clean && \
|
||||
rm -rf /var/lib/apt/lists/*
|
||||
|
||||
# Setup the Composer installer
|
||||
RUN curl -sS https://getcomposer.org/installer | php -- --install-dir=/usr/local/bin --filename=composer
|
||||
|
||||
# Install latest curl
|
||||
RUN cd /tmp && \
|
||||
wget https://www.openssl.org/source/openssl-${OPENSSL_VERSION}.tar.gz && \
|
||||
tar -xvf openssl-${OPENSSL_VERSION}.tar.gz && \
|
||||
cd openssl-${OPENSSL_VERSION} && \
|
||||
./config && \
|
||||
make && \
|
||||
make -j${CORES} && \
|
||||
make install
|
||||
|
||||
RUN cd /tmp && \
|
||||
wget https://curl.haxx.se/download/curl-${CURL_VERSION}.tar.gz && \
|
||||
tar -xvf curl-${CURL_VERSION}.tar.gz && \
|
||||
cd curl-${CURL_VERSION} && \
|
||||
./configure --with-ssl && \
|
||||
make && \
|
||||
./configure --with-ssl --host=$(gcc -dumpmachine) && \
|
||||
make -j${CORES} && \
|
||||
make install
|
||||
|
||||
# Make sure that libcurl is using the newer curl libaries
|
||||
RUN echo "/usr/local/lib" >> /etc/ld.so.conf.d/00-curl.conf && ldconfig
|
||||
|
||||
# Create the log file to be able to run tail
|
||||
RUN touch /var/log/cron.log
|
||||
# Mimic the Debian/Ubuntu config file structure for supervisor
|
||||
COPY .deploy/docker/supervisord.conf /etc/supervisor/supervisord.conf
|
||||
RUN mkdir -p /etc/supervisor/conf.d /var/log/supervisor
|
||||
|
||||
# Setup cron job
|
||||
RUN (crontab -l ; echo "* * * * * root $FIREFLY_PATH/artisan schedule:run >> /var/log/cron.log") | crontab
|
||||
# copy Firefly III supervisor conf file.
|
||||
COPY ./.deploy/docker/firefly-iii.conf /etc/supervisor/conf.d/firefly-iii.conf
|
||||
|
||||
# copy cron job supervisor conf file.
|
||||
COPY ./.deploy/docker/cronjob.conf /etc/supervisor/conf.d/cronjob.conf
|
||||
|
||||
# test crons added via crontab
|
||||
RUN echo "0 3 * * * /usr/local/bin/php /var/www/firefly-iii/artisan firefly:cron" | crontab -
|
||||
#RUN (crontab -l ; echo "*/1 * * * * free >> /var/www/firefly-iii/public/cron.html") 2>&1 | crontab -
|
||||
# Install PHP exentions.
|
||||
RUN docker-php-ext-install -j$(nproc) curl gd intl json readline tidy zip bcmath xml mbstring pdo_sqlite pdo_mysql bz2 pdo_pgsql
|
||||
RUN docker-php-ext-install -j$(nproc) gd intl tidy zip bcmath pdo_mysql bz2 pdo_pgsql
|
||||
|
||||
# Install composer
|
||||
RUN curl -sS https://getcomposer.org/installer | php -- --install-dir=/usr/local/bin --filename=composer
|
||||
|
||||
# Generate locales supported by Firefly III
|
||||
RUN echo "de_DE.UTF-8 UTF-8\nen_US.UTF-8 UTF-8\nes_ES.UTF-8 UTF-8\nfr_FR.UTF-8 UTF-8\nid_ID.UTF-8 UTF-8\nit_IT.UTF-8 UTF-8\nnl_NL.UTF-8 UTF-8\npl_PL.UTF-8 UTF-8pt_BR.UTF-8 UTF-8ru_RU.UTF-8 UTF-8\ntr_TR.UTF-8 UTF-8\n\n" > /etc/locale.gen && locale-gen
|
||||
RUN echo "en_US.UTF-8 UTF-8\nde_DE.UTF-8 UTF-8\nfr_FR.UTF-8 UTF-8\nit_IT.UTF-8 UTF-8\nnl_NL.UTF-8 UTF-8\npl_PL.UTF-8 UTF-8\npt_BR.UTF-8 UTF-8\nru_RU.UTF-8 UTF-8\ntr_TR.UTF-8 UTF-8\n\n" > /etc/locale.gen && locale-gen
|
||||
|
||||
# copy Apache config to correct spot.
|
||||
COPY ./.deploy/docker/apache2.conf /etc/apache2/apache2.conf
|
||||
@@ -70,7 +87,7 @@ RUN a2enmod rewrite
|
||||
# Enable apache mod ssl..
|
||||
RUN a2enmod ssl
|
||||
|
||||
# Create volumes for several directories:
|
||||
# Create volumes
|
||||
VOLUME $FIREFLY_PATH/storage/export $FIREFLY_PATH/storage/upload
|
||||
|
||||
# Enable default site (Firefly III)
|
||||
@@ -79,15 +96,19 @@ COPY ./.deploy/docker/apache-firefly.conf /etc/apache2/sites-available/000-defau
|
||||
# Make sure we own Firefly III directory
|
||||
RUN chown -R www-data:www-data /var/www && chmod -R 775 $FIREFLY_PATH/storage
|
||||
|
||||
# Copy in Firefly Source
|
||||
WORKDIR $FIREFLY_PATH
|
||||
ADD . $FIREFLY_PATH
|
||||
|
||||
# Fix the link to curl:
|
||||
RUN rm -rf /usr/local/lib/libcurl.so.4 && ln -s /usr/lib/x86_64-linux-gnu/libcurl.so.4.4.0 /usr/local/lib/libcurl.so.4
|
||||
|
||||
# Run composer
|
||||
ENV COMPOSER_ALLOW_SUPERUSER 1
|
||||
RUN composer install --prefer-dist --no-dev --no-scripts --no-suggest
|
||||
|
||||
# Expose port 80
|
||||
EXPOSE 80
|
||||
|
||||
# Run the command on container startup
|
||||
CMD cron
|
||||
|
||||
# Run entrypoint thing
|
||||
ENTRYPOINT [".deploy/docker/entrypoint.sh"]
|
||||
|
||||
|
||||
@@ -35,7 +35,7 @@ use League\Fractal\Serializer\JsonApiSerializer;
|
||||
/**
|
||||
* Returns basic information about this installation.
|
||||
*
|
||||
* Class AboutController
|
||||
* Class AboutController.
|
||||
*/
|
||||
class AboutController extends Controller
|
||||
{
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* AccountController.php
|
||||
* Copyright (c) 2018 thegrumpydictator@gmail.com
|
||||
@@ -41,13 +40,15 @@ use League\Fractal\Resource\Item;
|
||||
use League\Fractal\Serializer\JsonApiSerializer;
|
||||
|
||||
/**
|
||||
* Class AccountController
|
||||
* Class AccountController.
|
||||
*
|
||||
* @SuppressWarnings(PHPMD.CouplingBetweenObjects)
|
||||
*/
|
||||
class AccountController extends Controller
|
||||
{
|
||||
/** @var CurrencyRepositoryInterface */
|
||||
/** @var CurrencyRepositoryInterface The currency repository */
|
||||
private $currencyRepository;
|
||||
/** @var AccountRepositoryInterface */
|
||||
/** @var AccountRepositoryInterface The account repository */
|
||||
private $repository;
|
||||
|
||||
/**
|
||||
@@ -125,6 +126,8 @@ class AccountController extends Controller
|
||||
}
|
||||
|
||||
/**
|
||||
* Show single instance.
|
||||
*
|
||||
* @param Request $request
|
||||
* @param Account $account
|
||||
*
|
||||
@@ -146,6 +149,8 @@ class AccountController extends Controller
|
||||
}
|
||||
|
||||
/**
|
||||
* Store a new instance.
|
||||
*
|
||||
* @param AccountRequest $request
|
||||
*
|
||||
* @return \Illuminate\Http\JsonResponse
|
||||
@@ -197,52 +202,30 @@ class AccountController extends Controller
|
||||
}
|
||||
|
||||
/**
|
||||
* All the available types.
|
||||
*
|
||||
* @param string $type
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
private function mapTypes(string $type): array
|
||||
{
|
||||
$types = [
|
||||
'all' => [
|
||||
AccountType::DEFAULT,
|
||||
AccountType::CASH,
|
||||
AccountType::ASSET,
|
||||
AccountType::EXPENSE,
|
||||
AccountType::REVENUE,
|
||||
AccountType::INITIAL_BALANCE,
|
||||
AccountType::BENEFICIARY,
|
||||
AccountType::IMPORT,
|
||||
AccountType::RECONCILIATION,
|
||||
AccountType::LOAN,
|
||||
],
|
||||
'asset' => [
|
||||
AccountType::DEFAULT,
|
||||
AccountType::ASSET,
|
||||
],
|
||||
'cash' => [
|
||||
AccountType::CASH,
|
||||
],
|
||||
'expense' => [
|
||||
AccountType::EXPENSE,
|
||||
AccountType::BENEFICIARY,
|
||||
],
|
||||
'revenue' => [
|
||||
AccountType::REVENUE,
|
||||
],
|
||||
'special' => [
|
||||
AccountType::CASH,
|
||||
AccountType::INITIAL_BALANCE,
|
||||
AccountType::IMPORT,
|
||||
AccountType::RECONCILIATION,
|
||||
AccountType::LOAN,
|
||||
],
|
||||
'hidden' => [
|
||||
AccountType::INITIAL_BALANCE,
|
||||
AccountType::IMPORT,
|
||||
AccountType::RECONCILIATION,
|
||||
AccountType::LOAN,
|
||||
],
|
||||
$types = [
|
||||
'all' => [AccountType::DEFAULT, AccountType::CASH, AccountType::ASSET, AccountType::EXPENSE, AccountType::REVENUE,
|
||||
AccountType::INITIAL_BALANCE, AccountType::BENEFICIARY, AccountType::IMPORT, AccountType::RECONCILIATION,
|
||||
AccountType::LOAN,],
|
||||
'asset' => [AccountType::DEFAULT, AccountType::ASSET,],
|
||||
'cash' => [AccountType::CASH,],
|
||||
'expense' => [AccountType::EXPENSE, AccountType::BENEFICIARY,],
|
||||
'revenue' => [AccountType::REVENUE,],
|
||||
'special' => [AccountType::CASH, AccountType::INITIAL_BALANCE, AccountType::IMPORT, AccountType::RECONCILIATION,
|
||||
AccountType::LOAN,],
|
||||
'hidden' => [AccountType::INITIAL_BALANCE, AccountType::IMPORT, AccountType::RECONCILIATION, AccountType::LOAN,],
|
||||
'liability' => [AccountType::DEBT, AccountType::LOAN, AccountType::MORTGAGE, AccountType::CREDITCARD],
|
||||
'liabilities' => [AccountType::DEBT, AccountType::LOAN, AccountType::MORTGAGE, AccountType::CREDITCARD],
|
||||
'cc' => [AccountType::CREDITCARD],
|
||||
'creditcard' => [AccountType::CREDITCARD],
|
||||
'credit_card' => [AccountType::CREDITCARD],
|
||||
AccountType::DEFAULT => [AccountType::DEFAULT],
|
||||
AccountType::CASH => [AccountType::CASH],
|
||||
AccountType::ASSET => [AccountType::ASSET],
|
||||
@@ -253,11 +236,16 @@ class AccountController extends Controller
|
||||
AccountType::IMPORT => [AccountType::IMPORT],
|
||||
AccountType::RECONCILIATION => [AccountType::RECONCILIATION],
|
||||
AccountType::LOAN => [AccountType::LOAN],
|
||||
AccountType::MORTGAGE => [AccountType::MORTGAGE],
|
||||
AccountType::DEBT => [AccountType::DEBT],
|
||||
AccountType::CREDITCARD => [AccountType::CREDITCARD],
|
||||
|
||||
];
|
||||
$return = $types['all'];
|
||||
if (isset($types[$type])) {
|
||||
return $types[$type];
|
||||
$return = $types[$type];
|
||||
}
|
||||
|
||||
return $types['all']; // @codeCoverageIgnore
|
||||
return $return; // @codeCoverageIgnore
|
||||
}
|
||||
}
|
||||
|
||||
@@ -41,11 +41,13 @@ use League\Fractal\Resource\Item;
|
||||
use League\Fractal\Serializer\JsonApiSerializer;
|
||||
|
||||
/**
|
||||
* Class AttachmentController
|
||||
* Class AttachmentController.
|
||||
*
|
||||
* @SuppressWarnings(PHPMD.CouplingBetweenObjects)
|
||||
*/
|
||||
class AttachmentController extends Controller
|
||||
{
|
||||
/** @var AttachmentRepositoryInterface */
|
||||
/** @var AttachmentRepositoryInterface The attachment repository */
|
||||
private $repository;
|
||||
|
||||
/**
|
||||
@@ -81,6 +83,8 @@ class AttachmentController extends Controller
|
||||
}
|
||||
|
||||
/**
|
||||
* Download an attachment.
|
||||
*
|
||||
* @param Attachment $attachment
|
||||
*
|
||||
* @return LaravelResponse
|
||||
@@ -88,7 +92,7 @@ class AttachmentController extends Controller
|
||||
*/
|
||||
public function download(Attachment $attachment): LaravelResponse
|
||||
{
|
||||
if ($attachment->uploaded === false) {
|
||||
if (false === $attachment->uploaded) {
|
||||
throw new FireflyException('No file has been uploaded for this attachment (yet).');
|
||||
}
|
||||
if ($this->repository->exists($attachment)) {
|
||||
@@ -211,6 +215,8 @@ class AttachmentController extends Controller
|
||||
}
|
||||
|
||||
/**
|
||||
* Upload an attachment.
|
||||
*
|
||||
* @param Request $request
|
||||
* @param Attachment $attachment
|
||||
*
|
||||
@@ -226,4 +232,4 @@ class AttachmentController extends Controller
|
||||
return response()->json([], 204);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -24,6 +24,7 @@ declare(strict_types=1);
|
||||
namespace FireflyIII\Api\V1\Controllers;
|
||||
|
||||
use FireflyIII\Api\V1\Requests\AvailableBudgetRequest;
|
||||
use FireflyIII\Exceptions\FireflyException;
|
||||
use FireflyIII\Models\AvailableBudget;
|
||||
use FireflyIII\Repositories\Budget\BudgetRepositoryInterface;
|
||||
use FireflyIII\Repositories\Currency\CurrencyRepositoryInterface;
|
||||
@@ -39,13 +40,15 @@ use League\Fractal\Resource\Item;
|
||||
use League\Fractal\Serializer\JsonApiSerializer;
|
||||
|
||||
/**
|
||||
* Class AvailableBudgetController
|
||||
* Class AvailableBudgetController.
|
||||
*
|
||||
* @SuppressWarnings(PHPMD.CouplingBetweenObjects)
|
||||
*/
|
||||
class AvailableBudgetController extends Controller
|
||||
{
|
||||
/** @var CurrencyRepositoryInterface */
|
||||
/** @var CurrencyRepositoryInterface The currency repository */
|
||||
private $currencyRepository;
|
||||
/** @var BudgetRepositoryInterface */
|
||||
/** @var BudgetRepositoryInterface The budget repository */
|
||||
private $repository;
|
||||
|
||||
/**
|
||||
@@ -144,11 +147,18 @@ class AvailableBudgetController extends Controller
|
||||
* @param AvailableBudgetRequest $request
|
||||
*
|
||||
* @return JsonResponse
|
||||
* @throws FireflyException
|
||||
*/
|
||||
public function store(AvailableBudgetRequest $request): JsonResponse
|
||||
{
|
||||
$data = $request->getAll();
|
||||
$currency = $this->currencyRepository->findNull($data['transaction_currency_id']);
|
||||
$data = $request->getAll();
|
||||
$currency = $this->currencyRepository->findNull($data['currency_id']);
|
||||
if (null === $currency) {
|
||||
$currency = $this->currencyRepository->findByCodeNull($data['currency_code']);
|
||||
}
|
||||
if (null === $currency) {
|
||||
throw new FireflyException('Could not find the indicated currency.');
|
||||
}
|
||||
$availableBudget = $this->repository->setAvailableBudget($currency, $data['start_date'], $data['end_date'], $data['amount']);
|
||||
$manager = new Manager;
|
||||
$baseUrl = $request->getSchemeAndHttpHost() . '/api/v1';
|
||||
@@ -159,6 +169,8 @@ class AvailableBudgetController extends Controller
|
||||
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', 'application/vnd.api+json');
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Update the specified resource in storage.
|
||||
*
|
||||
@@ -180,4 +192,4 @@ class AvailableBudgetController extends Controller
|
||||
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', 'application/vnd.api+json');
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -29,6 +29,7 @@ use FireflyIII\Exceptions\FireflyException;
|
||||
use FireflyIII\Models\Bill;
|
||||
use FireflyIII\Repositories\Bill\BillRepositoryInterface;
|
||||
use FireflyIII\Transformers\BillTransformer;
|
||||
use FireflyIII\User;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Collection;
|
||||
@@ -39,11 +40,11 @@ use League\Fractal\Resource\Item;
|
||||
use League\Fractal\Serializer\JsonApiSerializer;
|
||||
|
||||
/**
|
||||
* Class BillController
|
||||
* Class BillController.
|
||||
*/
|
||||
class BillController extends Controller
|
||||
{
|
||||
/** @var BillRepositoryInterface */
|
||||
/** @var BillRepositoryInterface The bill repository */
|
||||
private $repository;
|
||||
|
||||
/**
|
||||
@@ -54,9 +55,12 @@ class BillController extends Controller
|
||||
parent::__construct();
|
||||
$this->middleware(
|
||||
function ($request, $next) {
|
||||
/** @var User $admin */
|
||||
$admin = auth()->user();
|
||||
|
||||
/** @var BillRepositoryInterface repository */
|
||||
$this->repository = app(BillRepositoryInterface::class);
|
||||
$this->repository->setUser(auth()->user());
|
||||
$this->repository->setUser($admin);
|
||||
|
||||
return $next($request);
|
||||
}
|
||||
@@ -103,6 +107,8 @@ class BillController extends Controller
|
||||
|
||||
|
||||
/**
|
||||
* Show the specified bill.
|
||||
*
|
||||
* @param Request $request
|
||||
* @param Bill $bill
|
||||
*
|
||||
@@ -124,6 +130,8 @@ class BillController extends Controller
|
||||
}
|
||||
|
||||
/**
|
||||
* Store a bill.
|
||||
*
|
||||
* @param BillRequest $request
|
||||
*
|
||||
* @return JsonResponse
|
||||
@@ -147,6 +155,8 @@ class BillController extends Controller
|
||||
|
||||
|
||||
/**
|
||||
* Update a bill.
|
||||
*
|
||||
* @param BillRequest $request
|
||||
* @param Bill $bill
|
||||
*
|
||||
|
||||
@@ -28,6 +28,7 @@ use FireflyIII\Exceptions\FireflyException;
|
||||
use FireflyIII\Models\Budget;
|
||||
use FireflyIII\Repositories\Budget\BudgetRepositoryInterface;
|
||||
use FireflyIII\Transformers\BudgetTransformer;
|
||||
use FireflyIII\User;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Pagination\LengthAwarePaginator;
|
||||
@@ -38,11 +39,13 @@ use League\Fractal\Resource\Item;
|
||||
use League\Fractal\Serializer\JsonApiSerializer;
|
||||
|
||||
/**
|
||||
* Class BudgetController
|
||||
* Class BudgetController.
|
||||
*
|
||||
* @SuppressWarnings(PHPMD.CouplingBetweenObjects)
|
||||
*/
|
||||
class BudgetController extends Controller
|
||||
{
|
||||
/** @var BudgetRepositoryInterface */
|
||||
/** @var BudgetRepositoryInterface The budget repository */
|
||||
private $repository;
|
||||
|
||||
/**
|
||||
@@ -53,9 +56,12 @@ class BudgetController extends Controller
|
||||
parent::__construct();
|
||||
$this->middleware(
|
||||
function ($request, $next) {
|
||||
/** @var User $admin */
|
||||
$admin = auth()->user();
|
||||
|
||||
/** @var BudgetRepositoryInterface repository */
|
||||
$this->repository = app(BudgetRepositoryInterface::class);
|
||||
$this->repository->setUser(auth()->user());
|
||||
$this->repository->setUser($admin);
|
||||
|
||||
return $next($request);
|
||||
}
|
||||
@@ -111,6 +117,8 @@ class BudgetController extends Controller
|
||||
|
||||
|
||||
/**
|
||||
* Show a budget.
|
||||
*
|
||||
* @param Request $request
|
||||
* @param Budget $budget
|
||||
*
|
||||
@@ -132,6 +140,8 @@ class BudgetController extends Controller
|
||||
}
|
||||
|
||||
/**
|
||||
* Store a budget.
|
||||
*
|
||||
* @param BudgetRequest $request
|
||||
*
|
||||
* @return JsonResponse
|
||||
@@ -154,6 +164,8 @@ class BudgetController extends Controller
|
||||
|
||||
|
||||
/**
|
||||
* Update a budget.
|
||||
*
|
||||
* @param BudgetRequest $request
|
||||
* @param Budget $budget
|
||||
*
|
||||
@@ -173,4 +185,4 @@ class BudgetController extends Controller
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -23,9 +23,7 @@ declare(strict_types=1);
|
||||
|
||||
namespace FireflyIII\Api\V1\Controllers;
|
||||
|
||||
use Carbon\Carbon;
|
||||
use Exception;
|
||||
use FireflyIII\Api\V1\Requests\AvailableBudgetRequest;
|
||||
|
||||
use FireflyIII\Api\V1\Requests\BudgetLimitRequest;
|
||||
use FireflyIII\Exceptions\FireflyException;
|
||||
use FireflyIII\Models\BudgetLimit;
|
||||
@@ -36,23 +34,21 @@ use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Pagination\LengthAwarePaginator;
|
||||
use Illuminate\Support\Collection;
|
||||
use InvalidArgumentException;
|
||||
use League\Fractal\Manager;
|
||||
use League\Fractal\Pagination\IlluminatePaginatorAdapter;
|
||||
use League\Fractal\Resource\Collection as FractalCollection;
|
||||
use League\Fractal\Resource\Item;
|
||||
use League\Fractal\Serializer\JsonApiSerializer;
|
||||
use Log;
|
||||
use Throwable;
|
||||
|
||||
|
||||
/**
|
||||
* Class BudgetLimitController
|
||||
* Class BudgetLimitController.
|
||||
*
|
||||
* @SuppressWarnings(PHPMD.CouplingBetweenObjects)
|
||||
*/
|
||||
class BudgetLimitController extends Controller
|
||||
{
|
||||
///** @var CurrencyRepositoryInterface */
|
||||
//private $currencyRepository;
|
||||
/** @var BudgetRepositoryInterface */
|
||||
/** @var BudgetRepositoryInterface The budget repository */
|
||||
private $repository;
|
||||
|
||||
/**
|
||||
@@ -66,7 +62,6 @@ class BudgetLimitController extends Controller
|
||||
/** @var User $user */
|
||||
$user = auth()->user();
|
||||
$this->repository = app(BudgetRepositoryInterface::class);
|
||||
//$this->currencyRepository = app(CurrencyRepositoryInterface::class);
|
||||
$this->repository->setUser($user);
|
||||
|
||||
return $next($request);
|
||||
@@ -97,56 +92,26 @@ class BudgetLimitController extends Controller
|
||||
*/
|
||||
public function index(Request $request): JsonResponse
|
||||
{
|
||||
// create some objects:
|
||||
$manager = new Manager;
|
||||
$baseUrl = $request->getSchemeAndHttpHost() . '/api/v1';
|
||||
|
||||
// read budget from request
|
||||
$manager = new Manager;
|
||||
$baseUrl = $request->getSchemeAndHttpHost() . '/api/v1';
|
||||
$budgetId = (int)($request->get('budget_id') ?? 0);
|
||||
$budget = null;
|
||||
if ($budgetId > 0) {
|
||||
$budget = $this->repository->findNull($budgetId);
|
||||
}
|
||||
// read start date from request
|
||||
$start = null;
|
||||
try {
|
||||
$start = Carbon::createFromFormat('Y-m-d', $request->get('start'));
|
||||
$this->parameters->set('start', $start->format('Y-m-d'));
|
||||
} catch (InvalidArgumentException $e) {
|
||||
Log::debug(sprintf('Could not parse start date "%s": %s', $request->get('start'), $e->getMessage()));
|
||||
|
||||
}
|
||||
|
||||
// read end date from request
|
||||
$end = null;
|
||||
try {
|
||||
$end = Carbon::createFromFormat('Y-m-d', $request->get('end'));
|
||||
$this->parameters->set('end', $end->format('Y-m-d'));
|
||||
} catch (InvalidArgumentException $e) {
|
||||
Log::debug(sprintf('Could not parse end date "%s": %s', $request->get('end'), $e->getMessage()));
|
||||
}
|
||||
$budget = $this->repository->findNull($budgetId);
|
||||
$pageSize = (int)app('preferences')->getForUser(auth()->user(), 'listPageSize', 50)->data;
|
||||
$this->parameters->set('budget_id', $budgetId);
|
||||
|
||||
// types to get, page size:
|
||||
$pageSize = (int)app('preferences')->getForUser(auth()->user(), 'listPageSize', 50)->data;
|
||||
|
||||
// get list of budget limits. Count it and split it.
|
||||
$collection = new Collection;
|
||||
if (null === $budget) {
|
||||
$collection = $this->repository->getAllBudgetLimits($start, $end);
|
||||
$collection = $this->repository->getAllBudgetLimits($this->parameters->get('start'), $this->parameters->get('end'));
|
||||
}
|
||||
if (null !== $budget) {
|
||||
$collection = $this->repository->getBudgetLimits($budget, $start, $end);
|
||||
$collection = $this->repository->getBudgetLimits($budget, $this->parameters->get('start'), $this->parameters->get('end'));
|
||||
}
|
||||
|
||||
$count = $collection->count();
|
||||
$budgetLimits = $collection->slice(($this->parameters->get('page') - 1) * $pageSize, $pageSize);
|
||||
|
||||
// make paginator:
|
||||
$paginator = new LengthAwarePaginator($budgetLimits, $count, $pageSize, $this->parameters->get('page'));
|
||||
$paginator = new LengthAwarePaginator($budgetLimits, $count, $pageSize, $this->parameters->get('page'));
|
||||
$paginator->setPath(route('api.v1.budget_limits.index') . $this->buildParams());
|
||||
|
||||
// present to user.
|
||||
$manager->setSerializer(new JsonApiSerializer($baseUrl));
|
||||
$resource = new FractalCollection($budgetLimits, new BudgetLimitTransformer($this->parameters), 'budget_limits');
|
||||
$resource->setPaginator(new IlluminatePaginatorAdapter($paginator));
|
||||
@@ -206,8 +171,8 @@ class BudgetLimitController extends Controller
|
||||
/**
|
||||
* Update the specified resource in storage.
|
||||
*
|
||||
* @param AvailableBudgetRequest $request
|
||||
* @param BudgetLimit $budgetLimit
|
||||
* @param BudgetLimitRequest $request
|
||||
* @param BudgetLimit $budgetLimit
|
||||
*
|
||||
* @return JsonResponse
|
||||
*/
|
||||
@@ -229,4 +194,4 @@ class BudgetLimitController extends Controller
|
||||
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', 'application/vnd.api+json');
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -28,6 +28,7 @@ use FireflyIII\Exceptions\FireflyException;
|
||||
use FireflyIII\Models\Category;
|
||||
use FireflyIII\Repositories\Category\CategoryRepositoryInterface;
|
||||
use FireflyIII\Transformers\CategoryTransformer;
|
||||
use FireflyIII\User;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Pagination\LengthAwarePaginator;
|
||||
@@ -38,11 +39,13 @@ use League\Fractal\Resource\Item;
|
||||
use League\Fractal\Serializer\JsonApiSerializer;
|
||||
|
||||
/**
|
||||
* Class CategoryController
|
||||
* Class CategoryController.
|
||||
*
|
||||
* @SuppressWarnings(PHPMD.CouplingBetweenObjects)
|
||||
*/
|
||||
class CategoryController extends Controller
|
||||
{
|
||||
/** @var CategoryRepositoryInterface */
|
||||
/** @var CategoryRepositoryInterface The category repository */
|
||||
private $repository;
|
||||
|
||||
/**
|
||||
@@ -53,9 +56,12 @@ class CategoryController extends Controller
|
||||
parent::__construct();
|
||||
$this->middleware(
|
||||
function ($request, $next) {
|
||||
/** @var User $admin */
|
||||
$admin = auth()->user();
|
||||
|
||||
/** @var CategoryRepositoryInterface repository */
|
||||
$this->repository = app(CategoryRepositoryInterface::class);
|
||||
$this->repository->setUser(auth()->user());
|
||||
$this->repository->setUser($admin);
|
||||
|
||||
return $next($request);
|
||||
}
|
||||
@@ -111,6 +117,8 @@ class CategoryController extends Controller
|
||||
|
||||
|
||||
/**
|
||||
* Show the category.
|
||||
*
|
||||
* @param Request $request
|
||||
* @param Category $category
|
||||
*
|
||||
@@ -132,6 +140,8 @@ class CategoryController extends Controller
|
||||
}
|
||||
|
||||
/**
|
||||
* Store new category.
|
||||
*
|
||||
* @param CategoryRequest $request
|
||||
*
|
||||
* @return JsonResponse
|
||||
@@ -154,6 +164,8 @@ class CategoryController extends Controller
|
||||
|
||||
|
||||
/**
|
||||
* Update the category.
|
||||
*
|
||||
* @param CategoryRequest $request
|
||||
* @param Category $category
|
||||
*
|
||||
@@ -173,4 +185,4 @@ class CategoryController extends Controller
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -25,39 +25,67 @@ namespace FireflyIII\Api\V1\Controllers;
|
||||
|
||||
use FireflyIII\Exceptions\FireflyException;
|
||||
use FireflyIII\Models\Configuration;
|
||||
use FireflyIII\Repositories\User\UserRepositoryInterface;
|
||||
use FireflyIII\User;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
/**
|
||||
* Class ConfigurationController
|
||||
* Class ConfigurationController.
|
||||
*/
|
||||
class ConfigurationController extends Controller
|
||||
{
|
||||
|
||||
|
||||
/** @var UserRepositoryInterface The user repository */
|
||||
private $repository;
|
||||
|
||||
/**
|
||||
* @throws FireflyException
|
||||
* BudgetController constructor.
|
||||
*/
|
||||
public function index()
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
$this->middleware(
|
||||
function ($request, $next) {
|
||||
/** @noinspection UnusedConstructorDependenciesInspection */
|
||||
$this->repository = app(UserRepositoryInterface::class);
|
||||
/** @var User $admin */
|
||||
$admin = auth()->user();
|
||||
|
||||
if (!$this->repository->hasRole($admin, 'owner')) {
|
||||
/** @noinspection ExceptionsAnnotatingAndHandlingInspection */
|
||||
throw new FireflyException('No access to method.'); // @codeCoverageIgnore
|
||||
}
|
||||
|
||||
return $next($request);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Show all configuration.
|
||||
*
|
||||
* @return JsonResponse
|
||||
*/
|
||||
public function index(): JsonResponse
|
||||
{
|
||||
if (!auth()->user()->hasRole('owner')) {
|
||||
throw new FireflyException('No access to method.'); // @codeCoverageIgnore
|
||||
}
|
||||
$configData = $this->getConfigData();
|
||||
|
||||
return response()->json(['data' => $configData], 200)->header('Content-Type', 'application/vnd.api+json');
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the configuration.
|
||||
*
|
||||
* @param Request $request
|
||||
*
|
||||
* @return JsonResponse
|
||||
* @throws FireflyException
|
||||
* @SuppressWarnings(PHPMD.CyclomaticComplexity)
|
||||
*/
|
||||
public function update(Request $request): JsonResponse
|
||||
{
|
||||
if (!auth()->user()->hasRole('owner')) {
|
||||
throw new FireflyException('No access to method.'); // @codeCoverageIgnore
|
||||
}
|
||||
$name = $request->get('name');
|
||||
$value = $request->get('value');
|
||||
$valid = ['is_demo_site', 'permission_update_check', 'single_user_mode'];
|
||||
@@ -68,7 +96,7 @@ class ConfigurationController extends Controller
|
||||
switch ($name) {
|
||||
case 'is_demo_site':
|
||||
case 'single_user_mode':
|
||||
$configValue = $value === 'true';
|
||||
$configValue = 'true' === $value;
|
||||
break;
|
||||
case 'permission_update_check':
|
||||
$configValue = (int)$value >= -1 && (int)$value <= 1 ? (int)$value : -1;
|
||||
@@ -81,7 +109,10 @@ class ConfigurationController extends Controller
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all config values.
|
||||
*
|
||||
* @return array
|
||||
* @SuppressWarnings(PHPMD.CyclomaticComplexity)
|
||||
*/
|
||||
private function getConfigData(): array
|
||||
{
|
||||
@@ -102,4 +133,4 @@ class ConfigurationController extends Controller
|
||||
|
||||
return $data;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -37,12 +37,13 @@ use Symfony\Component\HttpFoundation\ParameterBag;
|
||||
* Class Controller.
|
||||
*
|
||||
* @codeCoverageIgnore
|
||||
* @SuppressWarnings(PHPMD.NumberOfChildren)
|
||||
*/
|
||||
class Controller extends BaseController
|
||||
{
|
||||
use AuthorizesRequests, DispatchesJobs, ValidatesRequests;
|
||||
|
||||
/** @var ParameterBag */
|
||||
/** @var ParameterBag Parameters from the URI are stored here. */
|
||||
protected $parameters;
|
||||
|
||||
/**
|
||||
@@ -56,39 +57,42 @@ class Controller extends BaseController
|
||||
}
|
||||
|
||||
/**
|
||||
* Method to help build URI's.
|
||||
*
|
||||
* @return string
|
||||
*
|
||||
* @SuppressWarnings(PHPMD.CyclomaticComplexity)
|
||||
*/
|
||||
protected function buildParams(): string
|
||||
{
|
||||
$return = '?';
|
||||
$params = [];
|
||||
foreach ($this->parameters as $key => $value) {
|
||||
if ($key === 'page') {
|
||||
if ('page' === $key) {
|
||||
continue;
|
||||
}
|
||||
if ($value instanceof Carbon) {
|
||||
$params[$key] = $value->format('Y-m-d');
|
||||
continue;
|
||||
}
|
||||
if (!$value instanceof Carbon) {
|
||||
$params[$key] = $value;
|
||||
}
|
||||
$params[$key] = $value;
|
||||
}
|
||||
$return .= http_build_query($params);
|
||||
if (\strlen($return) === 1) {
|
||||
return '';
|
||||
}
|
||||
|
||||
return $return;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method to grab all parameters from the URI.
|
||||
*
|
||||
* @return ParameterBag
|
||||
* @SuppressWarnings(PHPMD.CyclomaticComplexity)
|
||||
*/
|
||||
private function getParameters(): ParameterBag
|
||||
{
|
||||
$bag = new ParameterBag;
|
||||
$page = (int)request()->get('page');
|
||||
if ($page === 0) {
|
||||
if (0 === $page) {
|
||||
$page = 1;
|
||||
}
|
||||
$bag->set('page', $page);
|
||||
|
||||
@@ -30,6 +30,7 @@ use FireflyIII\Models\TransactionCurrency;
|
||||
use FireflyIII\Repositories\Currency\CurrencyRepositoryInterface;
|
||||
use FireflyIII\Repositories\User\UserRepositoryInterface;
|
||||
use FireflyIII\Transformers\CurrencyTransformer;
|
||||
use FireflyIII\User;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Pagination\LengthAwarePaginator;
|
||||
@@ -40,29 +41,32 @@ use League\Fractal\Resource\Item;
|
||||
use League\Fractal\Serializer\JsonApiSerializer;
|
||||
|
||||
/**
|
||||
* Class CurrencyController
|
||||
* Class CurrencyController.
|
||||
*
|
||||
* @SuppressWarnings(PHPMD.CouplingBetweenObjects)
|
||||
*/
|
||||
class CurrencyController extends Controller
|
||||
{
|
||||
/** @var CurrencyRepositoryInterface */
|
||||
/** @var CurrencyRepositoryInterface The currency repository */
|
||||
private $repository;
|
||||
/** @var UserRepositoryInterface */
|
||||
/** @var UserRepositoryInterface The user repository */
|
||||
private $userRepository;
|
||||
|
||||
/**
|
||||
* CurrencyRepository constructor.
|
||||
*
|
||||
* @throws FireflyException
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
$this->middleware(
|
||||
function ($request, $next) {
|
||||
/** @var User $admin */
|
||||
$admin = auth()->user();
|
||||
|
||||
/** @var CurrencyRepositoryInterface repository */
|
||||
$this->repository = app(CurrencyRepositoryInterface::class);
|
||||
$this->userRepository = app(UserRepositoryInterface::class);
|
||||
$this->repository->setUser(auth()->user());
|
||||
$this->repository->setUser($admin);
|
||||
|
||||
return $next($request);
|
||||
}
|
||||
@@ -79,7 +83,10 @@ class CurrencyController extends Controller
|
||||
*/
|
||||
public function delete(TransactionCurrency $currency): JsonResponse
|
||||
{
|
||||
if (!$this->userRepository->hasRole(auth()->user(), 'owner')) {
|
||||
/** @var User $admin */
|
||||
$admin = auth()->user();
|
||||
|
||||
if (!$this->userRepository->hasRole($admin, 'owner')) {
|
||||
// access denied:
|
||||
throw new FireflyException('No access to method, user is not owner.'); // @codeCoverageIgnore
|
||||
}
|
||||
@@ -123,6 +130,8 @@ class CurrencyController extends Controller
|
||||
|
||||
|
||||
/**
|
||||
* Show a currency.
|
||||
*
|
||||
* @param Request $request
|
||||
* @param TransactionCurrency $currency
|
||||
*
|
||||
@@ -146,6 +155,8 @@ class CurrencyController extends Controller
|
||||
}
|
||||
|
||||
/**
|
||||
* Store new currency.
|
||||
*
|
||||
* @param CurrencyRequest $request
|
||||
*
|
||||
* @return JsonResponse
|
||||
@@ -155,11 +166,11 @@ class CurrencyController extends Controller
|
||||
{
|
||||
$currency = $this->repository->store($request->getAll());
|
||||
|
||||
if ($request->boolean('default') === true) {
|
||||
app('preferences')->set('currencyPreference', $currency->code);
|
||||
app('preferences')->mark();
|
||||
}
|
||||
if (null !== $currency) {
|
||||
if (true === $request->boolean('default')) {
|
||||
app('preferences')->set('currencyPreference', $currency->code);
|
||||
app('preferences')->mark();
|
||||
}
|
||||
$manager = new Manager();
|
||||
$baseUrl = $request->getSchemeAndHttpHost() . '/api/v1';
|
||||
$manager->setSerializer(new JsonApiSerializer($baseUrl));
|
||||
@@ -176,6 +187,8 @@ class CurrencyController extends Controller
|
||||
|
||||
|
||||
/**
|
||||
* Update a currency.
|
||||
*
|
||||
* @param CurrencyRequest $request
|
||||
* @param TransactionCurrency $currency
|
||||
*
|
||||
@@ -186,7 +199,7 @@ class CurrencyController extends Controller
|
||||
$data = $request->getAll();
|
||||
$currency = $this->repository->update($currency, $data);
|
||||
|
||||
if ($request->boolean('default') === true) {
|
||||
if (true === $request->boolean('default')) {
|
||||
app('preferences')->set('currencyPreference', $currency->code);
|
||||
app('preferences')->mark();
|
||||
}
|
||||
|
||||
@@ -28,20 +28,19 @@ use FireflyIII\Exceptions\FireflyException;
|
||||
use FireflyIII\Repositories\Currency\CurrencyRepositoryInterface;
|
||||
use FireflyIII\Services\Currency\ExchangeRateInterface;
|
||||
use FireflyIII\Transformers\CurrencyExchangeRateTransformer;
|
||||
use FireflyIII\User;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Http\Request;
|
||||
use InvalidArgumentException;
|
||||
use League\Fractal\Manager;
|
||||
use League\Fractal\Resource\Item;
|
||||
use Log;
|
||||
use League\Fractal\Serializer\JsonApiSerializer;
|
||||
|
||||
/**
|
||||
*
|
||||
* Class CurrencyExchangeRateController
|
||||
*/
|
||||
class CurrencyExchangeRateController extends Controller
|
||||
{
|
||||
/** @var CurrencyRepositoryInterface */
|
||||
/** @var CurrencyRepositoryInterface The currency repository */
|
||||
private $repository;
|
||||
|
||||
/**
|
||||
@@ -52,8 +51,11 @@ class CurrencyExchangeRateController extends Controller
|
||||
parent::__construct();
|
||||
$this->middleware(
|
||||
function ($request, $next) {
|
||||
/** @var User $admin */
|
||||
$admin = auth()->user();
|
||||
|
||||
$this->repository = app(CurrencyRepositoryInterface::class);
|
||||
$this->repository->setUser(auth()->user());
|
||||
$this->repository->setUser($admin);
|
||||
|
||||
return $next($request);
|
||||
}
|
||||
@@ -62,6 +64,8 @@ class CurrencyExchangeRateController extends Controller
|
||||
}
|
||||
|
||||
/**
|
||||
* Show an exchange rate.
|
||||
*
|
||||
* @param Request $request
|
||||
*
|
||||
* @return JsonResponse
|
||||
@@ -72,8 +76,8 @@ class CurrencyExchangeRateController extends Controller
|
||||
// create some objects:
|
||||
$manager = new Manager;
|
||||
$baseUrl = $request->getSchemeAndHttpHost() . '/api/v1';
|
||||
$manager->setSerializer(new JsonApiSerializer($baseUrl));
|
||||
|
||||
// currencies
|
||||
$fromCurrency = $this->repository->findByCodeNull($request->get('from') ?? 'EUR');
|
||||
$toCurrency = $this->repository->findByCodeNull($request->get('to') ?? 'USD');
|
||||
|
||||
@@ -84,27 +88,19 @@ class CurrencyExchangeRateController extends Controller
|
||||
throw new FireflyException('Unknown destination currency.');
|
||||
}
|
||||
|
||||
$dateObj = new Carbon;
|
||||
try {
|
||||
$dateObj = Carbon::createFromFormat('Y-m-d', $request->get('date') ?? date('Y-m-d'));
|
||||
} catch (InvalidArgumentException $e) {
|
||||
Log::debug($e->getMessage());
|
||||
}
|
||||
|
||||
|
||||
$dateObj = Carbon::createFromFormat('Y-m-d', $request->get('date') ?? date('Y-m-d'));
|
||||
$this->parameters->set('from', $fromCurrency->code);
|
||||
$this->parameters->set('to', $toCurrency->code);
|
||||
$this->parameters->set('date', $dateObj->format('Y-m-d'));
|
||||
|
||||
// get the exchange rate.
|
||||
$rate = $this->repository->getExchangeRate($fromCurrency, $toCurrency, $dateObj);
|
||||
if (null === $rate) {
|
||||
/** @var User $admin */
|
||||
$admin = auth()->user();
|
||||
// create service:
|
||||
/** @var ExchangeRateInterface $service */
|
||||
$service = app(ExchangeRateInterface::class);
|
||||
$service->setUser(auth()->user());
|
||||
|
||||
// get rate:
|
||||
$service->setUser($admin);
|
||||
$rate = $service->getRate($fromCurrency, $toCurrency, $dateObj);
|
||||
}
|
||||
|
||||
@@ -112,4 +108,4 @@ class CurrencyExchangeRateController extends Controller
|
||||
|
||||
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', 'application/vnd.api+json');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -39,13 +39,21 @@ use League\Fractal\Resource\Collection as FractalCollection;
|
||||
use League\Fractal\Resource\Item;
|
||||
use League\Fractal\Serializer\JsonApiSerializer;
|
||||
|
||||
/**
|
||||
* Class JournalLinkController.
|
||||
*
|
||||
* @SuppressWarnings(PHPMD.CouplingBetweenObjects)
|
||||
*/
|
||||
class JournalLinkController extends Controller
|
||||
{
|
||||
/** @var JournalRepositoryInterface */
|
||||
/** @var JournalRepositoryInterface The journal repository */
|
||||
private $journalRepository;
|
||||
/** @var LinkTypeRepositoryInterface */
|
||||
/** @var LinkTypeRepositoryInterface The link type repository */
|
||||
private $repository;
|
||||
|
||||
/**
|
||||
* JournalLinkController constructor.
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
@@ -167,14 +175,15 @@ class JournalLinkController extends Controller
|
||||
$data['direction'] = 'inward';
|
||||
|
||||
$journalLink = $this->repository->storeLink($data, $inward, $outward);
|
||||
|
||||
$resource = new Item($journalLink, new JournalLinkTransformer($this->parameters), 'journal_links');
|
||||
$resource = new Item($journalLink, new JournalLinkTransformer($this->parameters), 'journal_links');
|
||||
|
||||
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', 'application/vnd.api+json');
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Update object.
|
||||
*
|
||||
* @param JournalLinkRequest $request
|
||||
* @param TransactionJournalLink $journalLink
|
||||
*
|
||||
@@ -204,4 +213,4 @@ class JournalLinkController extends Controller
|
||||
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', 'application/vnd.api+json');
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -40,17 +40,21 @@ use League\Fractal\Resource\Item;
|
||||
use League\Fractal\Serializer\JsonApiSerializer;
|
||||
|
||||
/**
|
||||
* Class LinkTypeController.
|
||||
*
|
||||
* Class LinkTypeController
|
||||
* @SuppressWarnings(PHPMD.CouplingBetweenObjects)
|
||||
*/
|
||||
class LinkTypeController extends Controller
|
||||
{
|
||||
/** @var LinkTypeRepositoryInterface */
|
||||
/** @var LinkTypeRepositoryInterface The link type repository */
|
||||
private $repository;
|
||||
|
||||
/** @var UserRepositoryInterface */
|
||||
/** @var UserRepositoryInterface The user repository */
|
||||
private $userRepository;
|
||||
|
||||
/**
|
||||
* LinkTypeController constructor.
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
@@ -77,7 +81,7 @@ class LinkTypeController extends Controller
|
||||
*/
|
||||
public function delete(LinkType $linkType): JsonResponse
|
||||
{
|
||||
if ($linkType->editable === false) {
|
||||
if (false === $linkType->editable) {
|
||||
throw new FireflyException(sprintf('You cannot delete this link type (#%d, "%s")', $linkType->id, $linkType->name));
|
||||
}
|
||||
$this->repository->destroy($linkType, null);
|
||||
@@ -151,7 +155,10 @@ class LinkTypeController extends Controller
|
||||
*/
|
||||
public function store(LinkTypeRequest $request): JsonResponse
|
||||
{
|
||||
if (!$this->userRepository->hasRole(auth()->user(), 'owner')) {
|
||||
/** @var User $admin */
|
||||
$admin = auth()->user();
|
||||
|
||||
if (!$this->userRepository->hasRole($admin, 'owner')) {
|
||||
throw new FireflyException('You need the "owner"-role to do this.');
|
||||
}
|
||||
$data = $request->getAll();
|
||||
@@ -168,6 +175,8 @@ class LinkTypeController extends Controller
|
||||
}
|
||||
|
||||
/**
|
||||
* Update object.
|
||||
*
|
||||
* @param LinkTypeRequest $request
|
||||
* @param LinkType $linkType
|
||||
*
|
||||
@@ -176,10 +185,14 @@ class LinkTypeController extends Controller
|
||||
*/
|
||||
public function update(LinkTypeRequest $request, LinkType $linkType): JsonResponse
|
||||
{
|
||||
if ($linkType->editable === false) {
|
||||
if (false === $linkType->editable) {
|
||||
throw new FireflyException(sprintf('You cannot edit this link type (#%d, "%s")', $linkType->id, $linkType->name));
|
||||
}
|
||||
if (!$this->userRepository->hasRole(auth()->user(), 'owner')) {
|
||||
|
||||
/** @var User $admin */
|
||||
$admin = auth()->user();
|
||||
|
||||
if (!$this->userRepository->hasRole($admin, 'owner')) {
|
||||
throw new FireflyException('You need the "owner"-role to do this.');
|
||||
}
|
||||
|
||||
@@ -194,4 +207,4 @@ class LinkTypeController extends Controller
|
||||
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', 'application/vnd.api+json');
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -39,24 +39,30 @@ use League\Fractal\Resource\Item;
|
||||
use League\Fractal\Serializer\JsonApiSerializer;
|
||||
|
||||
/**
|
||||
* TODO order up and down.
|
||||
* Class PiggyBankController
|
||||
* Class PiggyBankController.
|
||||
*
|
||||
* @SuppressWarnings(PHPMD.CouplingBetweenObjects)
|
||||
*/
|
||||
class PiggyBankController extends Controller
|
||||
{
|
||||
|
||||
/** @var PiggyBankRepositoryInterface */
|
||||
/** @var PiggyBankRepositoryInterface The piggy bank repository */
|
||||
private $repository;
|
||||
|
||||
/**
|
||||
* PiggyBankController constructor.
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
$this->middleware(
|
||||
function ($request, $next) {
|
||||
/** @var User $user */
|
||||
$user = auth()->user();
|
||||
/** @var User $admin */
|
||||
$admin = auth()->user();
|
||||
|
||||
$this->repository = app(PiggyBankRepositoryInterface::class);
|
||||
$this->repository->setUser($admin);
|
||||
|
||||
|
||||
return $next($request);
|
||||
}
|
||||
@@ -155,11 +161,13 @@ class PiggyBankController extends Controller
|
||||
|
||||
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', 'application/vnd.api+json');
|
||||
}
|
||||
throw new FireflyException('Could not store new piggy bank.'); // @codeCoverageIgnore
|
||||
throw new FireflyException('Could not store new piggy bank.');
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Update piggy bank.
|
||||
*
|
||||
* @param PiggyBankRequest $request
|
||||
* @param PiggyBank $piggyBank
|
||||
*
|
||||
@@ -177,4 +185,4 @@ class PiggyBankController extends Controller
|
||||
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', 'application/vnd.api+json');
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -34,7 +34,6 @@ use League\Fractal\Manager;
|
||||
use League\Fractal\Resource\Collection as FractalCollection;
|
||||
use League\Fractal\Resource\Item;
|
||||
use League\Fractal\Serializer\JsonApiSerializer;
|
||||
use Preferences;
|
||||
|
||||
/**
|
||||
*
|
||||
@@ -42,20 +41,6 @@ use Preferences;
|
||||
*/
|
||||
class PreferenceController extends Controller
|
||||
{
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
$this->middleware(
|
||||
function ($request, $next) {
|
||||
/** @var User $user */
|
||||
$user = auth()->user();
|
||||
|
||||
// todo add local repositories.
|
||||
return $next($request);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* List all of them.
|
||||
*
|
||||
@@ -74,7 +59,7 @@ class PreferenceController extends Controller
|
||||
];
|
||||
$preferences = new Collection;
|
||||
foreach ($available as $name) {
|
||||
$pref = Preferences::getForUser($user, $name);
|
||||
$pref = app('preferences')->getForUser($user, $name);
|
||||
if (null !== $pref) {
|
||||
$preferences->push($pref);
|
||||
}
|
||||
@@ -116,10 +101,13 @@ class PreferenceController extends Controller
|
||||
}
|
||||
|
||||
/**
|
||||
* Update a preference.
|
||||
*
|
||||
* @param PreferenceRequest $request
|
||||
* @param Preference $preference
|
||||
*
|
||||
* @return JsonResponse
|
||||
* @SuppressWarnings(PHPMD.CyclomaticComplexity)
|
||||
*/
|
||||
public function update(PreferenceRequest $request, Preference $preference): JsonResponse
|
||||
{
|
||||
@@ -138,10 +126,10 @@ class PreferenceController extends Controller
|
||||
break;
|
||||
case 'customFiscalYear':
|
||||
case 'twoFactorAuthEnabled':
|
||||
$newValue = (int)$data['data'] === 1;
|
||||
$newValue = 1 === (int)$data['data'];
|
||||
break;
|
||||
}
|
||||
$result = Preferences::set($preference->name, $newValue);
|
||||
$result = app('preferences')->set($preference->name, $newValue);
|
||||
|
||||
// create some objects:
|
||||
$manager = new Manager;
|
||||
@@ -154,4 +142,4 @@ class PreferenceController extends Controller
|
||||
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', 'application/vnd.api+json');
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -38,14 +38,16 @@ use League\Fractal\Resource\Item;
|
||||
use League\Fractal\Serializer\JsonApiSerializer;
|
||||
|
||||
/**
|
||||
*
|
||||
* Class RecurrenceController
|
||||
*/
|
||||
class RecurrenceController extends Controller
|
||||
{
|
||||
/** @var RecurringRepositoryInterface */
|
||||
/** @var RecurringRepositoryInterface The recurring transaction repository */
|
||||
private $repository;
|
||||
|
||||
/**
|
||||
* RecurrenceController constructor.
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
@@ -155,6 +157,8 @@ class RecurrenceController extends Controller
|
||||
}
|
||||
|
||||
/**
|
||||
* Update single recurrence.
|
||||
*
|
||||
* @param RecurrenceRequest $request
|
||||
* @param Recurrence $recurrence
|
||||
*
|
||||
@@ -163,9 +167,6 @@ class RecurrenceController extends Controller
|
||||
public function update(RecurrenceRequest $request, Recurrence $recurrence): JsonResponse
|
||||
{
|
||||
$data = $request->getAll();
|
||||
|
||||
//
|
||||
|
||||
$category = $this->repository->update($recurrence, $data);
|
||||
$manager = new Manager();
|
||||
$baseUrl = $request->getSchemeAndHttpHost() . '/api/v1';
|
||||
@@ -176,4 +177,4 @@ class RecurrenceController extends Controller
|
||||
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', 'application/vnd.api+json');
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -42,9 +42,12 @@ use League\Fractal\Serializer\JsonApiSerializer;
|
||||
*/
|
||||
class RuleController extends Controller
|
||||
{
|
||||
/** @var RuleRepositoryInterface */
|
||||
/** @var RuleRepositoryInterface The rule repository */
|
||||
private $ruleRepository;
|
||||
|
||||
/**
|
||||
* RuleController constructor.
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
@@ -98,7 +101,7 @@ class RuleController extends Controller
|
||||
|
||||
// make paginator:
|
||||
$paginator = new LengthAwarePaginator($rules, $count, $pageSize, $this->parameters->get('page'));
|
||||
$paginator->setPath(route('api.v1.piggy_banks.index') . $this->buildParams());
|
||||
$paginator->setPath(route('api.v1.rules.index') . $this->buildParams());
|
||||
|
||||
// present to user.
|
||||
$manager->setSerializer(new JsonApiSerializer($baseUrl));
|
||||
@@ -136,7 +139,7 @@ class RuleController extends Controller
|
||||
/**
|
||||
* Store new object.
|
||||
*
|
||||
* @param Request $request
|
||||
* @param RuleRequest $request
|
||||
*
|
||||
* @return JsonResponse
|
||||
*/
|
||||
@@ -153,6 +156,8 @@ class RuleController extends Controller
|
||||
}
|
||||
|
||||
/**
|
||||
* Update a rule.
|
||||
*
|
||||
* @param RuleRequest $request
|
||||
* @param Rule $rule
|
||||
*
|
||||
@@ -160,9 +165,9 @@ class RuleController extends Controller
|
||||
*/
|
||||
public function update(RuleRequest $request, Rule $rule): JsonResponse
|
||||
{
|
||||
$rule = $this->ruleRepository->update($rule, $request->getAll());
|
||||
$manager = new Manager();
|
||||
$baseUrl = $request->getSchemeAndHttpHost() . '/api/v1';
|
||||
$rule = $this->ruleRepository->update($rule, $request->getAll());
|
||||
$manager = new Manager();
|
||||
$baseUrl = $request->getSchemeAndHttpHost() . '/api/v1';
|
||||
$manager->setSerializer(new JsonApiSerializer($baseUrl));
|
||||
|
||||
$resource = new Item($rule, new RuleTransformer($this->parameters), 'rules');
|
||||
@@ -170,4 +175,4 @@ class RuleController extends Controller
|
||||
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', 'application/vnd.api+json');
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -38,11 +38,17 @@ use League\Fractal\Resource\Item;
|
||||
use League\Fractal\Serializer\JsonApiSerializer;
|
||||
|
||||
|
||||
/**
|
||||
* Class RuleGroupController
|
||||
*/
|
||||
class RuleGroupController extends Controller
|
||||
{
|
||||
/** @var RuleGroupRepositoryInterface */
|
||||
/** @var RuleGroupRepositoryInterface The rule group repository */
|
||||
private $ruleGroupRepository;
|
||||
|
||||
/**
|
||||
* RuleGroupController constructor.
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
@@ -62,7 +68,7 @@ class RuleGroupController extends Controller
|
||||
/**
|
||||
* Delete the resource.
|
||||
*
|
||||
* @param string $object
|
||||
* @param RuleGroup $ruleGroup
|
||||
*
|
||||
* @return JsonResponse
|
||||
*/
|
||||
@@ -89,7 +95,7 @@ class RuleGroupController extends Controller
|
||||
// types to get, page size:
|
||||
$pageSize = (int)app('preferences')->getForUser(auth()->user(), 'listPageSize', 50)->data;
|
||||
|
||||
// get list of budgets. Count it and split it.
|
||||
// get list of rule groups. Count it and split it.
|
||||
$collection = $this->ruleGroupRepository->get();
|
||||
$count = $collection->count();
|
||||
$ruleGroups = $collection->slice(($this->parameters->get('page') - 1) * $pageSize, $pageSize);
|
||||
@@ -151,8 +157,10 @@ class RuleGroupController extends Controller
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Request $request
|
||||
* @param string $object
|
||||
* Update a rule group.
|
||||
*
|
||||
* @param RuleGroupRequest $request
|
||||
* @param RuleGroup $ruleGroup
|
||||
*
|
||||
* @return JsonResponse
|
||||
*/
|
||||
@@ -168,4 +176,4 @@ class RuleGroupController extends Controller
|
||||
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', 'application/vnd.api+json');
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -25,7 +25,8 @@ declare(strict_types=1);
|
||||
namespace FireflyIII\Api\V1\Controllers;
|
||||
|
||||
use FireflyIII\Api\V1\Requests\TransactionRequest;
|
||||
use FireflyIII\Helpers\Collector\JournalCollectorInterface;
|
||||
use FireflyIII\Exceptions\FireflyException;
|
||||
use FireflyIII\Helpers\Collector\TransactionCollectorInterface;
|
||||
use FireflyIII\Helpers\Filter\InternalTransferFilter;
|
||||
use FireflyIII\Helpers\Filter\NegativeAmountFilter;
|
||||
use FireflyIII\Helpers\Filter\PositiveAmountFilter;
|
||||
@@ -33,36 +34,39 @@ use FireflyIII\Models\Transaction;
|
||||
use FireflyIII\Models\TransactionType;
|
||||
use FireflyIII\Repositories\Journal\JournalRepositoryInterface;
|
||||
use FireflyIII\Transformers\TransactionTransformer;
|
||||
use FireflyIII\User;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Collection;
|
||||
use League\Fractal\Manager;
|
||||
use League\Fractal\Pagination\IlluminatePaginatorAdapter;
|
||||
use League\Fractal\Resource\Collection as FractalCollection;
|
||||
use League\Fractal\Serializer\JsonApiSerializer;
|
||||
use Log;
|
||||
|
||||
/**
|
||||
* Class TransactionController
|
||||
* @SuppressWarnings(PHPMD.CouplingBetweenObjects)
|
||||
*/
|
||||
class TransactionController extends Controller
|
||||
{
|
||||
|
||||
/** @var JournalRepositoryInterface */
|
||||
/** @var JournalRepositoryInterface The journal repository */
|
||||
private $repository;
|
||||
|
||||
/**
|
||||
* TransactionController constructor.
|
||||
*
|
||||
* @throws \FireflyIII\Exceptions\FireflyException
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
$this->middleware(
|
||||
function ($request, $next) {
|
||||
/** @var User $admin */
|
||||
$admin = auth()->user();
|
||||
|
||||
/** @var JournalRepositoryInterface repository */
|
||||
$this->repository = app(JournalRepositoryInterface::class);
|
||||
$this->repository->setUser(auth()->user());
|
||||
$this->repository->setUser($admin);
|
||||
|
||||
return $next($request);
|
||||
}
|
||||
@@ -74,9 +78,9 @@ class TransactionController extends Controller
|
||||
*
|
||||
* @param \FireflyIII\Models\Transaction $transaction
|
||||
*
|
||||
* @return \Illuminate\Http\Response
|
||||
* @return JsonResponse
|
||||
*/
|
||||
public function delete(Transaction $transaction)
|
||||
public function delete(Transaction $transaction): JsonResponse
|
||||
{
|
||||
$journal = $transaction->transactionJournal;
|
||||
$this->repository->destroy($journal);
|
||||
@@ -85,33 +89,32 @@ class TransactionController extends Controller
|
||||
}
|
||||
|
||||
/**
|
||||
* Show all transactions.
|
||||
*
|
||||
* @param Request $request
|
||||
*
|
||||
* @return \Illuminate\Http\JsonResponse
|
||||
* @return JsonResponse
|
||||
*/
|
||||
public function index(Request $request)
|
||||
public function index(Request $request): JsonResponse
|
||||
{
|
||||
$pageSize = (int)app('preferences')->getForUser(auth()->user(), 'listPageSize', 50)->data;
|
||||
|
||||
// read type from URI
|
||||
$type = $request->get('type') ?? 'default';
|
||||
$type = $request->get('type') ?? 'default';
|
||||
$this->parameters->set('type', $type);
|
||||
|
||||
// types to get, page size:
|
||||
$types = $this->mapTypes($this->parameters->get('type'));
|
||||
|
||||
$types = $this->mapTypes($this->parameters->get('type'));
|
||||
$manager = new Manager();
|
||||
$baseUrl = $request->getSchemeAndHttpHost() . '/api/v1';
|
||||
$manager->setSerializer(new JsonApiSerializer($baseUrl));
|
||||
|
||||
// collect transactions using the journal collector
|
||||
$collector = app(JournalCollectorInterface::class);
|
||||
$collector->setUser(auth()->user());
|
||||
/** @var User $admin */
|
||||
$admin = auth()->user();
|
||||
/** @var TransactionCollectorInterface $collector */
|
||||
$collector = app(TransactionCollectorInterface::class);
|
||||
$collector->setUser($admin);
|
||||
$collector->withOpposingAccount()->withCategoryInformation()->withBudgetInformation();
|
||||
$collector->setAllAssetAccounts();
|
||||
|
||||
// remove internal transfer filter:
|
||||
if (\in_array(TransactionType::TRANSFER, $types)) {
|
||||
if (\in_array(TransactionType::TRANSFER, $types, true)) {
|
||||
$collector->removeFilter(InternalTransferFilter::class);
|
||||
}
|
||||
|
||||
@@ -120,11 +123,10 @@ class TransactionController extends Controller
|
||||
}
|
||||
$collector->setLimit($pageSize)->setPage($this->parameters->get('page'));
|
||||
$collector->setTypes($types);
|
||||
$paginator = $collector->getPaginatedJournals();
|
||||
$paginator = $collector->getPaginatedTransactions();
|
||||
$paginator->setPath(route('api.v1.transactions.index') . $this->buildParams());
|
||||
$transactions = $paginator->getCollection();
|
||||
|
||||
|
||||
$resource = new FractalCollection($transactions, new TransactionTransformer($this->parameters), 'transactions');
|
||||
$resource->setPaginator(new IlluminatePaginatorAdapter($paginator));
|
||||
|
||||
@@ -133,13 +135,15 @@ class TransactionController extends Controller
|
||||
|
||||
|
||||
/**
|
||||
* Show a single transaction.
|
||||
*
|
||||
* @param Request $request
|
||||
* @param Transaction $transaction
|
||||
* @param string $include
|
||||
*
|
||||
* @return \Illuminate\Http\JsonResponse
|
||||
* @return JsonResponse
|
||||
*/
|
||||
public function show(Request $request, Transaction $transaction, string $include = null)
|
||||
public function show(Request $request, Transaction $transaction, string $include = null): JsonResponse
|
||||
{
|
||||
$manager = new Manager();
|
||||
$baseUrl = $request->getSchemeAndHttpHost() . '/api/v1';
|
||||
@@ -151,7 +155,7 @@ class TransactionController extends Controller
|
||||
$manager->parseIncludes($include);
|
||||
|
||||
// collect transactions using the journal collector
|
||||
$collector = app(JournalCollectorInterface::class);
|
||||
$collector = app(TransactionCollectorInterface::class);
|
||||
$collector->setUser(auth()->user());
|
||||
$collector->withOpposingAccount()->withCategoryInformation()->withBudgetInformation();
|
||||
// filter on specific journals.
|
||||
@@ -166,20 +170,23 @@ class TransactionController extends Controller
|
||||
$collector->addFilter(NegativeAmountFilter::class);
|
||||
}
|
||||
|
||||
$transactions = $collector->getJournals();
|
||||
$transactions = $collector->getTransactions();
|
||||
$resource = new FractalCollection($transactions, new TransactionTransformer($this->parameters), 'transactions');
|
||||
|
||||
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', 'application/vnd.api+json');
|
||||
}
|
||||
|
||||
/**
|
||||
* Store a new transaction.
|
||||
*
|
||||
* @param TransactionRequest $request
|
||||
*
|
||||
* @param JournalRepositoryInterface $repository
|
||||
*
|
||||
* @return \Illuminate\Http\JsonResponse
|
||||
* @throws FireflyException
|
||||
* @return JsonResponse
|
||||
*/
|
||||
public function store(TransactionRequest $request, JournalRepositoryInterface $repository)
|
||||
public function store(TransactionRequest $request, JournalRepositoryInterface $repository): JsonResponse
|
||||
{
|
||||
$data = $request->getAll();
|
||||
$data['user'] = auth()->user()->id;
|
||||
@@ -194,7 +201,7 @@ class TransactionController extends Controller
|
||||
$manager->parseIncludes($include);
|
||||
|
||||
// collect transactions using the journal collector
|
||||
$collector = app(JournalCollectorInterface::class);
|
||||
$collector = app(TransactionCollectorInterface::class);
|
||||
$collector->setUser(auth()->user());
|
||||
$collector->withOpposingAccount()->withCategoryInformation()->withBudgetInformation();
|
||||
// filter on specific journals.
|
||||
@@ -209,7 +216,7 @@ class TransactionController extends Controller
|
||||
$collector->addFilter(NegativeAmountFilter::class);
|
||||
}
|
||||
|
||||
$transactions = $collector->getJournals();
|
||||
$transactions = $collector->getTransactions();
|
||||
$resource = new FractalCollection($transactions, new TransactionTransformer($this->parameters), 'transactions');
|
||||
|
||||
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', 'application/vnd.api+json');
|
||||
@@ -217,23 +224,21 @@ class TransactionController extends Controller
|
||||
|
||||
|
||||
/**
|
||||
* Update a transaction.
|
||||
*
|
||||
* @param TransactionRequest $request
|
||||
* @param JournalRepositoryInterface $repository
|
||||
* @param Transaction $transaction
|
||||
*
|
||||
* @return \Illuminate\Http\JsonResponse
|
||||
* @return JsonResponse
|
||||
*/
|
||||
public function update(TransactionRequest $request, JournalRepositoryInterface $repository, Transaction $transaction)
|
||||
public function update(TransactionRequest $request, JournalRepositoryInterface $repository, Transaction $transaction): JsonResponse
|
||||
{
|
||||
$data = $request->getAll();
|
||||
$data['user'] = auth()->user()->id;
|
||||
|
||||
Log::debug('Inside transaction update');
|
||||
|
||||
$journal = $repository->update($transaction->transactionJournal, $data);
|
||||
|
||||
$manager = new Manager();
|
||||
$baseUrl = $request->getSchemeAndHttpHost() . '/api/v1';
|
||||
$journal = $repository->update($transaction->transactionJournal, $data);
|
||||
$manager = new Manager();
|
||||
$baseUrl = $request->getSchemeAndHttpHost() . '/api/v1';
|
||||
$manager->setSerializer(new JsonApiSerializer($baseUrl));
|
||||
|
||||
// add include parameter:
|
||||
@@ -242,7 +247,7 @@ class TransactionController extends Controller
|
||||
|
||||
// needs a lot of extra data to match the journal collector. Or just expand that one.
|
||||
// collect transactions using the journal collector
|
||||
$collector = app(JournalCollectorInterface::class);
|
||||
$collector = app(TransactionCollectorInterface::class);
|
||||
$collector->setUser(auth()->user());
|
||||
$collector->withOpposingAccount()->withCategoryInformation()->withBudgetInformation();
|
||||
// filter on specific journals.
|
||||
@@ -257,7 +262,7 @@ class TransactionController extends Controller
|
||||
$collector->addFilter(NegativeAmountFilter::class);
|
||||
}
|
||||
|
||||
$transactions = $collector->getJournals();
|
||||
$transactions = $collector->getTransactions();
|
||||
$resource = new FractalCollection($transactions, new TransactionTransformer($this->parameters), 'transactions');
|
||||
|
||||
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', 'application/vnd.api+json');
|
||||
@@ -265,72 +270,38 @@ class TransactionController extends Controller
|
||||
}
|
||||
|
||||
/**
|
||||
* All the types you can request.
|
||||
*
|
||||
* @param string $type
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
private function mapTypes(string $type): array
|
||||
{
|
||||
$types = [
|
||||
'all' => [
|
||||
TransactionType::WITHDRAWAL,
|
||||
TransactionType::DEPOSIT,
|
||||
TransactionType::TRANSFER,
|
||||
TransactionType::OPENING_BALANCE,
|
||||
TransactionType::RECONCILIATION,
|
||||
],
|
||||
'withdrawal' => [
|
||||
TransactionType::WITHDRAWAL,
|
||||
],
|
||||
'withdrawals' => [
|
||||
TransactionType::WITHDRAWAL,
|
||||
],
|
||||
'expense' => [
|
||||
TransactionType::WITHDRAWAL,
|
||||
],
|
||||
'income' => [
|
||||
TransactionType::DEPOSIT,
|
||||
],
|
||||
'deposit' => [
|
||||
TransactionType::DEPOSIT,
|
||||
],
|
||||
'deposits' => [
|
||||
TransactionType::DEPOSIT,
|
||||
],
|
||||
'transfer' => [
|
||||
TransactionType::TRANSFER,
|
||||
],
|
||||
'transfers' => [
|
||||
TransactionType::TRANSFER,
|
||||
],
|
||||
'opening_balance' => [
|
||||
TransactionType::OPENING_BALANCE,
|
||||
],
|
||||
'reconciliation' => [
|
||||
TransactionType::RECONCILIATION,
|
||||
],
|
||||
'reconciliations' => [
|
||||
TransactionType::RECONCILIATION,
|
||||
],
|
||||
'special' => [
|
||||
TransactionType::OPENING_BALANCE,
|
||||
TransactionType::RECONCILIATION,
|
||||
],
|
||||
'specials' => [
|
||||
TransactionType::OPENING_BALANCE,
|
||||
TransactionType::RECONCILIATION,
|
||||
],
|
||||
'default' => [
|
||||
TransactionType::WITHDRAWAL,
|
||||
TransactionType::DEPOSIT,
|
||||
TransactionType::TRANSFER,
|
||||
],
|
||||
$types = [
|
||||
'all' => [TransactionType::WITHDRAWAL, TransactionType::DEPOSIT, TransactionType::TRANSFER, TransactionType::OPENING_BALANCE,
|
||||
TransactionType::RECONCILIATION,],
|
||||
'withdrawal' => [TransactionType::WITHDRAWAL,],
|
||||
'withdrawals' => [TransactionType::WITHDRAWAL,],
|
||||
'expense' => [TransactionType::WITHDRAWAL,],
|
||||
'income' => [TransactionType::DEPOSIT,],
|
||||
'deposit' => [TransactionType::DEPOSIT,],
|
||||
'deposits' => [TransactionType::DEPOSIT,],
|
||||
'transfer' => [TransactionType::TRANSFER,],
|
||||
'transfers' => [TransactionType::TRANSFER,],
|
||||
'opening_balance' => [TransactionType::OPENING_BALANCE,],
|
||||
'reconciliation' => [TransactionType::RECONCILIATION,],
|
||||
'reconciliations' => [TransactionType::RECONCILIATION,],
|
||||
'special' => [TransactionType::OPENING_BALANCE, TransactionType::RECONCILIATION,],
|
||||
'specials' => [TransactionType::OPENING_BALANCE, TransactionType::RECONCILIATION,],
|
||||
'default' => [TransactionType::WITHDRAWAL, TransactionType::DEPOSIT, TransactionType::TRANSFER,],
|
||||
];
|
||||
$return = $types['default'];
|
||||
if (isset($types[$type])) {
|
||||
return $types[$type];
|
||||
$return = $types[$type];
|
||||
}
|
||||
|
||||
return $types['default']; // @codeCoverageIgnore
|
||||
return $return;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -29,6 +29,7 @@ use FireflyIII\Exceptions\FireflyException;
|
||||
use FireflyIII\Repositories\User\UserRepositoryInterface;
|
||||
use FireflyIII\Transformers\UserTransformer;
|
||||
use FireflyIII\User;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Pagination\LengthAwarePaginator;
|
||||
use League\Fractal\Manager;
|
||||
@@ -39,18 +40,18 @@ use League\Fractal\Serializer\JsonApiSerializer;
|
||||
|
||||
|
||||
/**
|
||||
* Class UserController
|
||||
* Class UserController.
|
||||
*
|
||||
* @SuppressWarnings(PHPMD.CouplingBetweenObjects)
|
||||
*/
|
||||
class UserController extends Controller
|
||||
{
|
||||
|
||||
/** @var UserRepositoryInterface */
|
||||
/** @var UserRepositoryInterface The user repository */
|
||||
private $repository;
|
||||
|
||||
/**
|
||||
* UserController constructor.
|
||||
*
|
||||
* @throws \FireflyIII\Exceptions\FireflyException
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
@@ -70,12 +71,14 @@ class UserController extends Controller
|
||||
*
|
||||
* @param \FireflyIII\User $user
|
||||
*
|
||||
* @return \Illuminate\Http\Response
|
||||
* @return JsonResponse
|
||||
* @throws FireflyException
|
||||
*/
|
||||
public function delete(User $user)
|
||||
public function delete(User $user): JsonResponse
|
||||
{
|
||||
if (auth()->user()->hasRole('owner')) {
|
||||
/** @var User $admin */
|
||||
$admin = auth()->user();
|
||||
if ($this->repository->hasRole($admin, 'owner')) {
|
||||
$this->repository->destroy($user);
|
||||
|
||||
return response()->json([], 204);
|
||||
@@ -88,9 +91,9 @@ class UserController extends Controller
|
||||
*
|
||||
* @param Request $request
|
||||
*
|
||||
* @return \Illuminate\Http\JsonResponse
|
||||
* @return JsonResponse
|
||||
*/
|
||||
public function index(Request $request)
|
||||
public function index(Request $request): JsonResponse
|
||||
{
|
||||
// user preferences
|
||||
$pageSize = (int)app('preferences')->getForUser(auth()->user(), 'listPageSize', 50)->data;
|
||||
@@ -117,12 +120,14 @@ class UserController extends Controller
|
||||
}
|
||||
|
||||
/**
|
||||
* Show a single user.
|
||||
*
|
||||
* @param Request $request
|
||||
* @param User $user
|
||||
*
|
||||
* @return \Illuminate\Http\JsonResponse
|
||||
* @return JsonResponse
|
||||
*/
|
||||
public function show(Request $request, User $user)
|
||||
public function show(Request $request, User $user): JsonResponse
|
||||
{
|
||||
// make manager
|
||||
$manager = new Manager();
|
||||
@@ -140,11 +145,13 @@ class UserController extends Controller
|
||||
}
|
||||
|
||||
/**
|
||||
* Store a new user.
|
||||
*
|
||||
* @param UserRequest $request
|
||||
*
|
||||
* @return \Illuminate\Http\JsonResponse
|
||||
* @return JsonResponse
|
||||
*/
|
||||
public function store(UserRequest $request)
|
||||
public function store(UserRequest $request): JsonResponse
|
||||
{
|
||||
$data = $request->getAll();
|
||||
$user = $this->repository->store($data);
|
||||
@@ -165,12 +172,14 @@ class UserController extends Controller
|
||||
}
|
||||
|
||||
/**
|
||||
* Update a user.
|
||||
*
|
||||
* @param UserRequest $request
|
||||
* @param User $user
|
||||
*
|
||||
* @return \Illuminate\Http\JsonResponse
|
||||
* @return JsonResponse
|
||||
*/
|
||||
public function update(UserRequest $request, User $user)
|
||||
public function update(UserRequest $request, User $user): JsonResponse
|
||||
{
|
||||
$data = $request->getAll();
|
||||
$user = $this->repository->update($user, $data);
|
||||
|
||||
@@ -23,7 +23,6 @@
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace FireflyIII\Api\V1\Requests;
|
||||
|
||||
/**
|
||||
* Class AccountRequest
|
||||
*/
|
||||
@@ -31,6 +30,8 @@ class AccountRequest extends Request
|
||||
{
|
||||
|
||||
/**
|
||||
* Authorize logged in users.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function authorize(): bool
|
||||
@@ -40,6 +41,8 @@ class AccountRequest extends Request
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all data from the request.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getAll(): array
|
||||
@@ -47,6 +50,7 @@ class AccountRequest extends Request
|
||||
$data = [
|
||||
'name' => $this->string('name'),
|
||||
'active' => $this->boolean('active'),
|
||||
'include_net_worth' => $this->boolean('include_net_worth'),
|
||||
'accountType' => $this->string('type'),
|
||||
'account_type_id' => null,
|
||||
'currency_id' => $this->integer('currency_id'),
|
||||
@@ -61,12 +65,28 @@ class AccountRequest extends Request
|
||||
'ccType' => $this->string('cc_type'),
|
||||
'ccMonthlyPaymentDate' => $this->string('cc_monthly_payment_date'),
|
||||
'notes' => $this->string('notes'),
|
||||
'interest' => $this->string('interest'),
|
||||
'interest_period' => $this->string('interest_period'),
|
||||
];
|
||||
// new fields for liabilities
|
||||
// 'liability_type' => $this->string('liability_type'),
|
||||
// 'liability_start_date' => $this->date('liability_start_date'),
|
||||
|
||||
|
||||
//];
|
||||
if ('liability' === $data['accountType']) {
|
||||
$data['openingBalance'] = bcmul($this->string('liability_amount'), '-1');
|
||||
$data['openingBalanceDate'] = $this->date('liability_start_date');
|
||||
$data['accountType'] = $this->string('liability_type');
|
||||
$data['account_type_id'] = null;
|
||||
}
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* The rules that the incoming request must be matched against.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function rules(): array
|
||||
@@ -86,10 +106,18 @@ class AccountRequest extends Request
|
||||
'account_number' => 'between:1,255|nullable|uniqueAccountNumberForUser',
|
||||
'account_role' => 'in:' . $accountRoles . '|required_if:type,asset',
|
||||
'active' => 'required|boolean',
|
||||
'include_net_worth' => 'required|boolean',
|
||||
'cc_type' => 'in:' . $ccPaymentTypes . '|required_if:account_role,ccAsset',
|
||||
'cc_monthly_payment_date' => 'date' . '|required_if:account_role,ccAsset|required_if:cc_type,monthlyFull',
|
||||
'type' => 'required|in:' . $types,
|
||||
'notes' => 'min:0|max:65536',
|
||||
// required fields for liabilities:
|
||||
'liability_type' => 'required_if:type,liability|in:loan,debt,mortgage,credit card',
|
||||
'liability_amount' => 'required_if:type,liability|min:0|numeric',
|
||||
'liability_start_date' => 'required_if:type,liability|date',
|
||||
'interest' => 'required_if:type,liability|between:0,100|numeric',
|
||||
'interest_period' => 'required_if:type,liability|in:daily,monthly,yearly',
|
||||
|
||||
];
|
||||
switch ($this->method()) {
|
||||
default:
|
||||
|
||||
@@ -26,7 +26,6 @@ namespace FireflyIII\Api\V1\Requests;
|
||||
use FireflyIII\Models\Bill;
|
||||
use FireflyIII\Models\ImportJob;
|
||||
use FireflyIII\Models\TransactionJournal;
|
||||
use FireflyIII\Rules\IsBase64;
|
||||
use FireflyIII\Rules\IsValidAttachmentModel;
|
||||
|
||||
/**
|
||||
@@ -35,6 +34,8 @@ use FireflyIII\Rules\IsValidAttachmentModel;
|
||||
class AttachmentRequest extends Request
|
||||
{
|
||||
/**
|
||||
* Authorize logged in users.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function authorize(): bool
|
||||
@@ -44,6 +45,8 @@ class AttachmentRequest extends Request
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all data from the request.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getAll(): array
|
||||
@@ -58,6 +61,8 @@ class AttachmentRequest extends Request
|
||||
}
|
||||
|
||||
/**
|
||||
* The rules that the incoming request must be matched against.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function rules(): array
|
||||
@@ -89,4 +94,4 @@ class AttachmentRequest extends Request
|
||||
|
||||
return $rules;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -29,6 +29,8 @@ namespace FireflyIII\Api\V1\Requests;
|
||||
class AvailableBudgetRequest extends Request
|
||||
{
|
||||
/**
|
||||
* Authorize logged in users.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function authorize(): bool
|
||||
@@ -38,32 +40,38 @@ class AvailableBudgetRequest extends Request
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all data from the request.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getAll(): array
|
||||
{
|
||||
return [
|
||||
'transaction_currency_id' => $this->integer('transaction_currency_id'),
|
||||
'amount' => $this->string('amount'),
|
||||
'start_date' => $this->date('start_date'),
|
||||
'end_date' => $this->date('end_date'),
|
||||
'currency_id' => $this->integer('currency_id'),
|
||||
'currency_code' => $this->string('currency_code'),
|
||||
'amount' => $this->string('amount'),
|
||||
'start_date' => $this->date('start_date'),
|
||||
'end_date' => $this->date('end_date'),
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* The rules that the incoming request must be matched against.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function rules(): array
|
||||
{
|
||||
$rules = [
|
||||
'transaction_currency_id' => 'required|numeric|exists:transaction_currencies,id',
|
||||
'amount' => 'required|numeric|more:0',
|
||||
'start_date' => 'required|date|before:end_date',
|
||||
'end_date' => 'required|date|after:start_date',
|
||||
'currency_id' => 'numeric|exists:transaction_currencies,id|required_without:currency_code',
|
||||
'currency_code' => 'min:3|max:3|exists:transaction_currencies,code|required_without:currency_id',
|
||||
'amount' => 'required|numeric|more:0',
|
||||
'start_date' => 'required|date|before:end_date',
|
||||
'end_date' => 'required|date|after:start_date',
|
||||
];
|
||||
|
||||
return $rules;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -33,6 +33,8 @@ class BillRequest extends Request
|
||||
{
|
||||
|
||||
/**
|
||||
* Authorize logged in users.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function authorize(): bool
|
||||
@@ -42,6 +44,8 @@ class BillRequest extends Request
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all data from the request.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getAll(): array
|
||||
@@ -64,6 +68,8 @@ class BillRequest extends Request
|
||||
}
|
||||
|
||||
/**
|
||||
* The rules that the incoming request must be matched against.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function rules(): array
|
||||
@@ -109,7 +115,7 @@ class BillRequest extends Request
|
||||
$min = (float)($data['amount_min'] ?? 0);
|
||||
$max = (float)($data['amount_max'] ?? 0);
|
||||
if ($min > $max) {
|
||||
$validator->errors()->add('amount_min', trans('validation.amount_min_over_max'));
|
||||
$validator->errors()->add('amount_min', (string)trans('validation.amount_min_over_max'));
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
@@ -30,6 +30,8 @@ namespace FireflyIII\Api\V1\Requests;
|
||||
class BudgetLimitRequest extends Request
|
||||
{
|
||||
/**
|
||||
* Authorize logged in users.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function authorize(): bool
|
||||
@@ -39,6 +41,8 @@ class BudgetLimitRequest extends Request
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all data from the request.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getAll(): array
|
||||
@@ -52,6 +56,8 @@ class BudgetLimitRequest extends Request
|
||||
}
|
||||
|
||||
/**
|
||||
* The rules that the incoming request must be matched against.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function rules(): array
|
||||
@@ -74,4 +80,4 @@ class BudgetLimitRequest extends Request
|
||||
return $rules;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -31,6 +31,8 @@ use FireflyIII\Models\Budget;
|
||||
class BudgetRequest extends Request
|
||||
{
|
||||
/**
|
||||
* Authorize logged in users.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function authorize(): bool
|
||||
@@ -40,6 +42,8 @@ class BudgetRequest extends Request
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all data from the request.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getAll(): array
|
||||
@@ -52,6 +56,8 @@ class BudgetRequest extends Request
|
||||
}
|
||||
|
||||
/**
|
||||
* The rules that the incoming request must be matched against.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function rules(): array
|
||||
@@ -73,4 +79,4 @@ class BudgetRequest extends Request
|
||||
|
||||
return $rules;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -31,6 +31,8 @@ use FireflyIII\Models\Category;
|
||||
class CategoryRequest extends Request
|
||||
{
|
||||
/**
|
||||
* Authorize logged in users.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function authorize(): bool
|
||||
@@ -40,6 +42,8 @@ class CategoryRequest extends Request
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all data from the request.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getAll(): array
|
||||
@@ -51,6 +55,8 @@ class CategoryRequest extends Request
|
||||
}
|
||||
|
||||
/**
|
||||
* The rules that the incoming request must be matched against.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function rules(): array
|
||||
@@ -72,4 +78,4 @@ class CategoryRequest extends Request
|
||||
|
||||
return $rules;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -30,6 +30,8 @@ namespace FireflyIII\Api\V1\Requests;
|
||||
class CurrencyRequest extends Request
|
||||
{
|
||||
/**
|
||||
* Authorize logged in users.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function authorize(): bool
|
||||
@@ -39,6 +41,8 @@ class CurrencyRequest extends Request
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all data from the request.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getAll(): array
|
||||
@@ -53,6 +57,8 @@ class CurrencyRequest extends Request
|
||||
}
|
||||
|
||||
/**
|
||||
* The rules that the incoming request must be matched against.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function rules(): array
|
||||
@@ -62,7 +68,7 @@ class CurrencyRequest extends Request
|
||||
'code' => 'required|between:3,3|unique:transaction_currencies,code',
|
||||
'symbol' => 'required|between:1,5|unique:transaction_currencies,symbol',
|
||||
'decimal_places' => 'required|between:0,20|numeric|min:0|max:20',
|
||||
'default' => 'in:true,false',
|
||||
'default' => 'boolean',
|
||||
];
|
||||
|
||||
switch ($this->method()) {
|
||||
|
||||
@@ -23,6 +23,9 @@ declare(strict_types=1);
|
||||
|
||||
namespace FireflyIII\Api\V1\Requests;
|
||||
|
||||
use FireflyIII\Repositories\Journal\JournalRepositoryInterface;
|
||||
use FireflyIII\Repositories\LinkType\LinkTypeRepositoryInterface;
|
||||
use Illuminate\Validation\Validator;
|
||||
|
||||
/**
|
||||
*
|
||||
@@ -31,6 +34,8 @@ namespace FireflyIII\Api\V1\Requests;
|
||||
class JournalLinkRequest extends Request
|
||||
{
|
||||
/**
|
||||
* Authorize logged in users.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function authorize(): bool
|
||||
@@ -40,29 +45,87 @@ class JournalLinkRequest extends Request
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all data from the request.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getAll(): array
|
||||
{
|
||||
return [
|
||||
'link_type_id' => $this->integer('link_type_id'),
|
||||
'inward_id' => $this->integer('inward_id'),
|
||||
'outward_id' => $this->integer('outward_id'),
|
||||
'notes' => $this->string('notes'),
|
||||
'link_type_id' => $this->integer('link_type_id'),
|
||||
'link_type_name' => $this->string('link_type_name'),
|
||||
'inward_id' => $this->integer('inward_id'),
|
||||
'outward_id' => $this->integer('outward_id'),
|
||||
'notes' => $this->string('notes'),
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* The rules that the incoming request must be matched against.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function rules(): array
|
||||
{
|
||||
return [
|
||||
'link_type_id' => 'required|exists:link_types,id',
|
||||
'inward_id' => 'required|belongsToUser:transaction_journals,id',
|
||||
'outward_id' => 'required|belongsToUser:transaction_journals,id',
|
||||
'notes' => 'between:0,65000',
|
||||
'link_type_id' => 'exists:link_types,id|required_without:link_type_name',
|
||||
'link_type_name' => 'exists:link_types,name|required_without:link_type_id',
|
||||
'inward_id' => 'required|belongsToUser:transaction_journals,id',
|
||||
'outward_id' => 'required|belongsToUser:transaction_journals,id',
|
||||
'notes' => 'between:0,65000',
|
||||
];
|
||||
}
|
||||
|
||||
}
|
||||
/**
|
||||
* Configure the validator instance.
|
||||
*
|
||||
* @param Validator $validator
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function withValidator(Validator $validator): void
|
||||
{
|
||||
$validator->after(
|
||||
function (Validator $validator) {
|
||||
$this->validateExistingLink($validator);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Validator $validator
|
||||
*/
|
||||
private function validateExistingLink(Validator $validator): void
|
||||
{
|
||||
/** @var LinkTypeRepositoryInterface $repository */
|
||||
$repository = app(LinkTypeRepositoryInterface::class);
|
||||
$repository->setUser(auth()->user());
|
||||
|
||||
/** @var JournalRepositoryInterface $journalRepos */
|
||||
$journalRepos = app(JournalRepositoryInterface::class);
|
||||
$journalRepos->setUser(auth()->user());
|
||||
|
||||
$data = $validator->getData();
|
||||
$inwardId = (int)($data['inward_id'] ?? 0);
|
||||
$outwardId = (int)($data['outward_id'] ?? 0);
|
||||
$inward = $journalRepos->findNull($inwardId);
|
||||
$outward = $journalRepos->findNull($outwardId);
|
||||
|
||||
if (null === $inward) {
|
||||
$validator->errors()->add('inward_id', 'Invalid inward ID.');
|
||||
|
||||
return;
|
||||
}
|
||||
if (null === $outward) {
|
||||
$validator->errors()->add('outward_id', 'Invalid outward ID.');
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if ($repository->findLink($inward, $outward)) {
|
||||
$validator->errors()->add('outward_id', 'Already have a link between inward and outward.');
|
||||
$validator->errors()->add('inward_id', 'Already have a link between inward and outward.');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -33,6 +33,8 @@ use Illuminate\Validation\Rule;
|
||||
class LinkTypeRequest extends Request
|
||||
{
|
||||
/**
|
||||
* Authorize logged in users.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function authorize(): bool
|
||||
@@ -42,6 +44,8 @@ class LinkTypeRequest extends Request
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all data from the request.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getAll(): array
|
||||
@@ -56,6 +60,8 @@ class LinkTypeRequest extends Request
|
||||
}
|
||||
|
||||
/**
|
||||
* The rules that the incoming request must be matched against.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function rules(): array
|
||||
@@ -65,7 +71,6 @@ class LinkTypeRequest extends Request
|
||||
'outward' => 'required|unique:link_types,outward|min:1|different:inward',
|
||||
'inward' => 'required|unique:link_types,inward|min:1|different:outward',
|
||||
];
|
||||
// Rule::unique('users')->ignore($user->id),
|
||||
|
||||
|
||||
switch ($this->method()) {
|
||||
@@ -83,4 +88,4 @@ class LinkTypeRequest extends Request
|
||||
|
||||
return $rules;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -33,6 +33,8 @@ use FireflyIII\Rules\IsAssetAccountId;
|
||||
class PiggyBankRequest extends Request
|
||||
{
|
||||
/**
|
||||
* Authorize logged in users.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function authorize(): bool
|
||||
@@ -42,6 +44,8 @@ class PiggyBankRequest extends Request
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all data from the request.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getAll(): array
|
||||
@@ -53,11 +57,13 @@ class PiggyBankRequest extends Request
|
||||
'current_amount' => $this->string('current_amount'),
|
||||
'start_date' => $this->date('start_date'),
|
||||
'target_date' => $this->date('target_date'),
|
||||
'note' => $this->string('notes'),
|
||||
'notes' => $this->string('notes'),
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* The rules that the incoming request must be matched against.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function rules(): array
|
||||
@@ -87,4 +93,4 @@ class PiggyBankRequest extends Request
|
||||
return $rules;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -32,6 +32,8 @@ class PreferenceRequest extends Request
|
||||
|
||||
|
||||
/**
|
||||
* Authorize logged in users.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function authorize(): bool
|
||||
@@ -40,6 +42,11 @@ class PreferenceRequest extends Request
|
||||
return auth()->check();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all data from the request.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getAll(): array
|
||||
{
|
||||
return [
|
||||
@@ -47,6 +54,11 @@ class PreferenceRequest extends Request
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* The rules that the incoming request must be matched against.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function rules(): array
|
||||
{
|
||||
return [
|
||||
@@ -54,4 +66,4 @@ class PreferenceRequest extends Request
|
||||
];
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -24,20 +24,21 @@ declare(strict_types=1);
|
||||
namespace FireflyIII\Api\V1\Requests;
|
||||
|
||||
use Carbon\Carbon;
|
||||
use FireflyIII\Models\Account;
|
||||
use FireflyIII\Models\AccountType;
|
||||
use FireflyIII\Repositories\Account\AccountRepositoryInterface;
|
||||
use FireflyIII\Rules\BelongsUser;
|
||||
use FireflyIII\Validation\RecurrenceValidation;
|
||||
use FireflyIII\Validation\TransactionValidation;
|
||||
use Illuminate\Validation\Validator;
|
||||
use InvalidArgumentException;
|
||||
use Log;
|
||||
|
||||
/**
|
||||
* Class RecurrenceRequest
|
||||
*/
|
||||
class RecurrenceRequest extends Request
|
||||
{
|
||||
use RecurrenceValidation, TransactionValidation;
|
||||
|
||||
/**
|
||||
* Authorize logged in users.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function authorize(): bool
|
||||
@@ -47,6 +48,8 @@ class RecurrenceRequest extends Request
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all data from the request.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getAll(): array
|
||||
@@ -67,61 +70,21 @@ class RecurrenceRequest extends Request
|
||||
'piggy_bank_name' => $this->string('piggy_bank_name'),
|
||||
'tags' => explode(',', $this->string('tags')),
|
||||
],
|
||||
'transactions' => [],
|
||||
'repetitions' => [],
|
||||
'transactions' => $this->getTransactionData(),
|
||||
'repetitions' => $this->getRepetitionData(),
|
||||
];
|
||||
|
||||
// repetition data:
|
||||
/** @var array $repetitions */
|
||||
$repetitions = $this->get('repetitions');
|
||||
/** @var array $repetition */
|
||||
foreach ($repetitions as $repetition) {
|
||||
$return['repetitions'][] = [
|
||||
'type' => $repetition['type'],
|
||||
'moment' => $repetition['moment'],
|
||||
'skip' => (int)$repetition['skip'],
|
||||
'weekend' => (int)$repetition['weekend'],
|
||||
];
|
||||
}
|
||||
// transaction data:
|
||||
/** @var array $transactions */
|
||||
$transactions = $this->get('transactions');
|
||||
/** @var array $transaction */
|
||||
foreach ($transactions as $transaction) {
|
||||
$return['transactions'][] = [
|
||||
'amount' => $transaction['amount'],
|
||||
|
||||
'currency_id' => isset($transaction['currency_id']) ? (int)$transaction['currency_id'] : null,
|
||||
'currency_code' => $transaction['currency_code'] ?? null,
|
||||
|
||||
'foreign_amount' => $transaction['foreign_amount'] ?? null,
|
||||
'foreign_currency_id' => isset($transaction['foreign_currency_id']) ? (int)$transaction['foreign_currency_id'] : null,
|
||||
'foreign_currency_code' => $transaction['foreign_currency_code'] ?? null,
|
||||
|
||||
'budget_id' => isset($transaction['budget_id']) ? (int)$transaction['budget_id'] : null,
|
||||
'budget_name' => $transaction['budget_name'] ?? null,
|
||||
'category_id' => isset($transaction['category_id']) ? (int)$transaction['category_id'] : null,
|
||||
'category_name' => $transaction['category_name'] ?? null,
|
||||
|
||||
'source_id' => isset($transaction['source_id']) ? (int)$transaction['source_id'] : null,
|
||||
'source_name' => isset($transaction['source_name']) ? (string)$transaction['source_name'] : null,
|
||||
'destination_id' => isset($transaction['destination_id']) ? (int)$transaction['destination_id'] : null,
|
||||
'destination_name' => isset($transaction['destination_name']) ? (string)$transaction['destination_name'] : null,
|
||||
|
||||
'description' => $transaction['description'],
|
||||
];
|
||||
}
|
||||
|
||||
return $return;
|
||||
}
|
||||
|
||||
/**
|
||||
* The rules that the incoming request must be matched against.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function rules(): array
|
||||
{
|
||||
$today = new Carbon;
|
||||
$today->addDay();
|
||||
$today = Carbon::now()->addDay();
|
||||
|
||||
return [
|
||||
'type' => 'required|in:withdrawal,transfer,deposit',
|
||||
@@ -132,18 +95,12 @@ class RecurrenceRequest extends Request
|
||||
'nr_of_repetitions' => 'numeric|between:1,31',
|
||||
'apply_rules' => 'required|boolean',
|
||||
'active' => 'required|boolean',
|
||||
|
||||
// rules for meta values:
|
||||
'tags' => 'between:1,64000',
|
||||
'piggy_bank_id' => 'numeric',
|
||||
|
||||
// rules for repetitions.
|
||||
'repetitions.*.type' => 'required|in:daily,weekly,ndom,monthly,yearly',
|
||||
'repetitions.*.moment' => 'between:0,10',
|
||||
'repetitions.*.skip' => 'required|numeric|between:0,31',
|
||||
'repetitions.*.weekend' => 'required|numeric|min:1|max:4',
|
||||
|
||||
// rules for transactions.
|
||||
'transactions.*.currency_id' => 'numeric|exists:transaction_currencies,id|required_without:transactions.*.currency_code',
|
||||
'transactions.*.currency_code' => 'min:3|max:3|exists:transaction_currencies,code|required_without:transactions.*.currency_id',
|
||||
'transactions.*.foreign_amount' => 'numeric|more:0',
|
||||
@@ -171,312 +128,76 @@ class RecurrenceRequest extends Request
|
||||
{
|
||||
$validator->after(
|
||||
function (Validator $validator) {
|
||||
$this->atLeastOneTransaction($validator);
|
||||
$this->atLeastOneRepetition($validator);
|
||||
$this->validRepeatsUntil($validator);
|
||||
$this->validRepetitionMoment($validator);
|
||||
$this->foreignCurrencyInformation($validator);
|
||||
$this->validateOneTransaction($validator);
|
||||
$this->validateOneRepetition($validator);
|
||||
$this->validateRecurrenceRepetition($validator);
|
||||
$this->validateRepetitionMoment($validator);
|
||||
$this->validateForeignCurrencyInformation($validator);
|
||||
$this->validateAccountInformation($validator);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Throws an error when this asset account is invalid.
|
||||
* Returns the repetition data as it is found in the submitted data.
|
||||
*
|
||||
* @noinspection MoreThanThreeArgumentsInspection
|
||||
*
|
||||
* @param Validator $validator
|
||||
* @param int|null $accountId
|
||||
* @param null|string $accountName
|
||||
* @param string $idField
|
||||
* @param string $nameField
|
||||
*
|
||||
* @return null|Account
|
||||
* @return array
|
||||
*/
|
||||
protected function assetAccountExists(Validator $validator, ?int $accountId, ?string $accountName, string $idField, string $nameField): ?Account
|
||||
private function getRepetitionData(): array
|
||||
{
|
||||
$accountId = (int)$accountId;
|
||||
$accountName = (string)$accountName;
|
||||
// both empty? hard exit.
|
||||
if ($accountId < 1 && '' === $accountName) {
|
||||
$validator->errors()->add($idField, trans('validation.filled', ['attribute' => $idField]));
|
||||
|
||||
return null;
|
||||
}
|
||||
// ID belongs to user and is asset account:
|
||||
/** @var AccountRepositoryInterface $repository */
|
||||
$repository = app(AccountRepositoryInterface::class);
|
||||
$repository->setUser(auth()->user());
|
||||
$set = $repository->getAccountsById([$accountId]);
|
||||
Log::debug(sprintf('Count of accounts found by ID %d is: %d', $accountId, $set->count()));
|
||||
if ($set->count() === 1) {
|
||||
/** @var Account $first */
|
||||
$first = $set->first();
|
||||
if ($first->accountType->type !== AccountType::ASSET) {
|
||||
$validator->errors()->add($idField, trans('validation.belongs_user'));
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
// we ignore the account name at this point.
|
||||
return $first;
|
||||
$return = [];
|
||||
// repetition data:
|
||||
/** @var array $repetitions */
|
||||
$repetitions = $this->get('repetitions');
|
||||
/** @var array $repetition */
|
||||
foreach ($repetitions as $repetition) {
|
||||
$return[] = [
|
||||
'type' => $repetition['type'],
|
||||
'moment' => $repetition['moment'],
|
||||
'skip' => (int)$repetition['skip'],
|
||||
'weekend' => (int)$repetition['weekend'],
|
||||
];
|
||||
}
|
||||
|
||||
$account = $repository->findByName($accountName, [AccountType::ASSET]);
|
||||
if (null === $account) {
|
||||
$validator->errors()->add($nameField, trans('validation.belongs_user'));
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
return $account;
|
||||
return $return;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds an error to the validator when there are no repetitions in the array of data.
|
||||
* Returns the transaction data as it is found in the submitted data. It's a complex method according to code
|
||||
* standards but it just has a lot of ??-statements because of the fields that may or may not exist.
|
||||
*
|
||||
* @param Validator $validator
|
||||
* @return array
|
||||
* @SuppressWarnings(PHPMD.NPathComplexity)
|
||||
* @SuppressWarnings(PHPMD.CyclomaticComplexity)
|
||||
*/
|
||||
protected function atLeastOneRepetition(Validator $validator): void
|
||||
private function getTransactionData(): array
|
||||
{
|
||||
$data = $validator->getData();
|
||||
$repetitions = $data['repetitions'] ?? [];
|
||||
// need at least one transaction
|
||||
if (\count($repetitions) === 0) {
|
||||
$validator->errors()->add('description', trans('validation.at_least_one_repetition'));
|
||||
$return = [];
|
||||
// transaction data:
|
||||
/** @var array $transactions */
|
||||
$transactions = $this->get('transactions');
|
||||
/** @var array $transaction */
|
||||
foreach ($transactions as $transaction) {
|
||||
$return[] = [
|
||||
'amount' => $transaction['amount'],
|
||||
'currency_id' => isset($transaction['currency_id']) ? (int)$transaction['currency_id'] : null,
|
||||
'currency_code' => $transaction['currency_code'] ?? null,
|
||||
'foreign_amount' => $transaction['foreign_amount'] ?? null,
|
||||
'foreign_currency_id' => isset($transaction['foreign_currency_id']) ? (int)$transaction['foreign_currency_id'] : null,
|
||||
'foreign_currency_code' => $transaction['foreign_currency_code'] ?? null,
|
||||
'budget_id' => isset($transaction['budget_id']) ? (int)$transaction['budget_id'] : null,
|
||||
'budget_name' => $transaction['budget_name'] ?? null,
|
||||
'category_id' => isset($transaction['category_id']) ? (int)$transaction['category_id'] : null,
|
||||
'category_name' => $transaction['category_name'] ?? null,
|
||||
'source_id' => isset($transaction['source_id']) ? (int)$transaction['source_id'] : null,
|
||||
'source_name' => isset($transaction['source_name']) ? (string)$transaction['source_name'] : null,
|
||||
'destination_id' => isset($transaction['destination_id']) ? (int)$transaction['destination_id'] : null,
|
||||
'destination_name' => isset($transaction['destination_name']) ? (string)$transaction['destination_name'] : null,
|
||||
'description' => $transaction['description'],
|
||||
];
|
||||
}
|
||||
|
||||
return $return;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds an error to the validator when there are no transactions in the array of data.
|
||||
*
|
||||
* @param Validator $validator
|
||||
*/
|
||||
protected function atLeastOneTransaction(Validator $validator): void
|
||||
{
|
||||
$data = $validator->getData();
|
||||
$transactions = $data['transactions'] ?? [];
|
||||
// need at least one transaction
|
||||
if (\count($transactions) === 0) {
|
||||
$validator->errors()->add('description', trans('validation.at_least_one_transaction'));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* TODO can be made a rule?
|
||||
* If the transactions contain foreign amounts, there must also be foreign currency information.
|
||||
*
|
||||
* @param Validator $validator
|
||||
*/
|
||||
protected function foreignCurrencyInformation(Validator $validator): void
|
||||
{
|
||||
$data = $validator->getData();
|
||||
$transactions = $data['transactions'] ?? [];
|
||||
foreach ($transactions as $index => $transaction) {
|
||||
// must have currency info.
|
||||
if (isset($transaction['foreign_amount'])
|
||||
&& !(isset($transaction['foreign_currency_id'])
|
||||
|| isset($transaction['foreign_currency_code']))) {
|
||||
$validator->errors()->add(
|
||||
'transactions.' . $index . '.foreign_amount',
|
||||
trans('validation.require_currency_info')
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Throws an error when the given opposing account (of type $type) is invalid.
|
||||
* Empty data is allowed, system will default to cash.
|
||||
*
|
||||
* @noinspection MoreThanThreeArgumentsInspection
|
||||
*
|
||||
* @param Validator $validator
|
||||
* @param string $type
|
||||
* @param int|null $accountId
|
||||
* @param null|string $accountName
|
||||
* @param string $idField
|
||||
*
|
||||
* @return null|Account
|
||||
*/
|
||||
protected function opposingAccountExists(Validator $validator, string $type, ?int $accountId, ?string $accountName, string $idField): ?Account
|
||||
{
|
||||
$accountId = (int)$accountId;
|
||||
$accountName = (string)$accountName;
|
||||
// both empty? done!
|
||||
if ($accountId < 1 && \strlen($accountName) === 0) {
|
||||
return null;
|
||||
}
|
||||
if ($accountId !== 0) {
|
||||
// ID belongs to user and is $type account:
|
||||
/** @var AccountRepositoryInterface $repository */
|
||||
$repository = app(AccountRepositoryInterface::class);
|
||||
$repository->setUser(auth()->user());
|
||||
$set = $repository->getAccountsById([$accountId]);
|
||||
if ($set->count() === 1) {
|
||||
/** @var Account $first */
|
||||
$first = $set->first();
|
||||
if ($first->accountType->type !== $type) {
|
||||
$validator->errors()->add($idField, trans('validation.belongs_user'));
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
// we ignore the account name at this point.
|
||||
return $first;
|
||||
}
|
||||
}
|
||||
|
||||
// not having an opposing account by this name is NOT a problem.
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* TODO can be a rule?
|
||||
*
|
||||
* Validates the given account information. Switches on given transaction type.
|
||||
*
|
||||
* @param Validator $validator
|
||||
*/
|
||||
protected function validateAccountInformation(Validator $validator): void
|
||||
{
|
||||
$data = $validator->getData();
|
||||
$transactions = $data['transactions'] ?? [];
|
||||
$idField = 'description';
|
||||
$transactionType = $data['type'] ?? 'false';
|
||||
foreach ($transactions as $index => $transaction) {
|
||||
$sourceId = isset($transaction['source_id']) ? (int)$transaction['source_id'] : null;
|
||||
$sourceName = $transaction['source_name'] ?? null;
|
||||
$destinationId = isset($transaction['destination_id']) ? (int)$transaction['destination_id'] : null;
|
||||
$destinationName = $transaction['destination_name'] ?? null;
|
||||
$sourceAccount = null;
|
||||
$destinationAccount = null;
|
||||
switch ($transactionType) {
|
||||
case 'withdrawal':
|
||||
$idField = 'transactions.' . $index . '.source_id';
|
||||
$nameField = 'transactions.' . $index . '.source_name';
|
||||
$sourceAccount = $this->assetAccountExists($validator, $sourceId, $sourceName, $idField, $nameField);
|
||||
$idField = 'transactions.' . $index . '.destination_id';
|
||||
$destinationAccount = $this->opposingAccountExists($validator, AccountType::EXPENSE, $destinationId, $destinationName, $idField);
|
||||
break;
|
||||
case 'deposit':
|
||||
$idField = 'transactions.' . $index . '.source_id';
|
||||
$sourceAccount = $this->opposingAccountExists($validator, AccountType::REVENUE, $sourceId, $sourceName, $idField);
|
||||
|
||||
$idField = 'transactions.' . $index . '.destination_id';
|
||||
$nameField = 'transactions.' . $index . '.destination_name';
|
||||
$destinationAccount = $this->assetAccountExists($validator, $destinationId, $destinationName, $idField, $nameField);
|
||||
break;
|
||||
case 'transfer':
|
||||
$idField = 'transactions.' . $index . '.source_id';
|
||||
$nameField = 'transactions.' . $index . '.source_name';
|
||||
$sourceAccount = $this->assetAccountExists($validator, $sourceId, $sourceName, $idField, $nameField);
|
||||
|
||||
$idField = 'transactions.' . $index . '.destination_id';
|
||||
$nameField = 'transactions.' . $index . '.destination_name';
|
||||
$destinationAccount = $this->assetAccountExists($validator, $destinationId, $destinationName, $idField, $nameField);
|
||||
break;
|
||||
default:
|
||||
$validator->errors()->add($idField, trans('validation.invalid_account_info'));
|
||||
|
||||
return;
|
||||
|
||||
}
|
||||
// add some errors in case of same account submitted:
|
||||
if (null !== $sourceAccount && null !== $destinationAccount && $sourceAccount->id === $destinationAccount->id) {
|
||||
$validator->errors()->add($idField, trans('validation.source_equals_destination'));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Validator $validator
|
||||
*/
|
||||
private function validRepeatsUntil(Validator $validator): void
|
||||
{
|
||||
$data = $validator->getData();
|
||||
$repetitions = $data['nr_of_repetitions'] ?? null;
|
||||
$repeatUntil = $data['repeat_until'] ?? null;
|
||||
if (null !== $repetitions && null !== $repeatUntil) {
|
||||
// expect a date OR count:
|
||||
$validator->errors()->add('repeat_until', trans('validation.require_repeat_until'));
|
||||
$validator->errors()->add('nr_of_repetitions', trans('validation.require_repeat_until'));
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* TODO merge this in a rule somehow.
|
||||
*
|
||||
* @param Validator $validator
|
||||
*/
|
||||
private function validRepetitionMoment(Validator $validator): void
|
||||
{
|
||||
$data = $validator->getData();
|
||||
$repetitions = $data['repetitions'] ?? [];
|
||||
/**
|
||||
* @var int $index
|
||||
* @var array $repetition
|
||||
*/
|
||||
foreach ($repetitions as $index => $repetition) {
|
||||
switch ($repetition['type']) {
|
||||
default:
|
||||
$validator->errors()->add(sprintf('repetitions.%d.type', $index), trans('validation.valid_recurrence_rep_type'));
|
||||
|
||||
return;
|
||||
case 'daily':
|
||||
if ('' !== (string)$repetition['moment']) {
|
||||
$validator->errors()->add(sprintf('repetitions.%d.moment', $index), trans('validation.valid_recurrence_rep_moment'));
|
||||
}
|
||||
|
||||
return;
|
||||
case 'monthly':
|
||||
$dayOfMonth = (int)$repetition['moment'];
|
||||
if ($dayOfMonth < 1 || $dayOfMonth > 31) {
|
||||
$validator->errors()->add(sprintf('repetitions.%d.moment', $index), trans('validation.valid_recurrence_rep_moment'));
|
||||
}
|
||||
|
||||
return;
|
||||
case 'ndom':
|
||||
$parameters = explode(',', $repetition['moment']);
|
||||
if (\count($parameters) !== 2) {
|
||||
$validator->errors()->add(sprintf('repetitions.%d.moment', $index), trans('validation.valid_recurrence_rep_moment'));
|
||||
|
||||
return;
|
||||
}
|
||||
$nthDay = (int)($parameters[0] ?? 0.0);
|
||||
$dayOfWeek = (int)($parameters[1] ?? 0.0);
|
||||
if ($nthDay < 1 || $nthDay > 5) {
|
||||
$validator->errors()->add(sprintf('repetitions.%d.moment', $index), trans('validation.valid_recurrence_rep_moment'));
|
||||
|
||||
return;
|
||||
}
|
||||
if ($dayOfWeek < 1 || $dayOfWeek > 7) {
|
||||
$validator->errors()->add(sprintf('repetitions.%d.moment', $index), trans('validation.valid_recurrence_rep_moment'));
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
return;
|
||||
case 'weekly':
|
||||
$dayOfWeek = (int)$repetition['moment'];
|
||||
if ($dayOfWeek < 1 || $dayOfWeek > 7) {
|
||||
$validator->errors()->add(sprintf('repetitions.%d.moment', $index), trans('validation.valid_recurrence_rep_moment'));
|
||||
|
||||
return;
|
||||
}
|
||||
break;
|
||||
case 'yearly':
|
||||
try {
|
||||
Carbon::createFromFormat('Y-m-d', $repetition['moment']);
|
||||
} catch (InvalidArgumentException $e) {
|
||||
$validator->errors()->add(sprintf('repetitions.%d.moment', $index), trans('validation.valid_recurrence_rep_moment'));
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -28,6 +28,10 @@ use FireflyIII\Http\Requests\Request as FireflyIIIRequest;
|
||||
|
||||
/**
|
||||
* Class Request.
|
||||
*
|
||||
* Technically speaking this class does not have to be extended like this but who knows what the future brings.
|
||||
*
|
||||
* @SuppressWarnings(PHPMD.NumberOfChildren)
|
||||
*/
|
||||
class Request extends FireflyIIIRequest
|
||||
{
|
||||
|
||||
@@ -33,6 +33,8 @@ use FireflyIII\Models\RuleGroup;
|
||||
class RuleGroupRequest extends Request
|
||||
{
|
||||
/**
|
||||
* Authorize logged in users.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function authorize(): bool
|
||||
@@ -42,6 +44,8 @@ class RuleGroupRequest extends Request
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all data from the request.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getAll(): array
|
||||
@@ -54,6 +58,8 @@ class RuleGroupRequest extends Request
|
||||
}
|
||||
|
||||
/**
|
||||
* The rules that the incoming request must be matched against.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function rules(): array
|
||||
@@ -76,4 +82,4 @@ class RuleGroupRequest extends Request
|
||||
|
||||
return $rules;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -32,6 +32,8 @@ use Illuminate\Validation\Validator;
|
||||
class RuleRequest extends Request
|
||||
{
|
||||
/**
|
||||
* Authorize logged in users.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function authorize(): bool
|
||||
@@ -41,6 +43,8 @@ class RuleRequest extends Request
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all data from the request.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getAll(): array
|
||||
@@ -52,31 +56,18 @@ class RuleRequest extends Request
|
||||
'rule_group_title' => $this->string('rule_group_title'),
|
||||
'trigger' => $this->string('trigger'),
|
||||
'strict' => $this->boolean('strict'),
|
||||
'stop-processing' => $this->boolean('stop_processing'),
|
||||
'stop_processing' => $this->boolean('stop_processing'),
|
||||
'active' => $this->boolean('active'),
|
||||
'rule-triggers' => [],
|
||||
'rule-actions' => [],
|
||||
'rule_triggers' => $this->getRuleTriggers(),
|
||||
'rule_actions' => $this->getRuleActions(),
|
||||
];
|
||||
|
||||
foreach ($this->get('rule-triggers') as $trigger) {
|
||||
$data['rule-triggers'][] = [
|
||||
'name' => $trigger['name'],
|
||||
'value' => $trigger['value'],
|
||||
'stop-processing' => (int)($trigger['stop-processing'] ?? 0) === 1,
|
||||
];
|
||||
}
|
||||
foreach ($this->get('rule-actions') as $action) {
|
||||
$data['rule-actions'][] = [
|
||||
'name' => $action['name'],
|
||||
'value' => $action['value'],
|
||||
'stop-processing' => (int)($action['stop-processing'] ?? 0) === 1,
|
||||
];
|
||||
}
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* The rules that the incoming request must be matched against.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function rules(): array
|
||||
@@ -93,12 +84,12 @@ class RuleRequest extends Request
|
||||
'rule_group_id' => 'required|belongsToUser:rule_groups|required_without:rule_group_title',
|
||||
'rule_group_title' => 'nullable|between:1,255|required_without:rule_group_id|belongsToUser:rule_groups,title',
|
||||
'trigger' => 'required|in:store-journal,update-journal',
|
||||
'rule-triggers.*.name' => 'required|in:' . implode(',', $validTriggers),
|
||||
'rule-triggers.*.stop-processing' => 'boolean',
|
||||
'rule-triggers.*.value' => 'required|min:1|ruleTriggerValue', //
|
||||
'rule-actions.*.name' => 'required|in:' . implode(',', $validActions),
|
||||
'rule-actions.*.value' => 'required_if:rule-action.*.type,' . $contextActions . '|ruleActionValue',
|
||||
'rule-actions.*.stop-processing' => 'boolean',
|
||||
'rule_triggers.*.name' => 'required|in:' . implode(',', $validTriggers),
|
||||
'rule_triggers.*.stop_processing' => 'boolean',
|
||||
'rule_triggers.*.value' => 'required|min:1|ruleTriggerValue',
|
||||
'rule_actions.*.name' => 'required|in:' . implode(',', $validActions),
|
||||
'rule_actions.*.value' => 'required_if:rule_actions.*.type,' . $contextActions . '|ruleActionValue',
|
||||
'rule_actions.*.stop_processing' => 'boolean',
|
||||
'strict' => 'required|boolean',
|
||||
'stop_processing' => 'required|boolean',
|
||||
'active' => 'required|boolean',
|
||||
@@ -132,10 +123,10 @@ class RuleRequest extends Request
|
||||
protected function atLeastOneAction(Validator $validator): void
|
||||
{
|
||||
$data = $validator->getData();
|
||||
$repetitions = $data['rule-actions'] ?? [];
|
||||
$repetitions = $data['rule_actions'] ?? [];
|
||||
// need at least one transaction
|
||||
if (\count($repetitions) === 0) {
|
||||
$validator->errors()->add('title', trans('validation.at_least_one_action'));
|
||||
if (0 === \count($repetitions)) {
|
||||
$validator->errors()->add('title', (string)trans('validation.at_least_one_action'));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -147,10 +138,50 @@ class RuleRequest extends Request
|
||||
protected function atLeastOneTrigger(Validator $validator): void
|
||||
{
|
||||
$data = $validator->getData();
|
||||
$repetitions = $data['rule-triggers'] ?? [];
|
||||
$repetitions = $data['rule_triggers'] ?? [];
|
||||
// need at least one transaction
|
||||
if (\count($repetitions) === 0) {
|
||||
$validator->errors()->add('title', trans('validation.at_least_one_trigger'));
|
||||
if (0 === \count($repetitions)) {
|
||||
$validator->errors()->add('title', (string)trans('validation.at_least_one_trigger'));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
private function getRuleActions(): array
|
||||
{
|
||||
$actions = $this->get('rule_actions');
|
||||
$return = [];
|
||||
if (\is_array($actions)) {
|
||||
foreach ($actions as $action) {
|
||||
$return[] = [
|
||||
'name' => $action['name'],
|
||||
'value' => $action['value'],
|
||||
'stop_processing' => 1 === (int)($action['stop-processing'] ?? '0'),
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
return $return;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
private function getRuleTriggers(): array
|
||||
{
|
||||
$triggers = $this->get('rule_triggers');
|
||||
$return = [];
|
||||
if (\is_array($triggers)) {
|
||||
foreach ($triggers as $trigger) {
|
||||
$return[] = [
|
||||
'name' => $trigger['name'],
|
||||
'value' => $trigger['value'],
|
||||
'stop_processing' => 1 === (int)($trigger['stop-processing'] ?? '0'),
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
return $return;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -24,12 +24,8 @@ declare(strict_types=1);
|
||||
|
||||
namespace FireflyIII\Api\V1\Requests;
|
||||
|
||||
use FireflyIII\Exceptions\FireflyException;
|
||||
use FireflyIII\Models\Account;
|
||||
use FireflyIII\Models\AccountType;
|
||||
use FireflyIII\Models\Transaction;
|
||||
use FireflyIII\Repositories\Account\AccountRepositoryInterface;
|
||||
use FireflyIII\Rules\BelongsUser;
|
||||
use FireflyIII\Validation\TransactionValidation;
|
||||
use Illuminate\Validation\Validator;
|
||||
|
||||
|
||||
@@ -38,7 +34,11 @@ use Illuminate\Validation\Validator;
|
||||
*/
|
||||
class TransactionRequest extends Request
|
||||
{
|
||||
use TransactionValidation;
|
||||
|
||||
/**
|
||||
* Authorize logged in users.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function authorize(): bool
|
||||
@@ -48,12 +48,15 @@ class TransactionRequest extends Request
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all data. Is pretty complex because of all the ??-statements.
|
||||
*
|
||||
* @SuppressWarnings(PHPMD.CyclomaticComplexity)
|
||||
* @SuppressWarnings(PHPMD.NPathComplexity)
|
||||
* @return array
|
||||
*/
|
||||
public function getAll(): array
|
||||
{
|
||||
$data = [
|
||||
// basic fields for journal:
|
||||
'type' => $this->string('type'),
|
||||
'date' => $this->date('date'),
|
||||
'description' => $this->string('description'),
|
||||
@@ -62,8 +65,6 @@ class TransactionRequest extends Request
|
||||
'bill_id' => $this->integer('bill_id'),
|
||||
'bill_name' => $this->string('bill_name'),
|
||||
'tags' => explode(',', $this->string('tags')),
|
||||
|
||||
// then, custom fields for journal
|
||||
'interest_date' => $this->date('interest_date'),
|
||||
'book_date' => $this->date('book_date'),
|
||||
'process_date' => $this->date('process_date'),
|
||||
@@ -72,39 +73,17 @@ class TransactionRequest extends Request
|
||||
'invoice_date' => $this->date('invoice_date'),
|
||||
'internal_reference' => $this->string('internal_reference'),
|
||||
'notes' => $this->string('notes'),
|
||||
|
||||
// then, transactions (see below).
|
||||
'transactions' => [],
|
||||
|
||||
'transactions' => $this->getTransactionData(),
|
||||
];
|
||||
foreach ($this->get('transactions') as $index => $transaction) {
|
||||
$array = [
|
||||
'description' => $transaction['description'] ?? null,
|
||||
'amount' => $transaction['amount'],
|
||||
'currency_id' => isset($transaction['currency_id']) ? (int)$transaction['currency_id'] : null,
|
||||
'currency_code' => $transaction['currency_code'] ?? null,
|
||||
'foreign_amount' => $transaction['foreign_amount'] ?? null,
|
||||
'foreign_currency_id' => isset($transaction['foreign_currency_id']) ? (int)$transaction['foreign_currency_id'] : null,
|
||||
'foreign_currency_code' => $transaction['foreign_currency_code'] ?? null,
|
||||
'budget_id' => isset($transaction['budget_id']) ? (int)$transaction['budget_id'] : null,
|
||||
'budget_name' => $transaction['budget_name'] ?? null,
|
||||
'category_id' => isset($transaction['category_id']) ? (int)$transaction['category_id'] : null,
|
||||
'category_name' => $transaction['category_name'] ?? null,
|
||||
'source_id' => isset($transaction['source_id']) ? (int)$transaction['source_id'] : null,
|
||||
'source_name' => isset($transaction['source_name']) ? (string)$transaction['source_name'] : null,
|
||||
'destination_id' => isset($transaction['destination_id']) ? (int)$transaction['destination_id'] : null,
|
||||
'destination_name' => isset($transaction['destination_name']) ? (string)$transaction['destination_name'] : null,
|
||||
'reconciled' => $transaction['reconciled'] ?? false,
|
||||
'identifier' => $index,
|
||||
];
|
||||
$data['transactions'][] = $array;
|
||||
}
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* The rules that the incoming request must be matched against.
|
||||
*
|
||||
* @return array
|
||||
* @SuppressWarnings(PHPMD.ExcessiveMethodLength)
|
||||
*/
|
||||
public function rules(): array
|
||||
{
|
||||
@@ -149,13 +128,8 @@ class TransactionRequest extends Request
|
||||
'transactions.*.destination_name' => 'between:1,255|nullable',
|
||||
];
|
||||
|
||||
switch ($this->method()) {
|
||||
default:
|
||||
break;
|
||||
case 'PUT':
|
||||
case 'PATCH':
|
||||
unset($rules['type'], $rules['piggy_bank_id'], $rules['piggy_bank_name']);
|
||||
break;
|
||||
if ('PUT' === $this->method()) {
|
||||
unset($rules['type'], $rules['piggy_bank_id'], $rules['piggy_bank_name']);
|
||||
}
|
||||
|
||||
return $rules;
|
||||
@@ -174,11 +148,11 @@ class TransactionRequest extends Request
|
||||
{
|
||||
$validator->after(
|
||||
function (Validator $validator) {
|
||||
$this->atLeastOneTransaction($validator);
|
||||
$this->checkValidDescriptions($validator);
|
||||
$this->equalToJournalDescription($validator);
|
||||
$this->emptySplitDescriptions($validator);
|
||||
$this->foreignCurrencyInformation($validator);
|
||||
$this->validateOneTransaction($validator);
|
||||
$this->validateDescriptions($validator);
|
||||
$this->validateJournalDescription($validator);
|
||||
$this->validateSplitDescriptions($validator);
|
||||
$this->validateForeignCurrencyInformation($validator);
|
||||
$this->validateAccountInformation($validator);
|
||||
$this->validateSplitAccounts($validator);
|
||||
}
|
||||
@@ -186,335 +160,37 @@ class TransactionRequest extends Request
|
||||
}
|
||||
|
||||
/**
|
||||
* Throws an error when this asset account is invalid.
|
||||
* Get transaction data.
|
||||
*
|
||||
* @noinspection MoreThanThreeArgumentsInspection
|
||||
*
|
||||
* @param Validator $validator
|
||||
* @param int|null $accountId
|
||||
* @param null|string $accountName
|
||||
* @param string $idField
|
||||
* @param string $nameField
|
||||
*
|
||||
* @return null|Account
|
||||
* @SuppressWarnings(PHPMD.CyclomaticComplexity)
|
||||
* @SuppressWarnings(PHPMD.NPathComplexity)
|
||||
* @return array
|
||||
*/
|
||||
protected function assetAccountExists(Validator $validator, ?int $accountId, ?string $accountName, string $idField, string $nameField): ?Account
|
||||
private function getTransactionData(): array
|
||||
{
|
||||
|
||||
$accountId = (int)$accountId;
|
||||
$accountName = (string)$accountName;
|
||||
// both empty? hard exit.
|
||||
if ($accountId < 1 && \strlen($accountName) === 0) {
|
||||
$validator->errors()->add($idField, trans('validation.filled', ['attribute' => $idField]));
|
||||
|
||||
return null;
|
||||
}
|
||||
// ID belongs to user and is asset account:
|
||||
/** @var AccountRepositoryInterface $repository */
|
||||
$repository = app(AccountRepositoryInterface::class);
|
||||
$repository->setUser(auth()->user());
|
||||
$set = $repository->getAccountsById([$accountId]);
|
||||
if ($set->count() === 1) {
|
||||
/** @var Account $first */
|
||||
$first = $set->first();
|
||||
if ($first->accountType->type !== AccountType::ASSET) {
|
||||
$validator->errors()->add($idField, trans('validation.belongs_user'));
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
// we ignore the account name at this point.
|
||||
return $first;
|
||||
$return = [];
|
||||
foreach ($this->get('transactions') as $index => $transaction) {
|
||||
$return[] = [
|
||||
'description' => $transaction['description'] ?? null,
|
||||
'amount' => $transaction['amount'],
|
||||
'currency_id' => isset($transaction['currency_id']) ? (int)$transaction['currency_id'] : null,
|
||||
'currency_code' => $transaction['currency_code'] ?? null,
|
||||
'foreign_amount' => $transaction['foreign_amount'] ?? null,
|
||||
'foreign_currency_id' => isset($transaction['foreign_currency_id']) ? (int)$transaction['foreign_currency_id'] : null,
|
||||
'foreign_currency_code' => $transaction['foreign_currency_code'] ?? null,
|
||||
'budget_id' => isset($transaction['budget_id']) ? (int)$transaction['budget_id'] : null,
|
||||
'budget_name' => $transaction['budget_name'] ?? null,
|
||||
'category_id' => isset($transaction['category_id']) ? (int)$transaction['category_id'] : null,
|
||||
'category_name' => $transaction['category_name'] ?? null,
|
||||
'source_id' => isset($transaction['source_id']) ? (int)$transaction['source_id'] : null,
|
||||
'source_name' => isset($transaction['source_name']) ? (string)$transaction['source_name'] : null,
|
||||
'destination_id' => isset($transaction['destination_id']) ? (int)$transaction['destination_id'] : null,
|
||||
'destination_name' => isset($transaction['destination_name']) ? (string)$transaction['destination_name'] : null,
|
||||
'reconciled' => $transaction['reconciled'] ?? false,
|
||||
'identifier' => $index,
|
||||
];
|
||||
}
|
||||
|
||||
$account = $repository->findByName($accountName, [AccountType::ASSET]);
|
||||
if (null === $account) {
|
||||
$validator->errors()->add($nameField, trans('validation.belongs_user'));
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
return $account;
|
||||
return $return;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds an error to the validator when there are no transactions in the array of data.
|
||||
*
|
||||
* @param Validator $validator
|
||||
*/
|
||||
protected function atLeastOneTransaction(Validator $validator): void
|
||||
{
|
||||
$data = $validator->getData();
|
||||
$transactions = $data['transactions'] ?? [];
|
||||
// need at least one transaction
|
||||
if (\count($transactions) === 0) {
|
||||
$validator->errors()->add('description', trans('validation.at_least_one_transaction'));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds an error to the "description" field when the user has submitted no descriptions and no
|
||||
* journal description.
|
||||
*
|
||||
* @param Validator $validator
|
||||
*/
|
||||
protected function checkValidDescriptions(Validator $validator): void
|
||||
{
|
||||
$data = $validator->getData();
|
||||
$transactions = $data['transactions'] ?? [];
|
||||
$journalDescription = (string)($data['description'] ?? '');
|
||||
$validDescriptions = 0;
|
||||
foreach ($transactions as $index => $transaction) {
|
||||
if (\strlen((string)($transaction['description'] ?? '')) > 0) {
|
||||
$validDescriptions++;
|
||||
}
|
||||
}
|
||||
|
||||
// no valid descriptions and empty journal description? error.
|
||||
if ($validDescriptions === 0 && \strlen($journalDescription) === 0) {
|
||||
$validator->errors()->add('description', trans('validation.filled', ['attribute' => trans('validation.attributes.description')]));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds an error to the validator when the user submits a split transaction (more than 1 transactions)
|
||||
* but does not give them a description.
|
||||
*
|
||||
* @param Validator $validator
|
||||
*/
|
||||
protected function emptySplitDescriptions(Validator $validator): void
|
||||
{
|
||||
$data = $validator->getData();
|
||||
$transactions = $data['transactions'] ?? [];
|
||||
foreach ($transactions as $index => $transaction) {
|
||||
$description = (string)($transaction['description'] ?? '');
|
||||
// filled description is mandatory for split transactions.
|
||||
if (\count($transactions) > 1 && \strlen($description) === 0) {
|
||||
$validator->errors()->add(
|
||||
'transactions.' . $index . '.description',
|
||||
trans('validation.filled', ['attribute' => trans('validation.attributes.transaction_description')])
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds an error to the validator when any transaction descriptions are equal to the journal description.
|
||||
*
|
||||
* @param Validator $validator
|
||||
*/
|
||||
protected function equalToJournalDescription(Validator $validator): void
|
||||
{
|
||||
$data = $validator->getData();
|
||||
$transactions = $data['transactions'] ?? [];
|
||||
$journalDescription = (string)($data['description'] ?? '');
|
||||
foreach ($transactions as $index => $transaction) {
|
||||
$description = (string)($transaction['description'] ?? '');
|
||||
// description cannot be equal to journal description.
|
||||
if ($description === $journalDescription) {
|
||||
$validator->errors()->add('transactions.' . $index . '.description', trans('validation.equal_description'));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* TODO can be made a rule?
|
||||
*
|
||||
* If the transactions contain foreign amounts, there must also be foreign currency information.
|
||||
*
|
||||
* @param Validator $validator
|
||||
*/
|
||||
protected function foreignCurrencyInformation(Validator $validator): void
|
||||
{
|
||||
$data = $validator->getData();
|
||||
$transactions = $data['transactions'] ?? [];
|
||||
foreach ($transactions as $index => $transaction) {
|
||||
// must have currency info.
|
||||
if (isset($transaction['foreign_amount'])
|
||||
&& !(isset($transaction['foreign_currency_id'])
|
||||
|| isset($transaction['foreign_currency_code']))) {
|
||||
$validator->errors()->add(
|
||||
'transactions.' . $index . '.foreign_amount',
|
||||
trans('validation.require_currency_info')
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Throws an error when the given opposing account (of type $type) is invalid.
|
||||
* Empty data is allowed, system will default to cash.
|
||||
*
|
||||
* @noinspection MoreThanThreeArgumentsInspection
|
||||
*
|
||||
* @param Validator $validator
|
||||
* @param string $type
|
||||
* @param int|null $accountId
|
||||
* @param null|string $accountName
|
||||
* @param string $idField
|
||||
*
|
||||
* @return null|Account
|
||||
*/
|
||||
protected function opposingAccountExists(Validator $validator, string $type, ?int $accountId, ?string $accountName, string $idField): ?Account
|
||||
{
|
||||
$accountId = (int)$accountId;
|
||||
$accountName = (string)$accountName;
|
||||
// both empty? done!
|
||||
if ($accountId < 1 && \strlen($accountName) === 0) {
|
||||
return null;
|
||||
}
|
||||
if ($accountId !== 0) {
|
||||
// ID belongs to user and is $type account:
|
||||
/** @var AccountRepositoryInterface $repository */
|
||||
$repository = app(AccountRepositoryInterface::class);
|
||||
$repository->setUser(auth()->user());
|
||||
$set = $repository->getAccountsById([$accountId]);
|
||||
if ($set->count() === 1) {
|
||||
/** @var Account $first */
|
||||
$first = $set->first();
|
||||
if ($first->accountType->type !== $type) {
|
||||
$validator->errors()->add($idField, trans('validation.belongs_user'));
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
// we ignore the account name at this point.
|
||||
return $first;
|
||||
}
|
||||
}
|
||||
|
||||
// not having an opposing account by this name is NOT a problem.
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Validates the given account information. Switches on given transaction type.
|
||||
*
|
||||
* @param Validator $validator
|
||||
*
|
||||
* @throws FireflyException
|
||||
*/
|
||||
protected function validateAccountInformation(Validator $validator): void
|
||||
{
|
||||
$data = $validator->getData();
|
||||
$transactions = $data['transactions'] ?? [];
|
||||
if (!isset($data['type'])) {
|
||||
// the journal may exist in the request:
|
||||
/** @var Transaction $transaction */
|
||||
$transaction = $this->route()->parameter('transaction');
|
||||
if (null === $transaction) {
|
||||
return; // @codeCoverageIgnore
|
||||
}
|
||||
$data['type'] = strtolower($transaction->transactionJournal->transactionType->type);
|
||||
}
|
||||
foreach ($transactions as $index => $transaction) {
|
||||
$sourceId = isset($transaction['source_id']) ? (int)$transaction['source_id'] : null;
|
||||
$sourceName = $transaction['source_name'] ?? null;
|
||||
$destinationId = isset($transaction['destination_id']) ? (int)$transaction['destination_id'] : null;
|
||||
$destinationName = $transaction['destination_name'] ?? null;
|
||||
$sourceAccount = null;
|
||||
$destinationAccount = null;
|
||||
switch ($data['type']) {
|
||||
case 'withdrawal':
|
||||
$idField = 'transactions.' . $index . '.source_id';
|
||||
$nameField = 'transactions.' . $index . '.source_name';
|
||||
$sourceAccount = $this->assetAccountExists($validator, $sourceId, $sourceName, $idField, $nameField);
|
||||
$idField = 'transactions.' . $index . '.destination_id';
|
||||
$destinationAccount = $this->opposingAccountExists($validator, AccountType::EXPENSE, $destinationId, $destinationName, $idField);
|
||||
break;
|
||||
case 'deposit':
|
||||
$idField = 'transactions.' . $index . '.source_id';
|
||||
$sourceAccount = $this->opposingAccountExists($validator, AccountType::REVENUE, $sourceId, $sourceName, $idField);
|
||||
|
||||
$idField = 'transactions.' . $index . '.destination_id';
|
||||
$nameField = 'transactions.' . $index . '.destination_name';
|
||||
$destinationAccount = $this->assetAccountExists($validator, $destinationId, $destinationName, $idField, $nameField);
|
||||
break;
|
||||
case 'transfer':
|
||||
$idField = 'transactions.' . $index . '.source_id';
|
||||
$nameField = 'transactions.' . $index . '.source_name';
|
||||
$sourceAccount = $this->assetAccountExists($validator, $sourceId, $sourceName, $idField, $nameField);
|
||||
|
||||
$idField = 'transactions.' . $index . '.destination_id';
|
||||
$nameField = 'transactions.' . $index . '.destination_name';
|
||||
$destinationAccount = $this->assetAccountExists($validator, $destinationId, $destinationName, $idField, $nameField);
|
||||
break;
|
||||
default:
|
||||
// @codeCoverageIgnoreStart
|
||||
throw new FireflyException(
|
||||
sprintf('The validator cannot handle transaction type "%s" in validateAccountInformation().', $data['type'])
|
||||
);
|
||||
// @codeCoverageIgnoreEnd
|
||||
|
||||
}
|
||||
// add some errors in case of same account submitted:
|
||||
if (null !== $sourceAccount && null !== $destinationAccount && $sourceAccount->id === $destinationAccount->id) {
|
||||
$validator->errors()->add($idField, trans('validation.source_equals_destination'));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Validator $validator
|
||||
*
|
||||
* @throws FireflyException
|
||||
*/
|
||||
protected function validateSplitAccounts(Validator $validator): void
|
||||
{
|
||||
$data = $validator->getData();
|
||||
$count = isset($data['transactions']) ? \count($data['transactions']) : 0;
|
||||
if ($count < 2) {
|
||||
return;
|
||||
}
|
||||
// this is pretty much impossible:
|
||||
// @codeCoverageIgnoreStart
|
||||
if (!isset($data['type'])) {
|
||||
// the journal may exist in the request:
|
||||
/** @var Transaction $transaction */
|
||||
$transaction = $this->route()->parameter('transaction');
|
||||
if (null === $transaction) {
|
||||
return;
|
||||
}
|
||||
$data['type'] = strtolower($transaction->transactionJournal->transactionType->type);
|
||||
}
|
||||
// @codeCoverageIgnoreEnd
|
||||
|
||||
// collect all source ID's and destination ID's, if present:
|
||||
$sources = [];
|
||||
$destinations = [];
|
||||
|
||||
foreach ($data['transactions'] as $transaction) {
|
||||
$sources[] = isset($transaction['source_id']) ? (int)$transaction['source_id'] : 0;
|
||||
$destinations[] = isset($transaction['destination_id']) ? (int)$transaction['destination_id'] : 0;
|
||||
}
|
||||
$destinations = array_unique($destinations);
|
||||
$sources = array_unique($sources);
|
||||
// switch on type:
|
||||
switch ($data['type']) {
|
||||
case 'withdrawal':
|
||||
if (\count($sources) > 1) {
|
||||
$validator->errors()->add('transactions.0.source_id', trans('validation.all_accounts_equal'));
|
||||
}
|
||||
break;
|
||||
case 'deposit':
|
||||
if (\count($destinations) > 1) {
|
||||
$validator->errors()->add('transactions.0.destination_id', trans('validation.all_accounts_equal'));
|
||||
}
|
||||
break;
|
||||
case 'transfer':
|
||||
if (\count($sources) > 1 || \count($destinations) > 1) {
|
||||
$validator->errors()->add('transactions.0.source_id', trans('validation.all_accounts_equal'));
|
||||
$validator->errors()->add('transactions.0.destination_id', trans('validation.all_accounts_equal'));
|
||||
}
|
||||
break;
|
||||
default:
|
||||
// @codeCoverageIgnoreStart
|
||||
throw new FireflyException(
|
||||
sprintf('The validator cannot handle transaction type "%s" in validateSplitAccounts().', $data['type'])
|
||||
);
|
||||
// @codeCoverageIgnoreEnd
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -24,6 +24,7 @@ declare(strict_types=1);
|
||||
|
||||
namespace FireflyIII\Api\V1\Requests;
|
||||
|
||||
use FireflyIII\Repositories\User\UserRepositoryInterface;
|
||||
use FireflyIII\User;
|
||||
|
||||
|
||||
@@ -33,24 +34,32 @@ use FireflyIII\User;
|
||||
class UserRequest extends Request
|
||||
{
|
||||
/**
|
||||
* Authorize logged in users.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function authorize(): bool
|
||||
{
|
||||
$result = false;
|
||||
// Only allow authenticated users
|
||||
if (!auth()->check()) {
|
||||
return false; // @codeCoverageIgnore
|
||||
}
|
||||
/** @var User $user */
|
||||
$user = auth()->user();
|
||||
if (!$user->hasRole('owner')) {
|
||||
return false; // @codeCoverageIgnore
|
||||
if (auth()->check()) {
|
||||
/** @var User $user */
|
||||
$user = auth()->user();
|
||||
|
||||
/** @var UserRepositoryInterface $repository */
|
||||
$repository = app(UserRepositoryInterface::class);
|
||||
|
||||
if ($repository->hasRole($user, 'owner')) {
|
||||
$result = true; // @codeCoverageIgnore
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all data from the request.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getAll(): array
|
||||
@@ -65,6 +74,8 @@ class UserRequest extends Request
|
||||
}
|
||||
|
||||
/**
|
||||
* The rules that the incoming request must be matched against.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function rules(): array
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* CreateExport.php
|
||||
* Copyright (c) 2018 thegrumpydictator@gmail.com
|
||||
@@ -20,6 +19,8 @@
|
||||
* along with Firefly III. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/** @noinspection MultipleReturnStatementsInspection */
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace FireflyIII\Console\Commands;
|
||||
@@ -38,10 +39,13 @@ use Storage;
|
||||
* Class CreateExport.
|
||||
*
|
||||
* Generates export from the command line.
|
||||
*
|
||||
* @codeCoverageIgnore
|
||||
*/
|
||||
class CreateExport extends Command
|
||||
{
|
||||
use VerifiesAccessToken;
|
||||
|
||||
/**
|
||||
* The console command description.
|
||||
*
|
||||
@@ -64,9 +68,11 @@ class CreateExport extends Command
|
||||
/**
|
||||
* Execute the console command.
|
||||
*
|
||||
* @return mixed
|
||||
* @return int
|
||||
* @SuppressWarnings(PHPMD.CyclomaticComplexity)
|
||||
* @SuppressWarnings(PHPMD.ExcessiveMethodLength)
|
||||
*/
|
||||
public function handle()
|
||||
public function handle(): int
|
||||
{
|
||||
if (!$this->verifyAccessToken()) {
|
||||
$this->error('Invalid access token.');
|
||||
@@ -86,6 +92,9 @@ class CreateExport extends Command
|
||||
|
||||
// set user
|
||||
$user = $userRepository->findNull((int)$this->option('user'));
|
||||
if (null === $user) {
|
||||
return 1;
|
||||
}
|
||||
$jobRepository->setUser($user);
|
||||
$journalRepository->setUser($user);
|
||||
$accountRepository->setUser($user);
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* CreateImport.php
|
||||
* Copyright (c) 2018 thegrumpydictator@gmail.com
|
||||
@@ -20,6 +19,8 @@
|
||||
* along with Firefly III. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/** @noinspection MultipleReturnStatementsInspection */
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace FireflyIII\Console\Commands;
|
||||
@@ -33,10 +34,11 @@ use FireflyIII\Repositories\ImportJob\ImportJobRepositoryInterface;
|
||||
use FireflyIII\Repositories\User\UserRepositoryInterface;
|
||||
use Illuminate\Console\Command;
|
||||
use Log;
|
||||
use Preferences;
|
||||
|
||||
/**
|
||||
* Class CreateImport.
|
||||
*
|
||||
* @codeCoverageIgnore
|
||||
*/
|
||||
class CreateImport extends Command
|
||||
{
|
||||
@@ -81,10 +83,15 @@ class CreateImport extends Command
|
||||
$configuration = (string)$this->argument('configuration');
|
||||
$user = $userRepository->findNull((int)$this->option('user'));
|
||||
$cwd = getcwd();
|
||||
$type = strtolower((string)$this->option('type'));
|
||||
$provider = strtolower((string)$this->option('provider'));
|
||||
$configurationData = [];
|
||||
|
||||
if (null === $user) {
|
||||
$this->errorLine('User is NULL.');
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (!$this->validArguments()) {
|
||||
$this->errorLine('Invalid arguments.');
|
||||
|
||||
@@ -145,7 +152,7 @@ class CreateImport extends Command
|
||||
|
||||
|
||||
if (true === $this->option('start')) {
|
||||
$this->infoLine('The has started. The process is not visible. Please wait.');
|
||||
$this->infoLine('The import routine has started. The process is not visible. Please wait.');
|
||||
Log::debug('Go for import!');
|
||||
|
||||
// run it!
|
||||
@@ -182,7 +189,7 @@ class CreateImport extends Command
|
||||
}
|
||||
$count++;
|
||||
}
|
||||
if ($importJob->status === 'provider_finished') {
|
||||
if ('provider_finished' === $importJob->status) {
|
||||
$this->infoLine('Import has finished. Please wait for storage of data.');
|
||||
// set job to be storing data:
|
||||
$jobRepository->setStatus($importJob, 'storing_data');
|
||||
@@ -226,7 +233,7 @@ class CreateImport extends Command
|
||||
}
|
||||
}
|
||||
// clear cache for user:
|
||||
Preferences::setForUser($user, 'lastActivity', microtime());
|
||||
app('preferences')->setForUser($user, 'lastActivity', microtime());
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -260,8 +267,8 @@ class CreateImport extends Command
|
||||
*/
|
||||
private function validArguments(): bool
|
||||
{
|
||||
$file = $this->argument('file');
|
||||
$configuration = $this->argument('configuration');
|
||||
$file = (string)$this->argument('file');
|
||||
$configuration = (string)$this->argument('configuration');
|
||||
$cwd = getcwd();
|
||||
$validTypes = config('import.options.file.import_formats');
|
||||
$type = strtolower($this->option('type'));
|
||||
@@ -274,19 +281,19 @@ class CreateImport extends Command
|
||||
return false;
|
||||
}
|
||||
|
||||
if ($provider === 'file' && !\in_array($type, $validTypes, true)) {
|
||||
if ('file' === $provider && !\in_array($type, $validTypes, true)) {
|
||||
$this->errorLine(sprintf('Cannot import file of type "%s"', $type));
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
if ($provider === 'file' && !file_exists($file)) {
|
||||
if ('file' === $provider && !file_exists($file)) {
|
||||
$this->errorLine(sprintf('Firefly III cannot find file "%s" (working directory: "%s").', $file, $cwd));
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
if ($provider === 'file' && !file_exists($configuration)) {
|
||||
if ('file' === $provider && !file_exists($configuration)) {
|
||||
$this->errorLine(sprintf('Firefly III cannot find configuration file "%s" (working directory: "%s").', $configuration, $cwd));
|
||||
|
||||
return false;
|
||||
|
||||
67
app/Console/Commands/Cron.php
Normal file
67
app/Console/Commands/Cron.php
Normal file
@@ -0,0 +1,67 @@
|
||||
<?php
|
||||
|
||||
namespace FireflyIII\Console\Commands;
|
||||
|
||||
use FireflyIII\Exceptions\FireflyException;
|
||||
use FireflyIII\Support\Cronjobs\RecurringCronjob;
|
||||
use Illuminate\Console\Command;
|
||||
|
||||
/**
|
||||
* Class Cron
|
||||
*
|
||||
* @codeCoverageIgnore
|
||||
*/
|
||||
class Cron extends Command
|
||||
{
|
||||
/**
|
||||
* The console command description.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $description = 'Runs all Firefly III cron-job related commands. Configure a cron job according to the official Firefly III documentation.';
|
||||
/**
|
||||
* The name and signature of the console command.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $signature = 'firefly:cron';
|
||||
|
||||
/**
|
||||
* Create a new command instance.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute the console command.
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function handle(): int
|
||||
{
|
||||
$recurring = new RecurringCronjob;
|
||||
try {
|
||||
$result = $recurring->fire();
|
||||
} catch (FireflyException $e) {
|
||||
$this->error($e->getMessage());
|
||||
|
||||
return 0;
|
||||
}
|
||||
if (false === $result) {
|
||||
$this->line('The recurring transaction cron job did not fire.');
|
||||
}
|
||||
if (true === $result) {
|
||||
$this->line('The recurring transaction cron job fired successfully.');
|
||||
}
|
||||
|
||||
$this->info('More feedback on the cron jobs can be found in the log files.');
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -1,5 +1,4 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* DecryptAttachment.php
|
||||
* Copyright (c) 2018 thegrumpydictator@gmail.com
|
||||
@@ -20,6 +19,8 @@
|
||||
* along with Firefly III. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/** @noinspection MultipleReturnStatementsInspection */
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace FireflyIII\Console\Commands;
|
||||
@@ -30,6 +31,8 @@ use Log;
|
||||
|
||||
/**
|
||||
* Class DecryptAttachment.
|
||||
*
|
||||
* @codeCoverageIgnore
|
||||
*/
|
||||
class DecryptAttachment extends Command
|
||||
{
|
||||
@@ -51,44 +54,45 @@ class DecryptAttachment extends Command
|
||||
|
||||
/**
|
||||
* Execute the console command.
|
||||
*
|
||||
* @SuppressWarnings(PHPMD.CyclomaticComplexity) // it's five its fine.
|
||||
* @SuppressWarnings(PHPMD.CyclomaticComplexity)
|
||||
* @SuppressWarnings(PHPMD.ExcessiveMethodLength)
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function handle()
|
||||
public function handle(): int
|
||||
{
|
||||
/** @var AttachmentRepositoryInterface $repository */
|
||||
$repository = app(AttachmentRepositoryInterface::class);
|
||||
$attachmentId = (int)$this->argument('id');
|
||||
$attachment = $repository->findWithoutUser($attachmentId);
|
||||
$attachmentName = trim($this->argument('name'));
|
||||
$storagePath = realpath(trim($this->argument('directory')));
|
||||
if (null === $attachment->id) {
|
||||
$attachmentName = trim((string)$this->argument('name'));
|
||||
$storagePath = realpath(trim((string)$this->argument('directory')));
|
||||
if (null === $attachment) {
|
||||
$this->error(sprintf('No attachment with id #%d', $attachmentId));
|
||||
Log::error(sprintf('DecryptAttachment: No attachment with id #%d', $attachmentId));
|
||||
|
||||
return;
|
||||
return 1;
|
||||
}
|
||||
|
||||
if ($attachmentName !== $attachment->filename) {
|
||||
$this->error('File name does not match.');
|
||||
Log::error('DecryptAttachment: File name does not match.');
|
||||
|
||||
return;
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (!is_dir($storagePath)) {
|
||||
$this->error(sprintf('Path "%s" is not a directory.', $storagePath));
|
||||
Log::error(sprintf('DecryptAttachment: Path "%s" is not a directory.', $storagePath));
|
||||
|
||||
return;
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (!is_writable($storagePath)) {
|
||||
$this->error(sprintf('Path "%s" is not writable.', $storagePath));
|
||||
Log::error(sprintf('DecryptAttachment: Path "%s" is not writable.', $storagePath));
|
||||
|
||||
return;
|
||||
return 1;
|
||||
}
|
||||
|
||||
$fullPath = $storagePath . DIRECTORY_SEPARATOR . $attachment->filename;
|
||||
@@ -98,9 +102,10 @@ class DecryptAttachment extends Command
|
||||
if (false === $result) {
|
||||
$this->error('Could not write to file.');
|
||||
|
||||
return;
|
||||
return 1;
|
||||
}
|
||||
$this->info(sprintf('%d bytes written. Exiting now..', $result));
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* EncryptFile.php
|
||||
* Copyright (c) 2018 thegrumpydictator@gmail.com
|
||||
@@ -30,6 +29,8 @@ use Illuminate\Console\Command;
|
||||
|
||||
/**
|
||||
* Class EncryptFile.
|
||||
*
|
||||
* @codeCoverageIgnore
|
||||
*/
|
||||
class EncryptFile extends Command
|
||||
{
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Import.php
|
||||
* Copyright (c) 2018 thegrumpydictator@gmail.com
|
||||
@@ -20,6 +19,9 @@
|
||||
* along with Firefly III. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/** @noinspection MultipleReturnStatementsInspection */
|
||||
/** @noinspection PhpDynamicAsStaticMethodCallInspection */
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace FireflyIII\Console\Commands;
|
||||
@@ -27,12 +29,14 @@ namespace FireflyIII\Console\Commands;
|
||||
use FireflyIII\Exceptions\FireflyException;
|
||||
use FireflyIII\Import\Routine\RoutineInterface;
|
||||
use FireflyIII\Models\ImportJob;
|
||||
use FireflyIII\Models\Tag;
|
||||
use Illuminate\Console\Command;
|
||||
use Illuminate\Support\MessageBag;
|
||||
use Log;
|
||||
|
||||
/**
|
||||
* Class Import.
|
||||
*
|
||||
* @codeCoverageIgnore
|
||||
*/
|
||||
class Import extends Command
|
||||
{
|
||||
@@ -52,23 +56,26 @@ class Import extends Command
|
||||
|
||||
/**
|
||||
* Run the import routine.
|
||||
* @SuppressWarnings(PHPMD.CyclomaticComplexity)
|
||||
* @SuppressWarnings(PHPMD.ExcessiveMethodLength)
|
||||
*
|
||||
* @throws FireflyException
|
||||
*/
|
||||
public function handle()
|
||||
public function handle(): int
|
||||
{
|
||||
Log::debug('Start start-import command');
|
||||
$jobKey = $this->argument('key');
|
||||
$job = ImportJob::where('key', $jobKey)->first();
|
||||
$jobKey = (string)$this->argument('key');
|
||||
/** @var ImportJob $job */
|
||||
$job = ImportJob::where('key', $jobKey)->first();
|
||||
if (null === $job) {
|
||||
$this->errorLine(sprintf('No job found with key "%s"', $jobKey));
|
||||
|
||||
return;
|
||||
return 1;
|
||||
}
|
||||
if (!$this->isValid($job)) {
|
||||
$this->errorLine('Job is not valid for some reason. Exit.');
|
||||
|
||||
return;
|
||||
return 1;
|
||||
}
|
||||
|
||||
$this->infoLine(sprintf('Going to import job with key "%s" of type "%s"', $job->key, $job->file_type));
|
||||
@@ -83,21 +90,32 @@ class Import extends Command
|
||||
|
||||
/** @var RoutineInterface $routine */
|
||||
$routine = app($className);
|
||||
$routine->setJob($job);
|
||||
$routine->setImportJob($job);
|
||||
$routine->run();
|
||||
|
||||
/** @var MessageBag $error */
|
||||
foreach ($routine->getErrors() as $index => $error) {
|
||||
/**
|
||||
* @var int $index
|
||||
* @var string $error
|
||||
*/
|
||||
foreach ($job->errors as $index => $error) {
|
||||
$this->errorLine(sprintf('Error importing line #%d: %s', $index, $error));
|
||||
}
|
||||
|
||||
$this->infoLine(
|
||||
sprintf('The import has finished. %d transactions have been imported out of %d records.', $routine->getJournals()->count(), $routine->getLines())
|
||||
);
|
||||
/** @var Tag $tag */
|
||||
$tag = $job->tag()->first();
|
||||
$count = 0;
|
||||
if (null === $tag) {
|
||||
$count = $tag->transactionJournals()->count();
|
||||
}
|
||||
|
||||
$this->infoLine(sprintf('The import has finished. %d transactions have been imported.', $count));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Displays an error.
|
||||
*
|
||||
* @param string $message
|
||||
* @param array|null $data
|
||||
*/
|
||||
@@ -109,6 +127,8 @@ class Import extends Command
|
||||
}
|
||||
|
||||
/**
|
||||
* Displays an informational message.
|
||||
*
|
||||
* @param string $message
|
||||
* @param array $data
|
||||
*/
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* ScanAttachments.php
|
||||
* Copyright (c) 2018 thegrumpydictator@gmail.com
|
||||
@@ -20,6 +19,8 @@
|
||||
* along with Firefly III. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/** @noinspection PhpDynamicAsStaticMethodCallInspection */
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace FireflyIII\Console\Commands;
|
||||
@@ -33,6 +34,8 @@ use Storage;
|
||||
|
||||
/**
|
||||
* Class ScanAttachments.
|
||||
*
|
||||
* @codeCoverageIgnore
|
||||
*/
|
||||
class ScanAttachments extends Command
|
||||
{
|
||||
@@ -53,7 +56,7 @@ class ScanAttachments extends Command
|
||||
/**
|
||||
* Execute the console command.
|
||||
*/
|
||||
public function handle()
|
||||
public function handle(): int
|
||||
{
|
||||
$attachments = Attachment::get();
|
||||
$disk = Storage::disk('upload');
|
||||
@@ -63,13 +66,13 @@ class ScanAttachments extends Command
|
||||
try {
|
||||
$content = $disk->get($fileName);
|
||||
} catch (FileNotFoundException $e) {
|
||||
$this->error(sprintf('Could not find data for attachment #%d', $attachment->id));
|
||||
$this->error(sprintf('Could not find data for attachment #%d: %s', $attachment->id, $e->getMessage()));
|
||||
continue;
|
||||
}
|
||||
try {
|
||||
$decrypted = Crypt::decrypt($content);
|
||||
} catch (DecryptException $e) {
|
||||
$this->error(sprintf('Could not decrypt data of attachment #%d', $attachment->id));
|
||||
$this->error(sprintf('Could not decrypt data of attachment #%d: %s', $attachment->id, $e->getMessage()));
|
||||
continue;
|
||||
}
|
||||
$tmpfname = tempnam(sys_get_temp_dir(), 'FireflyIII');
|
||||
@@ -81,5 +84,7 @@ class ScanAttachments extends Command
|
||||
$attachment->save();
|
||||
$this->line(sprintf('Fixed attachment #%d', $attachment->id));
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,6 +20,10 @@
|
||||
* along with Firefly III. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/** @noinspection MultipleReturnStatementsInspection */
|
||||
/** @noinspection PhpStaticAsDynamicMethodCallInspection */
|
||||
/** @noinspection PhpDynamicAsStaticMethodCallInspection */
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace FireflyIII\Console\Commands;
|
||||
@@ -42,22 +46,24 @@ use FireflyIII\Models\TransactionCurrency;
|
||||
use FireflyIII\Models\TransactionJournal;
|
||||
use FireflyIII\Models\TransactionJournalMeta;
|
||||
use FireflyIII\Models\TransactionType;
|
||||
use FireflyIII\Repositories\Account\AccountRepositoryInterface;
|
||||
use FireflyIII\Repositories\Currency\CurrencyRepositoryInterface;
|
||||
use FireflyIII\Repositories\Journal\JournalRepositoryInterface;
|
||||
use FireflyIII\User;
|
||||
use Illuminate\Console\Command;
|
||||
use Illuminate\Database\QueryException;
|
||||
use Illuminate\Support\Collection;
|
||||
use Log;
|
||||
use Preferences;
|
||||
use Schema;
|
||||
use UnexpectedValueException;
|
||||
|
||||
/**
|
||||
* Class UpgradeDatabase.
|
||||
*
|
||||
* Upgrade user database.
|
||||
*
|
||||
*
|
||||
* @SuppressWarnings(PHPMD.CouplingBetweenObjects) // it just touches a lot of things.
|
||||
* @SuppressWarnings(PHPMD.ExcessiveClassComplexity)
|
||||
* @SuppressWarnings(PHPMD.CouplingBetweenObjects)
|
||||
* @codeCoverageIgnore
|
||||
*/
|
||||
class UpgradeDatabase extends Command
|
||||
{
|
||||
@@ -77,7 +83,7 @@ class UpgradeDatabase extends Command
|
||||
/**
|
||||
* Execute the console command.
|
||||
*/
|
||||
public function handle()
|
||||
public function handle(): int
|
||||
{
|
||||
$this->setTransactionIdentifier();
|
||||
$this->updateAccountCurrencies();
|
||||
@@ -91,22 +97,39 @@ class UpgradeDatabase extends Command
|
||||
$this->migrateBillsToRules();
|
||||
|
||||
$this->info('Firefly III database is up to date.');
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
public function migrateBillsToRules()
|
||||
/**
|
||||
* Since it is one routine these warnings make sense and should be supressed.
|
||||
*
|
||||
* @SuppressWarnings(PHPMD.CyclomaticComplexity)
|
||||
* @SuppressWarnings(PHPMD.ExcessiveMethodLength)
|
||||
* @SuppressWarnings(PHPMD.NPathComplexity)
|
||||
*/
|
||||
public function migrateBillsToRules(): void
|
||||
{
|
||||
foreach (User::get() as $user) {
|
||||
/** @var Preference $lang */
|
||||
$lang = Preferences::getForUser($user, 'language', 'en_US');
|
||||
$lang = app('preferences')->getForUser($user, 'language', 'en_US');
|
||||
$groupName = (string)trans('firefly.rulegroup_for_bills_title', [], $lang->data);
|
||||
$ruleGroup = $user->ruleGroups()->where('title', $groupName)->first();
|
||||
$currencyPreference = Preferences::getForUser($user, 'currencyPreference', config('firefly.default_currency', 'EUR'));
|
||||
$currency = TransactionCurrency::where('code', $currencyPreference->data)->first();
|
||||
$currencyPreference = app('preferences')->getForUser($user, 'currencyPreference', config('firefly.default_currency', 'EUR'));
|
||||
|
||||
if (null === $currencyPreference) {
|
||||
$this->error('User has no currency preference. Impossible.');
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
$currency = TransactionCurrency::where('code', $currencyPreference->data)->first();
|
||||
if (null === $currency) {
|
||||
$this->line('Fall back to default currency in migrateBillsToRules().');
|
||||
$currency = app('amount')->getDefaultCurrency();
|
||||
}
|
||||
|
||||
if ($ruleGroup === null) {
|
||||
if (null === $ruleGroup) {
|
||||
$array = RuleGroup::get(['order'])->pluck('order')->toArray();
|
||||
$order = \count($array) > 0 ? max($array) + 1 : 1;
|
||||
$ruleGroup = RuleGroup::create(
|
||||
@@ -126,7 +149,7 @@ class UpgradeDatabase extends Command
|
||||
$collection = $user->bills()->get();
|
||||
/** @var Bill $bill */
|
||||
foreach ($collection as $bill) {
|
||||
if ($bill->match !== 'MIGRATED_TO_RULES') {
|
||||
if ('MIGRATED_TO_RULES' !== $bill->match) {
|
||||
$rule = Rule::create(
|
||||
[
|
||||
'user_id' => $user->id,
|
||||
@@ -177,7 +200,7 @@ class UpgradeDatabase extends Command
|
||||
[
|
||||
'rule_id' => $rule->id,
|
||||
'trigger_type' => 'amount_more',
|
||||
'trigger_value' => round($bill->amount_min, $currency->decimal_places),
|
||||
'trigger_value' => round((float)$bill->amount_min, $currency->decimal_places),
|
||||
'active' => 1,
|
||||
'stop_processing' => 0,
|
||||
'order' => 4,
|
||||
@@ -189,7 +212,7 @@ class UpgradeDatabase extends Command
|
||||
[
|
||||
'rule_id' => $rule->id,
|
||||
'trigger_type' => 'amount_exactly',
|
||||
'trigger_value' => round($bill->amount_min, $currency->decimal_places),
|
||||
'trigger_value' => round((float)$bill->amount_min, $currency->decimal_places),
|
||||
'active' => 1,
|
||||
'stop_processing' => 0,
|
||||
'order' => 3,
|
||||
@@ -260,23 +283,29 @@ class UpgradeDatabase extends Command
|
||||
/**
|
||||
* Each (asset) account must have a reference to a preferred currency. If the account does not have one, it's forced upon the account.
|
||||
*
|
||||
* @SuppressWarnings(PHPMD.CyclomaticComplexity) // it's seven but it can't really be helped.
|
||||
* @SuppressWarnings(PHPMD.CyclomaticComplexity)
|
||||
* @SuppressWarnings(PHPMD.ExcessiveMethodLength)
|
||||
*/
|
||||
public function updateAccountCurrencies(): void
|
||||
{
|
||||
$accounts = Account::leftJoin('account_types', 'account_types.id', '=', 'accounts.account_type_id')
|
||||
->whereIn('account_types.type', [AccountType::DEFAULT, AccountType::ASSET])->get(['accounts.*']);
|
||||
|
||||
/** @var AccountRepositoryInterface $repository */
|
||||
$repository = app(AccountRepositoryInterface::class);
|
||||
$accounts->each(
|
||||
function (Account $account) {
|
||||
function (Account $account) use ($repository) {
|
||||
$repository->setUser($account->user);
|
||||
// get users preference, fall back to system pref.
|
||||
$defaultCurrencyCode = Preferences::getForUser($account->user, 'currencyPreference', config('firefly.default_currency', 'EUR'))->data;
|
||||
$defaultCurrencyCode = app('preferences')->getForUser($account->user, 'currencyPreference', config('firefly.default_currency', 'EUR'))->data;
|
||||
$defaultCurrency = TransactionCurrency::where('code', $defaultCurrencyCode)->first();
|
||||
$accountCurrency = (int)$account->getMeta('currency_id');
|
||||
$accountCurrency = (int)$repository->getMetaValue($account, 'currency_id');
|
||||
$openingBalance = $account->getOpeningBalance();
|
||||
$obCurrency = (int)$openingBalance->transaction_currency_id;
|
||||
|
||||
if (null === $defaultCurrency) {
|
||||
throw new UnexpectedValueException('The default currency is NULL, and this is more or less impossible.');
|
||||
}
|
||||
|
||||
// both 0? set to default currency:
|
||||
if (0 === $accountCurrency && 0 === $obCurrency) {
|
||||
AccountMeta::where('account_id', $account->id)->where('name', 'currency_id')->forceDelete();
|
||||
@@ -317,19 +346,22 @@ class UpgradeDatabase extends Command
|
||||
* Both source and destination must match the respective currency preference of the related asset account.
|
||||
* So FF3 must verify all transactions.
|
||||
*
|
||||
* @SuppressWarnings(PHPMD.CyclomaticComplexity)
|
||||
* @SuppressWarnings(PHPMD.ExcessiveMethodLength)
|
||||
*/
|
||||
public function updateOtherCurrencies(): void
|
||||
{
|
||||
/** @var CurrencyRepositoryInterface $repository */
|
||||
$repository = app(CurrencyRepositoryInterface::class);
|
||||
$set = TransactionJournal
|
||||
/** @var AccountRepositoryInterface $accountRepos */
|
||||
$accountRepos = app(AccountRepositoryInterface::class);
|
||||
$set = TransactionJournal
|
||||
::leftJoin('transaction_types', 'transaction_types.id', '=', 'transaction_journals.transaction_type_id')
|
||||
->whereIn('transaction_types.type', [TransactionType::WITHDRAWAL, TransactionType::DEPOSIT, TransactionType::OPENING_BALANCE])
|
||||
->get(['transaction_journals.*']);
|
||||
|
||||
$set->each(
|
||||
function (TransactionJournal $journal) use ($repository) {
|
||||
function (TransactionJournal $journal) use ($repository, $accountRepos) {
|
||||
// get the transaction with the asset account in it:
|
||||
/** @var Transaction $transaction */
|
||||
$transaction = $journal->transactions()
|
||||
@@ -339,9 +371,13 @@ class UpgradeDatabase extends Command
|
||||
if (null === $transaction) {
|
||||
return;
|
||||
}
|
||||
$accountRepos->setUser($journal->user);
|
||||
/** @var Account $account */
|
||||
$account = $transaction->account;
|
||||
$currency = $repository->find((int)$account->getMeta('currency_id'));
|
||||
$account = $transaction->account;
|
||||
$currency = $repository->findNull((int)$accountRepos->getMetaValue($account, 'currency_id'));
|
||||
if (null === $currency) {
|
||||
return;
|
||||
}
|
||||
$transactions = $journal->transactions()->get();
|
||||
$transactions->each(
|
||||
function (Transaction $transaction) use ($currency) {
|
||||
@@ -377,7 +413,7 @@ class UpgradeDatabase extends Command
|
||||
* Both source and destination must match the respective currency preference. So FF3 must verify ALL
|
||||
* transactions.
|
||||
*/
|
||||
public function updateTransferCurrencies()
|
||||
public function updateTransferCurrencies(): void
|
||||
{
|
||||
$set = TransactionJournal
|
||||
::leftJoin('transaction_types', 'transaction_types.id', '=', 'transaction_journals.transaction_type_id')
|
||||
@@ -449,6 +485,7 @@ class UpgradeDatabase extends Command
|
||||
*/
|
||||
private function migrateNotes(): void
|
||||
{
|
||||
/** @noinspection PhpUndefinedMethodInspection */
|
||||
$set = TransactionJournalMeta::whereName('notes')->get();
|
||||
/** @var TransactionJournalMeta $meta */
|
||||
foreach ($set as $meta) {
|
||||
@@ -479,8 +516,15 @@ class UpgradeDatabase extends Command
|
||||
{
|
||||
/** @var CurrencyRepositoryInterface $repository */
|
||||
$repository = app(CurrencyRepositoryInterface::class);
|
||||
$currency = $repository->find((int)$transaction->account->getMeta('currency_id'));
|
||||
$journal = $transaction->transactionJournal;
|
||||
/** @var AccountRepositoryInterface $accountRepos */
|
||||
$accountRepos = app(AccountRepositoryInterface::class);
|
||||
$accountRepos->setUser($transaction->account->user);
|
||||
$currency = $repository->findNull((int)$accountRepos->getMetaValue($transaction->account, 'currency_id'));
|
||||
$journal = $transaction->transactionJournal;
|
||||
|
||||
if (null === $currency) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!((int)$currency->id === (int)$journal->transaction_currency_id)) {
|
||||
$this->line(
|
||||
@@ -549,11 +593,11 @@ class UpgradeDatabase extends Command
|
||||
*
|
||||
* The transaction that is sent to this function MUST be the source transaction (amount negative).
|
||||
*
|
||||
* Method is long and complex bit I'm taking it for granted.
|
||||
* Method is long and complex but I'll allow it. https://imgur.com/gallery/dVDJiez
|
||||
*
|
||||
* @SuppressWarnings(PHPMD.CyclomaticComplexity)
|
||||
* @SuppressWarnings(PHPMD.ExcessiveMethodLength)
|
||||
* @SuppressWarnings(PHPMD.NPathComplexity)
|
||||
* @SuppressWarnings(PHPMD.CyclomaticComplexity)
|
||||
*
|
||||
* @param Transaction $transaction
|
||||
*/
|
||||
@@ -561,7 +605,14 @@ class UpgradeDatabase extends Command
|
||||
{
|
||||
/** @var CurrencyRepositoryInterface $repository */
|
||||
$repository = app(CurrencyRepositoryInterface::class);
|
||||
$currency = $repository->findNull((int)$transaction->account->getMeta('currency_id'));
|
||||
/** @var AccountRepositoryInterface $accountRepos */
|
||||
$accountRepos = app(AccountRepositoryInterface::class);
|
||||
/** @var JournalRepositoryInterface $journalRepos */
|
||||
$journalRepos = app(JournalRepositoryInterface::class);
|
||||
|
||||
$accountRepos->setUser($transaction->account->user);
|
||||
$journalRepos->setUser($transaction->account->user);
|
||||
$currency = $repository->findNull((int)$accountRepos->getMetaValue($transaction->account, 'currency_id'));
|
||||
|
||||
if (null === $currency) {
|
||||
Log::error(sprintf('Account #%d ("%s") must have currency preference but has none.', $transaction->account->id, $transaction->account->name));
|
||||
@@ -597,7 +648,7 @@ class UpgradeDatabase extends Command
|
||||
$journal = $transaction->transactionJournal;
|
||||
/** @var Transaction $opposing */
|
||||
$opposing = $journal->transactions()->where('amount', '>', 0)->where('identifier', $transaction->identifier)->first();
|
||||
$opposingCurrency = $repository->findNull((int)$opposing->account->getMeta('currency_id'));
|
||||
$opposingCurrency = $repository->findNull((int)$accountRepos->getMetaValue($opposing->account, 'currency_id'));
|
||||
|
||||
if (null === $opposingCurrency) {
|
||||
Log::error(sprintf('Account #%d ("%s") must have currency preference but has none.', $opposing->account->id, $opposing->account->name));
|
||||
@@ -653,7 +704,7 @@ class UpgradeDatabase extends Command
|
||||
|
||||
// when both are zero, try to grab it from journal:
|
||||
if (null === $opposing->foreign_amount && null === $transaction->foreign_amount) {
|
||||
$foreignAmount = $journal->getMeta('foreign_amount');
|
||||
$foreignAmount = $journalRepos->getMetaField($journal, 'foreign_amount');
|
||||
if (null === $foreignAmount) {
|
||||
Log::debug(sprintf('Journal #%d has missing foreign currency data, forced to do 1:1 conversion :(.', $transaction->transaction_journal_id));
|
||||
$transaction->foreign_amount = bcmul((string)$transaction->amount, '-1');
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* UpgradeFireflyInstructions.php
|
||||
* Copyright (c) 2018 thegrumpydictator@gmail.com
|
||||
@@ -28,6 +27,8 @@ use Illuminate\Console\Command;
|
||||
|
||||
/**
|
||||
* Class UpgradeFireflyInstructions.
|
||||
*
|
||||
* @codeCoverageIgnore
|
||||
*/
|
||||
class UpgradeFireflyInstructions extends Command
|
||||
{
|
||||
@@ -47,14 +48,16 @@ class UpgradeFireflyInstructions extends Command
|
||||
/**
|
||||
* Execute the console command.
|
||||
*/
|
||||
public function handle()
|
||||
public function handle(): int
|
||||
{
|
||||
if ('update' === $this->argument('task')) {
|
||||
if ('update' === (string)$this->argument('task')) {
|
||||
$this->updateInstructions();
|
||||
}
|
||||
if ('install' === $this->argument('task')) {
|
||||
if ('install' === (string)$this->argument('task')) {
|
||||
$this->installInstructions();
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -62,7 +65,7 @@ class UpgradeFireflyInstructions extends Command
|
||||
*
|
||||
* @param string $text
|
||||
*/
|
||||
private function boxed(string $text)
|
||||
private function boxed(string $text): void
|
||||
{
|
||||
$parts = explode("\n", wordwrap($text));
|
||||
foreach ($parts as $string) {
|
||||
@@ -75,7 +78,7 @@ class UpgradeFireflyInstructions extends Command
|
||||
*
|
||||
* @param string $text
|
||||
*/
|
||||
private function boxedInfo(string $text)
|
||||
private function boxedInfo(string $text): void
|
||||
{
|
||||
$parts = explode("\n", wordwrap($text));
|
||||
foreach ($parts as $string) {
|
||||
@@ -86,7 +89,7 @@ class UpgradeFireflyInstructions extends Command
|
||||
/**
|
||||
* Render instructions.
|
||||
*/
|
||||
private function installInstructions()
|
||||
private function installInstructions(): void
|
||||
{
|
||||
/** @var string $version */
|
||||
$version = config('firefly.version');
|
||||
@@ -94,8 +97,7 @@ class UpgradeFireflyInstructions extends Command
|
||||
$text = '';
|
||||
foreach (array_keys($config) as $compare) {
|
||||
// if string starts with:
|
||||
$len = \strlen($compare);
|
||||
if (substr($version, 0, $len) === $compare) {
|
||||
if (0 === strpos($version, $compare)) {
|
||||
$text = $config[$compare];
|
||||
}
|
||||
}
|
||||
@@ -120,7 +122,7 @@ class UpgradeFireflyInstructions extends Command
|
||||
/**
|
||||
* Show a line.
|
||||
*/
|
||||
private function showLine()
|
||||
private function showLine(): void
|
||||
{
|
||||
$line = '+';
|
||||
for ($i = 0; $i < 78; ++$i) {
|
||||
@@ -133,7 +135,7 @@ class UpgradeFireflyInstructions extends Command
|
||||
/**
|
||||
* Render upgrade instructions.
|
||||
*/
|
||||
private function updateInstructions()
|
||||
private function updateInstructions(): void
|
||||
{
|
||||
/** @var string $version */
|
||||
$version = config('firefly.version');
|
||||
@@ -141,8 +143,7 @@ class UpgradeFireflyInstructions extends Command
|
||||
$text = '';
|
||||
foreach (array_keys($config) as $compare) {
|
||||
// if string starts with:
|
||||
$len = \strlen($compare);
|
||||
if (substr($version, 0, $len) === $compare) {
|
||||
if (0 === strpos($version, $compare)) {
|
||||
$text = $config[$compare];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* UseEncryption.php
|
||||
* Copyright (c) 2018 thegrumpydictator@gmail.com
|
||||
@@ -29,6 +28,7 @@ use Illuminate\Support\Str;
|
||||
|
||||
/**
|
||||
* Class UseEncryption.
|
||||
* @codeCoverageIgnore
|
||||
*/
|
||||
class UseEncryption extends Command
|
||||
{
|
||||
@@ -48,12 +48,12 @@ class UseEncryption extends Command
|
||||
/**
|
||||
* Execute the console command.
|
||||
*/
|
||||
public function handle()
|
||||
public function handle(): int
|
||||
{
|
||||
if (config('firefly.encryption') === true) {
|
||||
if (true === config('firefly.encryption')) {
|
||||
$this->info('Firefly III configuration calls for encrypted data.');
|
||||
}
|
||||
if (config('firefly.encryption') === false) {
|
||||
if (false === config('firefly.encryption')) {
|
||||
$this->info('Firefly III configuration calls for unencrypted data.');
|
||||
}
|
||||
$this->handleObjects('Account', 'name', 'encrypted');
|
||||
@@ -63,6 +63,8 @@ class UseEncryption extends Command
|
||||
$this->handleObjects('Category', 'name', 'encrypted');
|
||||
$this->handleObjects('PiggyBank', 'name', 'encrypted');
|
||||
$this->handleObjects('TransactionJournal', 'description', 'encrypted');
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -72,18 +74,21 @@ class UseEncryption extends Command
|
||||
* @param string $field
|
||||
* @param string $indicator
|
||||
*/
|
||||
public function handleObjects(string $class, string $field, string $indicator)
|
||||
public function handleObjects(string $class, string $field, string $indicator): void
|
||||
{
|
||||
$fqn = sprintf('FireflyIII\Models\%s', $class);
|
||||
$encrypt = config('firefly.encryption') === true ? 0 : 1;
|
||||
$set = $fqn::where($indicator, $encrypt)->get();
|
||||
$encrypt = true === config('firefly.encryption') ? 0 : 1;
|
||||
/** @noinspection PhpUndefinedMethodInspection */
|
||||
$set = $fqn::where($indicator, $encrypt)->get();
|
||||
|
||||
foreach ($set as $entry) {
|
||||
$newName = $entry->$field;
|
||||
$entry->$field = $newName;
|
||||
/** @noinspection PhpUndefinedMethodInspection */
|
||||
$entry->save();
|
||||
}
|
||||
|
||||
/** @noinspection PhpUndefinedMethodInspection */
|
||||
$this->line(sprintf('Updated %d %s.', $set->count(), strtolower(Str::plural($class))));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* VerifiesAccessToken.php
|
||||
* Copyright (c) 2018 thegrumpydictator@gmail.com
|
||||
@@ -26,12 +25,12 @@ namespace FireflyIII\Console\Commands;
|
||||
|
||||
use FireflyIII\Repositories\User\UserRepositoryInterface;
|
||||
use Log;
|
||||
use Preferences;
|
||||
|
||||
/**
|
||||
* Trait VerifiesAccessToken.
|
||||
*
|
||||
* Verifies user access token for sensitive commands.
|
||||
* @codeCoverageIgnore
|
||||
*/
|
||||
trait VerifiesAccessToken
|
||||
{
|
||||
@@ -62,7 +61,7 @@ trait VerifiesAccessToken
|
||||
|
||||
return false;
|
||||
}
|
||||
$accessToken = Preferences::getForUser($user, 'access_token', null);
|
||||
$accessToken = app('preferences')->getForUser($user, 'access_token', null);
|
||||
if (null === $accessToken) {
|
||||
Log::error(sprintf('User #%d has no access token, so cannot access command line options.', $userId));
|
||||
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* VerifyDatabase.php
|
||||
* Copyright (c) 2018 thegrumpydictator@gmail.com
|
||||
@@ -20,6 +19,8 @@
|
||||
* along with Firefly III. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/** @noinspection PhpDynamicAsStaticMethodCallInspection */
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace FireflyIII\Console\Commands;
|
||||
@@ -29,6 +30,7 @@ use DB;
|
||||
use FireflyIII\Models\Account;
|
||||
use FireflyIII\Models\AccountType;
|
||||
use FireflyIII\Models\Budget;
|
||||
use FireflyIII\Models\Category;
|
||||
use FireflyIII\Models\LinkType;
|
||||
use FireflyIII\Models\PiggyBankEvent;
|
||||
use FireflyIII\Models\Transaction;
|
||||
@@ -39,14 +41,16 @@ use FireflyIII\User;
|
||||
use Illuminate\Console\Command;
|
||||
use Illuminate\Contracts\Encryption\DecryptException;
|
||||
use Illuminate\Database\Eloquent\Builder;
|
||||
use Preferences;
|
||||
use Log;
|
||||
use Schema;
|
||||
use stdClass;
|
||||
|
||||
/**
|
||||
* Class VerifyDatabase.
|
||||
*
|
||||
* @SuppressWarnings(PHPMD.ExcessiveClassComplexity)
|
||||
* @SuppressWarnings(PHPMD.CouplingBetweenObjects)
|
||||
* @codeCoverageIgnore
|
||||
*/
|
||||
class VerifyDatabase extends Command
|
||||
{
|
||||
@@ -66,15 +70,15 @@ class VerifyDatabase extends Command
|
||||
/**
|
||||
* Execute the console command.
|
||||
*/
|
||||
public function handle()
|
||||
public function handle(): int
|
||||
{
|
||||
// if table does not exist, return false
|
||||
if (!Schema::hasTable('users')) {
|
||||
return;
|
||||
return 1;
|
||||
}
|
||||
|
||||
$this->reportObject('budget');
|
||||
$this->reportObject('category');
|
||||
$this->reportEmptyBudgets();
|
||||
$this->reportEmptyCategories();
|
||||
$this->reportObject('tag');
|
||||
$this->reportAccounts();
|
||||
$this->reportBudgetLimits();
|
||||
@@ -91,6 +95,8 @@ class VerifyDatabase extends Command
|
||||
$this->fixDoubleAmounts();
|
||||
$this->fixBadMeta();
|
||||
$this->removeBills();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -102,10 +108,10 @@ class VerifyDatabase extends Command
|
||||
$users = User::get();
|
||||
/** @var User $user */
|
||||
foreach ($users as $user) {
|
||||
$pref = Preferences::getForUser($user, 'access_token', null);
|
||||
$pref = app('preferences')->getForUser($user, 'access_token', null);
|
||||
if (null === $pref) {
|
||||
$token = $user->generateAccessToken();
|
||||
Preferences::setForUser($user, 'access_token', $token);
|
||||
app('preferences')->setForUser($user, 'access_token', $token);
|
||||
$this->line(sprintf('Generated access token for user %s', $user->email));
|
||||
++$count;
|
||||
}
|
||||
@@ -145,9 +151,10 @@ class VerifyDatabase extends Command
|
||||
}
|
||||
|
||||
/**
|
||||
* Fix the situation where the matching transactions
|
||||
* of a journal somehow have non-matching categories
|
||||
* or budgets
|
||||
* Fix the situation where the matching transactions of a journal somehow have non-matching categories or budgets.
|
||||
*
|
||||
* @SuppressWarnings(PHPMD.CyclomaticComplexity)
|
||||
* @SuppressWarnings(PHPMD.ExcessiveMethodLength)
|
||||
*/
|
||||
private function fixBadMeta(): void
|
||||
{
|
||||
@@ -208,6 +215,12 @@ class VerifyDatabase extends Command
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Makes sure amounts are stored correctly.
|
||||
*
|
||||
* @SuppressWarnings(PHPMD.CyclomaticComplexity)
|
||||
* @SuppressWarnings(PHPMD.ExcessiveMethodLength)
|
||||
*/
|
||||
private function fixDoubleAmounts(): void
|
||||
{
|
||||
$count = 0;
|
||||
@@ -257,7 +270,7 @@ class VerifyDatabase extends Command
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* Removes bills from journals that should not have bills.
|
||||
*/
|
||||
private function removeBills(): void
|
||||
{
|
||||
@@ -305,7 +318,7 @@ class VerifyDatabase extends Command
|
||||
/**
|
||||
* Reports on accounts with no transactions.
|
||||
*/
|
||||
private function reportAccounts()
|
||||
private function reportAccounts(): void
|
||||
{
|
||||
$set = Account::leftJoin('transactions', 'transactions.account_id', '=', 'accounts.id')
|
||||
->leftJoin('users', 'accounts.user_id', '=', 'users.id')
|
||||
@@ -378,6 +391,82 @@ class VerifyDatabase extends Command
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Report on budgets with no transactions or journals.
|
||||
*/
|
||||
private function reportEmptyBudgets(): void
|
||||
{
|
||||
$set = Budget::leftJoin('budget_transaction_journal', 'budgets.id', '=', 'budget_transaction_journal.budget_id')
|
||||
->leftJoin('users', 'budgets.user_id', '=', 'users.id')
|
||||
->distinct()
|
||||
->whereNull('budget_transaction_journal.budget_id')
|
||||
->whereNull('budgets.deleted_at')
|
||||
->get(['budgets.id', 'budgets.name', 'budgets.user_id', 'users.email']);
|
||||
|
||||
/** @var stdClass $entry */
|
||||
foreach ($set as $entry) {
|
||||
$objName = $entry->name;
|
||||
try {
|
||||
$objName = Crypt::decrypt($objName);
|
||||
} catch (DecryptException $e) {
|
||||
// it probably was not encrypted.
|
||||
Log::debug(sprintf('Not a problem: %s', $e->getMessage()));
|
||||
}
|
||||
|
||||
// also count the transactions:
|
||||
$countTransactions = DB::table('budget_transaction')->where('budget_id', $entry->id)->count();
|
||||
|
||||
if (0 === $countTransactions) {
|
||||
$line = sprintf(
|
||||
'User #%d (%s) has budget #%d ("%s") which has no transactions.',
|
||||
$entry->user_id,
|
||||
$entry->email,
|
||||
$entry->id,
|
||||
$objName
|
||||
);
|
||||
$this->line($line);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Report on categories with no transactions or journals.
|
||||
*/
|
||||
private function reportEmptyCategories(): void
|
||||
{
|
||||
$set = Category::leftJoin('category_transaction_journal', 'categories.id', '=', 'category_transaction_journal.category_id')
|
||||
->leftJoin('users', 'categories.user_id', '=', 'users.id')
|
||||
->distinct()
|
||||
->whereNull('category_transaction_journal.category_id')
|
||||
->whereNull('categories.deleted_at')
|
||||
->get(['categories.id', 'categories.name', 'categories.user_id', 'users.email']);
|
||||
|
||||
/** @var stdClass $entry */
|
||||
foreach ($set as $entry) {
|
||||
$objName = $entry->name;
|
||||
try {
|
||||
$objName = Crypt::decrypt($objName);
|
||||
} catch (DecryptException $e) {
|
||||
// it probably was not encrypted.
|
||||
Log::debug(sprintf('Not a problem: %s', $e->getMessage()));
|
||||
}
|
||||
|
||||
// also count the transactions:
|
||||
$countTransactions = DB::table('category_transaction')->where('category_id', $entry->id)->count();
|
||||
|
||||
if (0 === $countTransactions) {
|
||||
$line = sprintf(
|
||||
'User #%d (%s) has category #%d ("%s") which has no transactions.',
|
||||
$entry->user_id,
|
||||
$entry->email,
|
||||
$entry->id,
|
||||
$objName
|
||||
);
|
||||
$this->line($line);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Report on journals with bad account types linked to them.
|
||||
*/
|
||||
@@ -483,12 +572,13 @@ class VerifyDatabase extends Command
|
||||
$plural = str_plural($name);
|
||||
$class = sprintf('FireflyIII\Models\%s', ucfirst($name));
|
||||
$field = 'tag' === $name ? 'tag' : 'name';
|
||||
$set = $class::leftJoin($name . '_transaction_journal', $plural . '.id', '=', $name . '_transaction_journal.' . $name . '_id')
|
||||
->leftJoin('users', $plural . '.user_id', '=', 'users.id')
|
||||
->distinct()
|
||||
->whereNull($name . '_transaction_journal.' . $name . '_id')
|
||||
->whereNull($plural . '.deleted_at')
|
||||
->get([$plural . '.id', $plural . '.' . $field . ' as name', $plural . '.user_id', 'users.email']);
|
||||
/** @noinspection PhpUndefinedMethodInspection */
|
||||
$set = $class::leftJoin($name . '_transaction_journal', $plural . '.id', '=', $name . '_transaction_journal.' . $name . '_id')
|
||||
->leftJoin('users', $plural . '.user_id', '=', 'users.id')
|
||||
->distinct()
|
||||
->whereNull($name . '_transaction_journal.' . $name . '_id')
|
||||
->whereNull($plural . '.deleted_at')
|
||||
->get([$plural . '.id', $plural . '.' . $field . ' as name', $plural . '.user_id', 'users.email']);
|
||||
|
||||
/** @var stdClass $entry */
|
||||
foreach ($set as $entry) {
|
||||
@@ -497,6 +587,7 @@ class VerifyDatabase extends Command
|
||||
$objName = Crypt::decrypt($objName);
|
||||
} catch (DecryptException $e) {
|
||||
// it probably was not encrypted.
|
||||
Log::debug(sprintf('Not a problem: %s', $e->getMessage()));
|
||||
}
|
||||
|
||||
$line = sprintf(
|
||||
@@ -524,7 +615,8 @@ class VerifyDatabase extends Command
|
||||
$sum = (string)$user->transactions()->sum('amount');
|
||||
if (0 !== bccomp($sum, '0')) {
|
||||
$this->error('Error: Transactions for user #' . $user->id . ' (' . $user->email . ') are off by ' . $sum . '!');
|
||||
} else {
|
||||
}
|
||||
if (0 === bccomp($sum, '0')) {
|
||||
$this->info(sprintf('Amount integrity OK for user #%d', $user->id));
|
||||
}
|
||||
}
|
||||
@@ -554,7 +646,7 @@ class VerifyDatabase extends Command
|
||||
/**
|
||||
* Report on transfers that have budgets.
|
||||
*/
|
||||
private function reportTransfersBudgets()
|
||||
private function reportTransfersBudgets(): void
|
||||
{
|
||||
$set = TransactionJournal::distinct()
|
||||
->leftJoin('transaction_types', 'transaction_types.id', '=', 'transaction_journals.transaction_type_id')
|
||||
|
||||
@@ -24,25 +24,16 @@ declare(strict_types=1);
|
||||
|
||||
namespace FireflyIII\Console;
|
||||
|
||||
use Carbon\Carbon;
|
||||
use FireflyIII\Jobs\CreateRecurringTransactions;
|
||||
use Illuminate\Console\Scheduling\Schedule;
|
||||
use Illuminate\Foundation\Console\Kernel as ConsoleKernel;
|
||||
use Log;
|
||||
|
||||
/**
|
||||
* File to make sure commands work.
|
||||
* @codeCoverageIgnore
|
||||
*/
|
||||
class Kernel extends ConsoleKernel
|
||||
{
|
||||
/**
|
||||
* The Artisan commands provided by your application.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $commands
|
||||
= [
|
||||
];
|
||||
|
||||
/**
|
||||
* Register the commands for the application.
|
||||
*/
|
||||
@@ -50,6 +41,7 @@ class Kernel extends ConsoleKernel
|
||||
{
|
||||
$this->load(__DIR__ . '/Commands');
|
||||
|
||||
/** @noinspection PhpIncludeInspection */
|
||||
require base_path('routes/console.php');
|
||||
}
|
||||
|
||||
@@ -60,6 +52,21 @@ class Kernel extends ConsoleKernel
|
||||
*/
|
||||
protected function schedule(Schedule $schedule): void
|
||||
{
|
||||
$schedule->job(new CreateRecurringTransactions(new Carbon))->daily();
|
||||
$schedule->call(
|
||||
function () {
|
||||
Log::error('Firefly III no longer users the Laravel scheduler to do cron jobs! Please read the instructions at https://firefly-iii.readthedocs.io/en/latest/');
|
||||
echo "\n";
|
||||
echo '------------';
|
||||
echo "\n";
|
||||
echo wordwrap('Firefly III no longer users the Laravel scheduler to do cron jobs! Please read the instructions here:');
|
||||
echo "\n";
|
||||
echo 'https://firefly-iii.readthedocs.io/en/latest/';
|
||||
echo "\n\n";
|
||||
echo 'Disable this cron job!';
|
||||
echo "\n";
|
||||
echo '------------';
|
||||
echo "\n";
|
||||
}
|
||||
)->everyMinute();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -30,18 +30,15 @@ use Log;
|
||||
|
||||
/**
|
||||
* Class AdminRequestedTestMessage.
|
||||
* @codeCoverageIgnore
|
||||
*/
|
||||
class AdminRequestedTestMessage extends Event
|
||||
{
|
||||
use SerializesModels;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
/** @var string The users IP address */
|
||||
public $ipAddress;
|
||||
/**
|
||||
* @var User
|
||||
*/
|
||||
/** @var User The user */
|
||||
public $user;
|
||||
|
||||
/**
|
||||
|
||||
@@ -26,6 +26,7 @@ namespace FireflyIII\Events;
|
||||
|
||||
/**
|
||||
* Class Event.
|
||||
* @codeCoverageIgnore
|
||||
*/
|
||||
abstract class Event
|
||||
{
|
||||
|
||||
@@ -29,18 +29,15 @@ use Illuminate\Queue\SerializesModels;
|
||||
|
||||
/**
|
||||
* Class RegisteredUser.
|
||||
* @codeCoverageIgnore
|
||||
*/
|
||||
class RegisteredUser extends Event
|
||||
{
|
||||
use SerializesModels;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
/** @var string The users IP address */
|
||||
public $ipAddress;
|
||||
/**
|
||||
* @var User
|
||||
*/
|
||||
/** @var User The user */
|
||||
public $user;
|
||||
|
||||
/**
|
||||
|
||||
@@ -29,22 +29,17 @@ use Illuminate\Queue\SerializesModels;
|
||||
|
||||
/**
|
||||
* Class RequestedNewPassword.
|
||||
* @codeCoverageIgnore
|
||||
*/
|
||||
class RequestedNewPassword extends Event
|
||||
{
|
||||
use SerializesModels;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
/** @var string The users IP address */
|
||||
public $ipAddress;
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
/** @var string The token */
|
||||
public $token;
|
||||
/**
|
||||
* @var User
|
||||
*/
|
||||
/** @var User The user */
|
||||
public $user;
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,4 +1,24 @@
|
||||
<?php
|
||||
declare(strict_types=1);
|
||||
/**
|
||||
* RequestedReportOnJournals.php
|
||||
* Copyright (c) 2018 thegrumpydictator@gmail.com
|
||||
*
|
||||
* This file is part of Firefly III.
|
||||
*
|
||||
* Firefly III is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Firefly III is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Firefly III. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
namespace FireflyIII\Events;
|
||||
|
||||
@@ -11,14 +31,16 @@ use Log;
|
||||
|
||||
/**
|
||||
* Class RequestedReportOnJournals
|
||||
*
|
||||
* @codeCoverageIgnore
|
||||
*/
|
||||
class RequestedReportOnJournals
|
||||
{
|
||||
use Dispatchable, InteractsWithSockets, SerializesModels;
|
||||
|
||||
/** @var Collection */
|
||||
/** @var Collection The journals to report on. */
|
||||
public $journals;
|
||||
/** @var int */
|
||||
/** @var int The ID of the user. */
|
||||
public $userId;
|
||||
|
||||
/**
|
||||
|
||||
@@ -30,14 +30,14 @@ use Illuminate\Queue\SerializesModels;
|
||||
|
||||
/**
|
||||
* Class RequestedVersionCheckStatus
|
||||
*
|
||||
* @codeCoverageIgnore
|
||||
*/
|
||||
class RequestedVersionCheckStatus extends Event
|
||||
{
|
||||
use SerializesModels;
|
||||
|
||||
/**
|
||||
* @var User
|
||||
*/
|
||||
/** @var User The user */
|
||||
public $user;
|
||||
|
||||
/**
|
||||
|
||||
@@ -28,16 +28,17 @@ use FireflyIII\Models\TransactionJournal;
|
||||
use Illuminate\Queue\SerializesModels;
|
||||
|
||||
/**
|
||||
* @codeCoverageIgnore
|
||||
* Class StoredTransactionJournal.
|
||||
*
|
||||
* @codeCoverageIgnore
|
||||
*/
|
||||
class StoredTransactionJournal extends Event
|
||||
{
|
||||
use SerializesModels;
|
||||
|
||||
/** @var TransactionJournal */
|
||||
/** @var TransactionJournal The journal that was stored. */
|
||||
public $journal;
|
||||
/** @var int */
|
||||
/** @var int The piggy bank ID. */
|
||||
public $piggyBankId;
|
||||
|
||||
/**
|
||||
|
||||
@@ -37,7 +37,7 @@ class UpdatedTransactionJournal extends Event
|
||||
{
|
||||
use SerializesModels;
|
||||
|
||||
/** @var TransactionJournal */
|
||||
/** @var TransactionJournal The journal. */
|
||||
public $journal;
|
||||
|
||||
/**
|
||||
|
||||
@@ -29,18 +29,20 @@ use Illuminate\Queue\SerializesModels;
|
||||
|
||||
/**
|
||||
* Class UserChangedEmail.
|
||||
*
|
||||
* @codeCoverageIgnore
|
||||
*/
|
||||
class UserChangedEmail extends Event
|
||||
{
|
||||
use SerializesModels;
|
||||
|
||||
/** @var string */
|
||||
/** @var string The user's IP address */
|
||||
public $ipAddress;
|
||||
/** @var string */
|
||||
/** @var string The user's new email address */
|
||||
public $newEmail;
|
||||
/** @var string */
|
||||
/** @var string The user's old email address */
|
||||
public $oldEmail;
|
||||
/** @var User */
|
||||
/** @var User The user itself */
|
||||
public $user;
|
||||
|
||||
/**
|
||||
|
||||
@@ -20,6 +20,8 @@
|
||||
* along with Firefly III. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/** @noinspection MultipleReturnStatementsInspection */
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace FireflyIII\Exceptions;
|
||||
@@ -29,46 +31,31 @@ use Exception;
|
||||
use FireflyIII\Jobs\MailError;
|
||||
use Illuminate\Auth\AuthenticationException;
|
||||
use Illuminate\Foundation\Exceptions\Handler as ExceptionHandler;
|
||||
use Illuminate\Validation\ValidationException;
|
||||
use Illuminate\Validation\ValidationException as LaravelValidationException;
|
||||
use League\OAuth2\Server\Exception\OAuthServerException;
|
||||
use Request;
|
||||
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
|
||||
|
||||
/**
|
||||
* Class Handler
|
||||
* @codeCoverageIgnore
|
||||
*/
|
||||
class Handler extends ExceptionHandler
|
||||
{
|
||||
/**
|
||||
* A list of the inputs that are never flashed for validation exceptions.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $dontFlash
|
||||
= [
|
||||
'password',
|
||||
'password_confirmation',
|
||||
];
|
||||
/**
|
||||
* A list of the exception types that are not reported.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $dontReport
|
||||
= [
|
||||
];
|
||||
|
||||
/**
|
||||
* Render an exception into an HTTP response.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @param \Exception $exception
|
||||
* @param Request $request
|
||||
* @param Exception $exception
|
||||
* @SuppressWarnings(PHPMD.CyclomaticComplexity)
|
||||
* @SuppressWarnings(PHPMD.NPathComplexity)
|
||||
* @SuppressWarnings(PHPMD.ExcessiveMethodLength)
|
||||
*
|
||||
* @return \Illuminate\Http\Response
|
||||
* @return mixed
|
||||
*/
|
||||
public function render($request, Exception $exception)
|
||||
{
|
||||
if ($exception instanceof ValidationException && $request->expectsJson()) {
|
||||
if ($exception instanceof LaravelValidationException && $request->expectsJson()) {
|
||||
// ignore it: controller will handle it.
|
||||
return parent::render($request, $exception);
|
||||
}
|
||||
@@ -130,18 +117,10 @@ class Handler extends ExceptionHandler
|
||||
{
|
||||
|
||||
$doMailError = env('SEND_ERROR_MESSAGE', true);
|
||||
if (
|
||||
// if the user wants us to mail:
|
||||
$doMailError === true
|
||||
&& (
|
||||
// and if is one of these error instances
|
||||
$exception instanceof FireflyException
|
||||
|| $exception instanceof ErrorException
|
||||
|| $exception instanceof OAuthServerException
|
||||
|
||||
)
|
||||
) {
|
||||
// then, send email
|
||||
// if the user wants us to mail:
|
||||
if (true === $doMailError
|
||||
// and if is one of these error instances
|
||||
&& ($exception instanceof FireflyException || $exception instanceof ErrorException || $exception instanceof OAuthServerException)) {
|
||||
$userData = [
|
||||
'id' => 0,
|
||||
'email' => 'unknown@example.com',
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* AttachmentCollector.php
|
||||
* Copyright (c) 2018 thegrumpydictator@gmail.com
|
||||
@@ -35,18 +34,21 @@ use Storage;
|
||||
|
||||
/**
|
||||
* Class AttachmentCollector.
|
||||
*
|
||||
* @deprecated
|
||||
* @codeCoverageIgnore
|
||||
*/
|
||||
class AttachmentCollector extends BasicCollector implements CollectorInterface
|
||||
{
|
||||
/** @var Carbon */
|
||||
/** @var Carbon The end date of the range. */
|
||||
private $end;
|
||||
/** @var \Illuminate\Contracts\Filesystem\Filesystem */
|
||||
/** @var \Illuminate\Contracts\Filesystem\Filesystem File system */
|
||||
private $exportDisk;
|
||||
/** @var AttachmentRepositoryInterface */
|
||||
/** @var AttachmentRepositoryInterface Attachment repository */
|
||||
private $repository;
|
||||
/** @var Carbon */
|
||||
/** @var Carbon Start date of range */
|
||||
private $start;
|
||||
/** @var \Illuminate\Contracts\Filesystem\Filesystem */
|
||||
/** @var \Illuminate\Contracts\Filesystem\Filesystem Disk with uploads on it */
|
||||
private $uploadDisk;
|
||||
|
||||
/**
|
||||
@@ -64,6 +66,8 @@ class AttachmentCollector extends BasicCollector implements CollectorInterface
|
||||
}
|
||||
|
||||
/**
|
||||
* Run the routine.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function run(): bool
|
||||
@@ -80,6 +84,8 @@ class AttachmentCollector extends BasicCollector implements CollectorInterface
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the start and end date.
|
||||
*
|
||||
* @param Carbon $start
|
||||
* @param Carbon $end
|
||||
*/
|
||||
@@ -89,7 +95,10 @@ class AttachmentCollector extends BasicCollector implements CollectorInterface
|
||||
$this->end = $end;
|
||||
}
|
||||
|
||||
/** @noinspection MultipleReturnStatementsInspection */
|
||||
/**
|
||||
* Export attachments.
|
||||
*
|
||||
* @param Attachment $attachment
|
||||
*
|
||||
* @return bool
|
||||
@@ -107,7 +116,7 @@ class AttachmentCollector extends BasicCollector implements CollectorInterface
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if ($decrypted === false) {
|
||||
if (false === $decrypted) {
|
||||
return false;
|
||||
}
|
||||
$exportFile = $this->exportFileName($attachment);
|
||||
@@ -130,6 +139,8 @@ class AttachmentCollector extends BasicCollector implements CollectorInterface
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the attachments.
|
||||
*
|
||||
* @return Collection
|
||||
*/
|
||||
private function getAttachments(): Collection
|
||||
|
||||
@@ -30,14 +30,17 @@ use Illuminate\Support\Collection;
|
||||
|
||||
/**
|
||||
* Class BasicCollector.
|
||||
*
|
||||
* @codeCoverageIgnore
|
||||
* @deprecated
|
||||
*/
|
||||
class BasicCollector
|
||||
{
|
||||
/** @var ExportJob */
|
||||
/** @var ExportJob The job to export. */
|
||||
protected $job;
|
||||
/** @var User */
|
||||
/** @var User The user */
|
||||
protected $user;
|
||||
/** @var Collection */
|
||||
/** @var Collection All the entries. */
|
||||
private $entries;
|
||||
|
||||
/**
|
||||
@@ -49,6 +52,8 @@ class BasicCollector
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all entries.
|
||||
*
|
||||
* @return Collection
|
||||
*/
|
||||
public function getEntries(): Collection
|
||||
@@ -57,26 +62,32 @@ class BasicCollector
|
||||
}
|
||||
|
||||
/**
|
||||
* Set entries.
|
||||
*
|
||||
* @param Collection $entries
|
||||
*/
|
||||
public function setEntries(Collection $entries)
|
||||
public function setEntries(Collection $entries): void
|
||||
{
|
||||
$this->entries = $entries;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set export job.
|
||||
*
|
||||
* @param ExportJob $job
|
||||
*/
|
||||
public function setJob(ExportJob $job)
|
||||
public function setJob(ExportJob $job): void
|
||||
{
|
||||
$this->job = $job;
|
||||
$this->user = $job->user;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set user.
|
||||
*
|
||||
* @param User $user
|
||||
*/
|
||||
public function setUser(User $user)
|
||||
public function setUser(User $user): void
|
||||
{
|
||||
$this->user = $user;
|
||||
}
|
||||
|
||||
@@ -29,25 +29,36 @@ use Illuminate\Support\Collection;
|
||||
|
||||
/**
|
||||
* Interface CollectorInterface.
|
||||
*
|
||||
* @codeCoverageIgnore
|
||||
* @deprecated
|
||||
*/
|
||||
interface CollectorInterface
|
||||
{
|
||||
/**
|
||||
* Get entries.
|
||||
*
|
||||
* @return Collection
|
||||
*/
|
||||
public function getEntries(): Collection;
|
||||
|
||||
/**
|
||||
* Run the collector.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function run(): bool;
|
||||
|
||||
/**
|
||||
* Set entries.
|
||||
*
|
||||
* @param Collection $entries
|
||||
*/
|
||||
public function setEntries(Collection $entries);
|
||||
|
||||
/**
|
||||
* Set export job.
|
||||
*
|
||||
* @param ExportJob $job
|
||||
*
|
||||
* @return mixed
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* UploadCollector.php
|
||||
* Copyright (c) 2018 thegrumpydictator@gmail.com
|
||||
@@ -32,6 +31,9 @@ use Storage;
|
||||
|
||||
/**
|
||||
* Class UploadCollector.
|
||||
*
|
||||
* @codeCoverageIgnore
|
||||
* @deprecated
|
||||
*/
|
||||
class UploadCollector extends BasicCollector implements CollectorInterface
|
||||
{
|
||||
@@ -84,7 +86,10 @@ class UploadCollector extends BasicCollector implements CollectorInterface
|
||||
return true;
|
||||
}
|
||||
|
||||
/** @noinspection MultipleReturnStatementsInspection */
|
||||
/**
|
||||
* Process new file uploads.
|
||||
*
|
||||
* @param string $key
|
||||
*
|
||||
* @return bool
|
||||
|
||||
@@ -43,140 +43,71 @@ use FireflyIII\Models\Transaction;
|
||||
*
|
||||
* @SuppressWarnings(PHPMD.LongVariable)
|
||||
* @SuppressWarnings(PHPMD.TooManyFields)
|
||||
*
|
||||
* @codeCoverageIgnore
|
||||
* @deprecated
|
||||
*/
|
||||
final class Entry
|
||||
{
|
||||
// @formatter:off
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
/** @var int ID of the journal */
|
||||
public $journal_id;
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
/** @var int ID of the transaction */
|
||||
public $transaction_id = 0;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
/** @var string The date. */
|
||||
public $date;
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
/** @var string The description */
|
||||
public $description;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
/** @var string The currency code. */
|
||||
public $currency_code;
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
/** @var string The amount. */
|
||||
public $amount;
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
/** @var string The foreign currency code */
|
||||
public $foreign_currency_code = '';
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
/** @var string Foreign amount */
|
||||
public $foreign_amount = '0';
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
/** @var string Transaction type */
|
||||
public $transaction_type;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
/** @var string Asset account ID */
|
||||
public $asset_account_id;
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
/** @var string Asset account name */
|
||||
public $asset_account_name;
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
/** @var string Asset account IBAN */
|
||||
public $asset_account_iban;
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
/** @var string Asset account BIC */
|
||||
public $asset_account_bic;
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
/** @var string Asset account number */
|
||||
public $asset_account_number;
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
/** @var string Asset account currency code */
|
||||
public $asset_currency_code;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
/** @var string Opposing account ID */
|
||||
public $opposing_account_id;
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
/** @var string Opposing account name */
|
||||
public $opposing_account_name;
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
/** @var string Opposing account IBAN */
|
||||
public $opposing_account_iban;
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
/** @var string Opposing account BIC */
|
||||
public $opposing_account_bic;
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
/** @var string Opposing account number */
|
||||
public $opposing_account_number;
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
/** @var string Opposing account code */
|
||||
public $opposing_currency_code;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
/** @var string Budget ID */
|
||||
public $budget_id;
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
/** @var string Budget name */
|
||||
public $budget_name;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
/** @var string Category ID */
|
||||
public $category_id;
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
/** @var string Category name */
|
||||
public $category_name;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
/** @var string Bill ID */
|
||||
public $bill_id;
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
/** @var string Bill name */
|
||||
public $bill_name;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
/** @var string Notes */
|
||||
public $notes;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
/** @var string Tags */
|
||||
public $tags;
|
||||
|
||||
|
||||
// @formatter:on
|
||||
|
||||
/**
|
||||
* Entry constructor.
|
||||
*/
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* ExpandedProcessor.php
|
||||
* Copyright (c) 2018 thegrumpydictator@gmail.com
|
||||
@@ -20,6 +19,8 @@
|
||||
* along with Firefly III. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/** @noinspection PhpDynamicAsStaticMethodCallInspection */
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace FireflyIII\Export;
|
||||
@@ -30,7 +31,8 @@ use FireflyIII\Exceptions\FireflyException;
|
||||
use FireflyIII\Export\Collector\AttachmentCollector;
|
||||
use FireflyIII\Export\Collector\UploadCollector;
|
||||
use FireflyIII\Export\Entry\Entry;
|
||||
use FireflyIII\Helpers\Collector\JournalCollectorInterface;
|
||||
use FireflyIII\Export\Exporter\ExporterInterface;
|
||||
use FireflyIII\Helpers\Collector\TransactionCollectorInterface;
|
||||
use FireflyIII\Helpers\Filter\InternalTransferFilter;
|
||||
use FireflyIII\Models\AccountMeta;
|
||||
use FireflyIII\Models\ExportJob;
|
||||
@@ -47,26 +49,29 @@ use ZipArchive;
|
||||
* Class ExpandedProcessor.
|
||||
*
|
||||
* @SuppressWarnings(PHPMD.CouplingBetweenObjects) // its doing a lot.
|
||||
*
|
||||
* @codeCoverageIgnore
|
||||
* @deprecated
|
||||
*/
|
||||
class ExpandedProcessor implements ProcessorInterface
|
||||
{
|
||||
/** @var Collection */
|
||||
/** @var Collection All accounts */
|
||||
public $accounts;
|
||||
/** @var string */
|
||||
/** @var string The export format */
|
||||
public $exportFormat;
|
||||
/** @var bool */
|
||||
/** @var bool Should include attachments */
|
||||
public $includeAttachments;
|
||||
/** @var bool */
|
||||
/** @var bool Should include old uploads */
|
||||
public $includeOldUploads;
|
||||
/** @var ExportJob */
|
||||
/** @var ExportJob The export job itself */
|
||||
public $job;
|
||||
/** @var array */
|
||||
/** @var array The settings */
|
||||
public $settings;
|
||||
/** @var Collection */
|
||||
/** @var Collection The entries to export. */
|
||||
private $exportEntries;
|
||||
/** @var Collection */
|
||||
/** @var Collection The files to export */
|
||||
private $files;
|
||||
/** @var Collection */
|
||||
/** @var Collection The journals. */
|
||||
private $journals;
|
||||
|
||||
/**
|
||||
@@ -80,6 +85,8 @@ class ExpandedProcessor implements ProcessorInterface
|
||||
}
|
||||
|
||||
/**
|
||||
* Collect all attachments
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function collectAttachments(): bool
|
||||
@@ -103,13 +110,13 @@ class ExpandedProcessor implements ProcessorInterface
|
||||
public function collectJournals(): bool
|
||||
{
|
||||
// use journal collector thing.
|
||||
/** @var JournalCollectorInterface $collector */
|
||||
$collector = app(JournalCollectorInterface::class);
|
||||
/** @var TransactionCollectorInterface $collector */
|
||||
$collector = app(TransactionCollectorInterface::class);
|
||||
$collector->setUser($this->job->user);
|
||||
$collector->setAccounts($this->accounts)->setRange($this->settings['startDate'], $this->settings['endDate'])
|
||||
->withOpposingAccount()->withBudgetInformation()->withCategoryInformation()
|
||||
->removeFilter(InternalTransferFilter::class);
|
||||
$transactions = $collector->getJournals();
|
||||
$transactions = $collector->getTransactions();
|
||||
// get some more meta data for each entry:
|
||||
$ids = $transactions->pluck('journal_id')->toArray();
|
||||
$assetIds = $transactions->pluck('account_id')->toArray();
|
||||
@@ -143,6 +150,8 @@ class ExpandedProcessor implements ProcessorInterface
|
||||
}
|
||||
|
||||
/**
|
||||
* Get old oploads.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function collectOldUploads(): bool
|
||||
@@ -158,6 +167,8 @@ class ExpandedProcessor implements ProcessorInterface
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert journals to export objects.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function convertJournals(): bool
|
||||
@@ -173,6 +184,8 @@ class ExpandedProcessor implements ProcessorInterface
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a ZIP file.
|
||||
*
|
||||
* @return bool
|
||||
*
|
||||
* @throws FireflyException
|
||||
@@ -204,12 +217,15 @@ class ExpandedProcessor implements ProcessorInterface
|
||||
}
|
||||
|
||||
/**
|
||||
* Export the journals.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function exportJournals(): bool
|
||||
{
|
||||
$exporterClass = config('firefly.export_formats.' . $this->exportFormat);
|
||||
$exporter = app($exporterClass);
|
||||
/** @var ExporterInterface $exporter */
|
||||
$exporter = app($exporterClass);
|
||||
$exporter->setJob($this->job);
|
||||
$exporter->setEntries($this->exportEntries);
|
||||
$exporter->run();
|
||||
@@ -219,6 +235,8 @@ class ExpandedProcessor implements ProcessorInterface
|
||||
}
|
||||
|
||||
/**
|
||||
* Get files.
|
||||
*
|
||||
* @return Collection
|
||||
*/
|
||||
public function getFiles(): Collection
|
||||
@@ -231,7 +249,7 @@ class ExpandedProcessor implements ProcessorInterface
|
||||
*
|
||||
* @param array $settings
|
||||
*/
|
||||
public function setSettings(array $settings)
|
||||
public function setSettings(array $settings): void
|
||||
{
|
||||
// save settings
|
||||
$this->settings = $settings;
|
||||
@@ -243,9 +261,9 @@ class ExpandedProcessor implements ProcessorInterface
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* Delete files.
|
||||
*/
|
||||
private function deleteFiles()
|
||||
private function deleteFiles(): void
|
||||
{
|
||||
$disk = Storage::disk('export');
|
||||
foreach ($this->getFiles() as $file) {
|
||||
@@ -254,6 +272,8 @@ class ExpandedProcessor implements ProcessorInterface
|
||||
}
|
||||
|
||||
/**
|
||||
* Get currencies.
|
||||
*
|
||||
* @param array $array
|
||||
*
|
||||
* @return array
|
||||
|
||||
@@ -29,12 +29,15 @@ use Illuminate\Support\Collection;
|
||||
|
||||
/**
|
||||
* Class BasicExporter.
|
||||
*
|
||||
* @codeCoverageIgnore
|
||||
* @deprecated
|
||||
*/
|
||||
class BasicExporter
|
||||
{
|
||||
/** @var ExportJob */
|
||||
/** @var ExportJob The export job */
|
||||
protected $job;
|
||||
/** @var Collection */
|
||||
/** @var Collection The entries */
|
||||
private $entries;
|
||||
|
||||
/**
|
||||
@@ -46,6 +49,8 @@ class BasicExporter
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all entries.
|
||||
*
|
||||
* @return Collection
|
||||
*/
|
||||
public function getEntries(): Collection
|
||||
@@ -54,17 +59,21 @@ class BasicExporter
|
||||
}
|
||||
|
||||
/**
|
||||
* Set all entries.
|
||||
*
|
||||
* @param Collection $entries
|
||||
*/
|
||||
public function setEntries(Collection $entries)
|
||||
public function setEntries(Collection $entries): void
|
||||
{
|
||||
$this->entries = $entries;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the job.
|
||||
*
|
||||
* @param ExportJob $job
|
||||
*/
|
||||
public function setJob(ExportJob $job)
|
||||
public function setJob(ExportJob $job): void
|
||||
{
|
||||
$this->job = $job;
|
||||
}
|
||||
|
||||
@@ -30,13 +30,18 @@ use Storage;
|
||||
|
||||
/**
|
||||
* Class CsvExporter.
|
||||
*
|
||||
* @codeCoverageIgnore
|
||||
* @deprecated
|
||||
*/
|
||||
class CsvExporter extends BasicExporter implements ExporterInterface
|
||||
{
|
||||
/** @var string */
|
||||
/** @var string Filename */
|
||||
private $fileName;
|
||||
|
||||
/**
|
||||
* Get file name.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getFileName(): string
|
||||
@@ -45,6 +50,8 @@ class CsvExporter extends BasicExporter implements ExporterInterface
|
||||
}
|
||||
|
||||
/**
|
||||
* Run collector.
|
||||
*
|
||||
* @return bool
|
||||
*
|
||||
*/
|
||||
@@ -83,6 +90,9 @@ class CsvExporter extends BasicExporter implements ExporterInterface
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Make a temp file.
|
||||
*/
|
||||
private function tempFile()
|
||||
{
|
||||
$this->fileName = $this->job->key . '-records.csv';
|
||||
|
||||
@@ -29,30 +29,43 @@ use Illuminate\Support\Collection;
|
||||
|
||||
/**
|
||||
* Interface ExporterInterface.
|
||||
*
|
||||
* @codeCoverageIgnore
|
||||
* @deprecated
|
||||
*/
|
||||
interface ExporterInterface
|
||||
{
|
||||
/**
|
||||
* Get entries.
|
||||
*
|
||||
* @return Collection
|
||||
*/
|
||||
public function getEntries(): Collection;
|
||||
|
||||
/**
|
||||
* Get file name.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getFileName(): string;
|
||||
|
||||
/**
|
||||
* Run exporter.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function run(): bool;
|
||||
|
||||
/**
|
||||
* Set entries.
|
||||
*
|
||||
* @param Collection $entries
|
||||
*/
|
||||
public function setEntries(Collection $entries);
|
||||
|
||||
/**
|
||||
* Set job.
|
||||
*
|
||||
* @param ExportJob $job
|
||||
*/
|
||||
public function setJob(ExportJob $job);
|
||||
|
||||
@@ -28,6 +28,9 @@ use Illuminate\Support\Collection;
|
||||
|
||||
/**
|
||||
* Interface ProcessorInterface.
|
||||
*
|
||||
* @codeCoverageIgnore
|
||||
* @deprecated
|
||||
*/
|
||||
interface ProcessorInterface
|
||||
{
|
||||
@@ -37,41 +40,57 @@ interface ProcessorInterface
|
||||
public function __construct();
|
||||
|
||||
/**
|
||||
* Collect all attachments.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function collectAttachments(): bool;
|
||||
|
||||
/**
|
||||
* Collect all journals.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function collectJournals(): bool;
|
||||
|
||||
/**
|
||||
* Collect old uploads.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function collectOldUploads(): bool;
|
||||
|
||||
/**
|
||||
* Convert all journals.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function convertJournals(): bool;
|
||||
|
||||
/**
|
||||
* Create a zip file.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function createZipFile(): bool;
|
||||
|
||||
/**
|
||||
* Export journals.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function exportJournals(): bool;
|
||||
|
||||
/**
|
||||
* Get all files.
|
||||
*
|
||||
* @return Collection
|
||||
*/
|
||||
public function getFiles(): Collection;
|
||||
|
||||
/**
|
||||
* Set the settings.
|
||||
*
|
||||
* @param array $settings
|
||||
*/
|
||||
public function setSettings(array $settings);
|
||||
|
||||
@@ -20,14 +20,19 @@
|
||||
* along with Firefly III. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/** @noinspection PhpDynamicAsStaticMethodCallInspection */
|
||||
/** @noinspection PhpUndefinedMethodInspection */
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace FireflyIII\Factory;
|
||||
|
||||
use FireflyIII\Exceptions\FireflyException;
|
||||
use FireflyIII\Models\Account;
|
||||
use FireflyIII\Models\AccountType;
|
||||
use FireflyIII\Services\Internal\Support\AccountServiceTrait;
|
||||
use FireflyIII\User;
|
||||
use Log;
|
||||
|
||||
/**
|
||||
* Factory to create or return accounts.
|
||||
@@ -44,56 +49,64 @@ class AccountFactory
|
||||
* @param array $data
|
||||
*
|
||||
* @return Account
|
||||
* @throws FireflyException
|
||||
* @SuppressWarnings(PHPMD.CyclomaticComplexity)
|
||||
* @SuppressWarnings(PHPMD.ExcessiveMethodLength)
|
||||
*/
|
||||
public function create(array $data): Account
|
||||
{
|
||||
$type = $this->getAccountType($data['account_type_id'], $data['accountType']);
|
||||
$type = $this->getAccountType($data['account_type_id'], $data['accountType']);
|
||||
|
||||
if (null === $type) {
|
||||
throw new FireflyException(
|
||||
sprintf('AccountFactory::create() was unable to find account type #%d ("%s").', $data['account_type_id'], $data['accountType'])
|
||||
);
|
||||
}
|
||||
|
||||
$data['iban'] = $this->filterIban($data['iban']);
|
||||
|
||||
|
||||
// account may exist already:
|
||||
$existingAccount = $this->find($data['name'], $type->type);
|
||||
if (null !== $existingAccount) {
|
||||
return $existingAccount;
|
||||
$return = $this->find($data['name'], $type->type);
|
||||
|
||||
|
||||
if (null === $return) {
|
||||
// create it:
|
||||
$databaseData
|
||||
= [
|
||||
'user_id' => $this->user->id,
|
||||
'account_type_id' => $type->id,
|
||||
'name' => $data['name'],
|
||||
'virtual_balance' => $data['virtualBalance'] ?? '0',
|
||||
'active' => true === $data['active'],
|
||||
'iban' => $data['iban'],
|
||||
];
|
||||
|
||||
// remove virtual balance when not an asset account or a liability
|
||||
$canHaveVirtual = [AccountType::ASSET, AccountType::DEBT, AccountType::LOAN, AccountType::MORTGAGE, AccountType::CREDITCARD];
|
||||
if (!\in_array($type->type, $canHaveVirtual, true)) {
|
||||
$databaseData['virtual_balance'] = '0';
|
||||
}
|
||||
|
||||
// fix virtual balance when it's empty
|
||||
if ('' === $databaseData['virtual_balance']) {
|
||||
$databaseData['virtual_balance'] = '0';
|
||||
}
|
||||
|
||||
$return = Account::create($databaseData);
|
||||
$this->updateMetaData($return, $data);
|
||||
|
||||
if (\in_array($type->type, $canHaveVirtual, true)) {
|
||||
if ($this->validIBData($data)) {
|
||||
$this->updateIB($return, $data);
|
||||
}
|
||||
if (!$this->validIBData($data)) {
|
||||
$this->deleteIB($return);
|
||||
}
|
||||
}
|
||||
$this->updateNote($return, $data['notes'] ?? '');
|
||||
}
|
||||
|
||||
|
||||
// create it:
|
||||
$databaseData
|
||||
= [
|
||||
'user_id' => $this->user->id,
|
||||
'account_type_id' => $type->id,
|
||||
'name' => $data['name'],
|
||||
'virtual_balance' => $data['virtualBalance'] ?? '0',
|
||||
'active' => true === $data['active'],
|
||||
'iban' => $data['iban'],
|
||||
];
|
||||
|
||||
// remove virtual balance when not an asset account:
|
||||
if ($type->type !== AccountType::ASSET) {
|
||||
$databaseData['virtual_balance'] = '0';
|
||||
}
|
||||
|
||||
// fix virtual balance when it's empty
|
||||
if ($databaseData['virtual_balance'] === '') {
|
||||
$databaseData['virtual_balance'] = '0';
|
||||
}
|
||||
|
||||
$newAccount = Account::create($databaseData);
|
||||
$this->updateMetaData($newAccount, $data);
|
||||
|
||||
if ($this->validIBData($data) && $type->type === AccountType::ASSET) {
|
||||
$this->updateIB($newAccount, $data);
|
||||
}
|
||||
if (!$this->validIBData($data) && $type->type === AccountType::ASSET) {
|
||||
$this->deleteIB($newAccount);
|
||||
}
|
||||
// update note:
|
||||
if (isset($data['notes'])) {
|
||||
$this->updateNote($newAccount, $data['notes']);
|
||||
}
|
||||
|
||||
return $newAccount;
|
||||
return $return;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -106,46 +119,53 @@ class AccountFactory
|
||||
{
|
||||
$type = AccountType::whereType($accountType)->first();
|
||||
$accounts = $this->user->accounts()->where('account_type_id', $type->id)->get(['accounts.*']);
|
||||
|
||||
$return = null;
|
||||
/** @var Account $object */
|
||||
foreach ($accounts as $object) {
|
||||
if ($object->name === $accountName) {
|
||||
return $object;
|
||||
$return = $object;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
return $return;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param string $accountName
|
||||
* @param string $accountType
|
||||
*
|
||||
* @return Account
|
||||
* @throws FireflyException
|
||||
*/
|
||||
public function findOrCreate(string $accountName, string $accountType): Account
|
||||
{
|
||||
$type = AccountType::whereType($accountType)->first();
|
||||
$accounts = $this->user->accounts()->where('account_type_id', $type->id)->get(['accounts.*']);
|
||||
|
||||
$return = null;
|
||||
/** @var Account $object */
|
||||
foreach ($accounts as $object) {
|
||||
if ($object->name === $accountName) {
|
||||
return $object;
|
||||
$return = $object;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (null === $return) {
|
||||
$return = $this->create(
|
||||
[
|
||||
'user_id' => $this->user->id,
|
||||
'name' => $accountName,
|
||||
'account_type_id' => $type->id,
|
||||
'accountType' => null,
|
||||
'virtualBalance' => '0',
|
||||
'iban' => null,
|
||||
'active' => true,
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
return $this->create(
|
||||
[
|
||||
'user_id' => $this->user->id,
|
||||
'name' => $accountName,
|
||||
'account_type_id' => $type->id,
|
||||
'accountType' => null,
|
||||
'virtualBalance' => '0',
|
||||
'iban' => null,
|
||||
'active' => true,
|
||||
]
|
||||
);
|
||||
return $return;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -161,18 +181,27 @@ class AccountFactory
|
||||
* @param null|string $accountType
|
||||
*
|
||||
* @return AccountType|null
|
||||
* @SuppressWarnings(PHPMD.CyclomaticComplexity)
|
||||
*/
|
||||
protected function getAccountType(?int $accountTypeId, ?string $accountType): ?AccountType
|
||||
{
|
||||
$accountTypeId = (int)$accountTypeId;
|
||||
$result = null;
|
||||
if ($accountTypeId > 0) {
|
||||
return AccountType::find($accountTypeId);
|
||||
$result = AccountType::find($accountTypeId);
|
||||
}
|
||||
$type = config('firefly.accountTypeByIdentifier.' . (string)$accountType);
|
||||
$result = AccountType::whereType($type)->first();
|
||||
if (null === $result && null !== $accountType) {
|
||||
// try as full name:
|
||||
$result = AccountType::whereType($accountType)->first();
|
||||
if (null === $result) {
|
||||
Log::debug(sprintf('No account type found by ID, continue search for "%s".', $accountType));
|
||||
/** @var array $types */
|
||||
$types = config('firefly.accountTypeByIdentifier.' . $accountType) ?? [];
|
||||
if (\count($types) > 0) {
|
||||
Log::debug(sprintf('%d accounts in list from config', \count($types)), $types);
|
||||
$result = AccountType::whereIn('type', $types)->first();
|
||||
}
|
||||
if (null === $result && null !== $accountType) {
|
||||
// try as full name:
|
||||
$result = AccountType::whereType($accountType)->first();
|
||||
}
|
||||
}
|
||||
|
||||
return $result;
|
||||
|
||||
@@ -24,13 +24,17 @@ declare(strict_types=1);
|
||||
|
||||
namespace FireflyIII\Factory;
|
||||
|
||||
use Exception;
|
||||
use FireflyIII\Models\Account;
|
||||
use FireflyIII\Models\AccountMeta;
|
||||
use Log;
|
||||
|
||||
/**
|
||||
* Class AccountMetaFactory
|
||||
*/
|
||||
class AccountMetaFactory
|
||||
{
|
||||
|
||||
/**
|
||||
* @param array $data
|
||||
*
|
||||
@@ -41,4 +45,46 @@ class AccountMetaFactory
|
||||
return AccountMeta::create($data);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create update or delete meta data.
|
||||
*
|
||||
* @param Account $account
|
||||
* @param string $field
|
||||
* @param string $value
|
||||
*
|
||||
* @return AccountMeta|null
|
||||
*/
|
||||
public function crud(Account $account, string $field, string $value): ?AccountMeta
|
||||
{
|
||||
/** @var AccountMeta $entry */
|
||||
$entry = $account->accountMeta()->where('name', $field)->first();
|
||||
|
||||
// must not be an empty string:
|
||||
if ('' !== $value) {
|
||||
|
||||
// if $data has field and $entry is null, create new one:
|
||||
if (null === $entry) {
|
||||
Log::debug(sprintf('Created meta-field "%s":"%s" for account #%d ("%s") ', $field, $value, $account->id, $account->name));
|
||||
return $this->create(['account_id' => $account->id, 'name' => $field, 'data' => $value]);
|
||||
}
|
||||
|
||||
// if $data has field and $entry is not null, update $entry:
|
||||
if (null !== $entry) {
|
||||
$entry->data = $value;
|
||||
$entry->save();
|
||||
Log::debug(sprintf('Updated meta-field "%s":"%s" for #%d ("%s") ', $field, $value, $account->id, $account->name));
|
||||
}
|
||||
}
|
||||
if ('' === $value && null !== $entry) {
|
||||
try {
|
||||
$entry->delete();
|
||||
} catch (Exception $e) { // @codeCoverageIgnore
|
||||
Log::debug(sprintf('Could not delete entry: %s', $e->getMessage())); // @codeCoverageIgnore
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
return $entry;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -76,4 +76,4 @@ class AttachmentFactory
|
||||
$this->user = $user;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -25,6 +25,7 @@ declare(strict_types=1);
|
||||
namespace FireflyIII\Factory;
|
||||
|
||||
use FireflyIII\Models\Bill;
|
||||
use FireflyIII\Models\TransactionCurrency;
|
||||
use FireflyIII\Services\Internal\Support\BillServiceTrait;
|
||||
use FireflyIII\User;
|
||||
use Illuminate\Support\Collection;
|
||||
@@ -46,6 +47,10 @@ class BillFactory
|
||||
*/
|
||||
public function create(array $data): ?Bill
|
||||
{
|
||||
/** @var TransactionCurrencyFactory $factory */
|
||||
$factory = app(TransactionCurrencyFactory::class);
|
||||
/** @var TransactionCurrency $currency */
|
||||
$currency = $factory->find((int)$data['currency_id'], (string)$data['currency_code']);
|
||||
/** @var Bill $bill */
|
||||
$bill = Bill::create(
|
||||
[
|
||||
@@ -53,7 +58,7 @@ class BillFactory
|
||||
'match' => 'MIGRATED_TO_RULES',
|
||||
'amount_min' => $data['amount_min'],
|
||||
'user_id' => $this->user->id,
|
||||
'transaction_currency_id' => $data['transaction_currency_id'],
|
||||
'transaction_currency_id' => $currency->id,
|
||||
'amount_max' => $data['amount_max'],
|
||||
'date' => $data['date'],
|
||||
'repeat_freq' => $data['repeat_freq'],
|
||||
@@ -81,25 +86,19 @@ class BillFactory
|
||||
{
|
||||
$billId = (int)$billId;
|
||||
$billName = (string)$billName;
|
||||
|
||||
$bill = null;
|
||||
// first find by ID:
|
||||
if ($billId > 0) {
|
||||
/** @var Bill $bill */
|
||||
$bill = $this->user->bills()->find($billId);
|
||||
if (null !== $bill) {
|
||||
return $bill;
|
||||
}
|
||||
}
|
||||
|
||||
// then find by name:
|
||||
if (\strlen($billName) > 0) {
|
||||
if (null === $bill && \strlen($billName) > 0) {
|
||||
$bill = $this->findByName($billName);
|
||||
if (null !== $bill) {
|
||||
return $bill;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
return $bill;
|
||||
|
||||
}
|
||||
|
||||
@@ -112,22 +111,24 @@ class BillFactory
|
||||
{
|
||||
/** @var Collection $collection */
|
||||
$collection = $this->user->bills()->get();
|
||||
$return = null;
|
||||
/** @var Bill $bill */
|
||||
foreach ($collection as $bill) {
|
||||
Log::debug(sprintf('"%s" vs. "%s"', $bill->name, $name));
|
||||
if ($bill->name === $name) {
|
||||
return $bill;
|
||||
$return = $bill;
|
||||
break;
|
||||
}
|
||||
}
|
||||
Log::debug(sprintf('Bill::Find by name returns NULL based on "%s"', $name));
|
||||
Log::debug(sprintf('Bill::find("%s") by name returns null? %s', $name, var_export($return, true)));
|
||||
|
||||
return null;
|
||||
return $return;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param User $user
|
||||
*/
|
||||
public function setUser(User $user)
|
||||
public function setUser(User $user): void
|
||||
{
|
||||
$this->user = $user;
|
||||
}
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* BudgetFactory.php
|
||||
* Copyright (c) 2018 thegrumpydictator@gmail.com
|
||||
@@ -19,7 +18,7 @@
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Firefly III. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/** @noinspection MultipleReturnStatementsInspection */
|
||||
declare(strict_types=1);
|
||||
|
||||
|
||||
@@ -30,7 +29,7 @@ use FireflyIII\User;
|
||||
use Illuminate\Support\Collection;
|
||||
|
||||
/**
|
||||
* Class BudgetFactory
|
||||
* Class BudgetFactory.
|
||||
*/
|
||||
class BudgetFactory
|
||||
{
|
||||
@@ -43,13 +42,14 @@ class BudgetFactory
|
||||
* @param null|string $budgetName
|
||||
*
|
||||
* @return Budget|null
|
||||
* @SuppressWarnings(PHPMD.CyclomaticComplexity)
|
||||
*/
|
||||
public function find(?int $budgetId, ?string $budgetName): ?Budget
|
||||
{
|
||||
$budgetId = (int)$budgetId;
|
||||
$budgetName = (string)$budgetName;
|
||||
|
||||
if (\strlen($budgetName) === 0 && $budgetId === 0) {
|
||||
if (0 === $budgetId && '' === $budgetName) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -62,7 +62,7 @@ class BudgetFactory
|
||||
}
|
||||
}
|
||||
|
||||
if (\strlen($budgetName) > 0) {
|
||||
if ('' !== $budgetName) {
|
||||
$budget = $this->findByName($budgetName);
|
||||
if (null !== $budget) {
|
||||
return $budget;
|
||||
@@ -94,7 +94,7 @@ class BudgetFactory
|
||||
/**
|
||||
* @param User $user
|
||||
*/
|
||||
public function setUser(User $user)
|
||||
public function setUser(User $user): void
|
||||
{
|
||||
$this->user = $user;
|
||||
}
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* CategoryFactory.php
|
||||
* Copyright (c) 2018 thegrumpydictator@gmail.com
|
||||
@@ -19,7 +18,7 @@
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Firefly III. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/** @noinspection MultipleReturnStatementsInspection */
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace FireflyIII\Factory;
|
||||
@@ -64,6 +63,7 @@ class CategoryFactory
|
||||
* @param null|string $categoryName
|
||||
*
|
||||
* @return Category|null
|
||||
* @SuppressWarnings(PHPMD.CyclomaticComplexity)
|
||||
*/
|
||||
public function findOrCreate(?int $categoryId, ?string $categoryName): ?Category
|
||||
{
|
||||
@@ -72,7 +72,7 @@ class CategoryFactory
|
||||
|
||||
Log::debug(sprintf('Going to find category with ID %d and name "%s"', $categoryId, $categoryName));
|
||||
|
||||
if ('' === $categoryName && $categoryId === 0) {
|
||||
if ('' === $categoryName && 0 === $categoryId) {
|
||||
return null;
|
||||
}
|
||||
// first by ID:
|
||||
@@ -104,7 +104,7 @@ class CategoryFactory
|
||||
/**
|
||||
* @param User $user
|
||||
*/
|
||||
public function setUser(User $user)
|
||||
public function setUser(User $user): void
|
||||
{
|
||||
$this->user = $user;
|
||||
}
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* PiggyBankEventFactory.php
|
||||
* Copyright (c) 2018 thegrumpydictator@gmail.com
|
||||
@@ -19,7 +18,7 @@
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Firefly III. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/** @noinspection MultipleReturnStatementsInspection */
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace FireflyIII\Factory;
|
||||
@@ -43,6 +42,7 @@ class PiggyBankEventFactory
|
||||
* @param PiggyBank|null $piggyBank
|
||||
*
|
||||
* @return PiggyBankEvent|null
|
||||
* @SuppressWarnings(PHPMD.CyclomaticComplexity)
|
||||
*/
|
||||
public function create(TransactionJournal $journal, ?PiggyBank $piggyBank): ?PiggyBankEvent
|
||||
{
|
||||
@@ -51,7 +51,6 @@ class PiggyBankEventFactory
|
||||
return null;
|
||||
}
|
||||
|
||||
// is a transfer?
|
||||
if (!(TransactionType::TRANSFER === $journal->transactionType->type)) {
|
||||
Log::info(sprintf('Will not connect %s #%d to a piggy bank.', $journal->transactionType->type, $journal->id));
|
||||
|
||||
@@ -62,7 +61,6 @@ class PiggyBankEventFactory
|
||||
$piggyRepos = app(PiggyBankRepositoryInterface::class);
|
||||
$piggyRepos->setUser($journal->user);
|
||||
|
||||
// repetition exists?
|
||||
$repetition = $piggyRepos->getRepetition($piggyBank);
|
||||
if (null === $repetition) {
|
||||
Log::error(sprintf('No piggy bank repetition on %s!', $journal->date->format('Y-m-d')));
|
||||
@@ -70,7 +68,6 @@ class PiggyBankEventFactory
|
||||
return null;
|
||||
}
|
||||
|
||||
// get the amount
|
||||
$amount = $piggyRepos->getExactAmount($piggyBank, $repetition, $journal);
|
||||
if (0 === bccomp($amount, '0')) {
|
||||
Log::debug('Amount is zero, will not create event.');
|
||||
@@ -78,10 +75,8 @@ class PiggyBankEventFactory
|
||||
return null;
|
||||
}
|
||||
|
||||
// update amount
|
||||
$piggyRepos->addAmountToRepetition($repetition, $amount);
|
||||
$event = $piggyRepos->createEventWithJournal($piggyBank, $amount, $journal);
|
||||
|
||||
Log::debug(sprintf('Created piggy bank event #%d', $event->id));
|
||||
|
||||
return $event;
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* PiggyBankFactory.php
|
||||
* Copyright (c) 2018 thegrumpydictator@gmail.com
|
||||
@@ -19,7 +18,7 @@
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Firefly III. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/** @noinspection MultipleReturnStatementsInspection */
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace FireflyIII\Factory;
|
||||
@@ -41,12 +40,13 @@ class PiggyBankFactory
|
||||
* @param null|string $piggyBankName
|
||||
*
|
||||
* @return PiggyBank|null
|
||||
* @SuppressWarnings(PHPMD.CyclomaticComplexity)
|
||||
*/
|
||||
public function find(?int $piggyBankId, ?string $piggyBankName): ?PiggyBank
|
||||
{
|
||||
$piggyBankId = (int)$piggyBankId;
|
||||
$piggyBankName = (string)$piggyBankName;
|
||||
if (\strlen($piggyBankName) === 0 && $piggyBankId === 0) {
|
||||
if ('' === $piggyBankName && 0 === $piggyBankId) {
|
||||
return null;
|
||||
}
|
||||
// first find by ID:
|
||||
@@ -92,7 +92,7 @@ class PiggyBankFactory
|
||||
/**
|
||||
* @param User $user
|
||||
*/
|
||||
public function setUser(User $user)
|
||||
public function setUser(User $user): void
|
||||
{
|
||||
$this->user = $user;
|
||||
|
||||
|
||||
@@ -18,12 +18,14 @@
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Firefly III. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
/** @noinspection MultipleReturnStatementsInspection */
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace FireflyIII\Factory;
|
||||
|
||||
|
||||
use Carbon\Carbon;
|
||||
use FireflyIII\Exceptions\FireflyException;
|
||||
use FireflyIII\Models\Recurrence;
|
||||
use FireflyIII\Services\Internal\Support\RecurringTransactionTrait;
|
||||
@@ -56,6 +58,9 @@ class RecurrenceFactory
|
||||
|
||||
return null;
|
||||
}
|
||||
/** @var Carbon $firstDate */
|
||||
$firstDate = $data['recurrence']['first_date'];
|
||||
|
||||
$repetitions = (int)$data['recurrence']['repetitions'];
|
||||
$recurrence = new Recurrence(
|
||||
[
|
||||
@@ -63,7 +68,7 @@ class RecurrenceFactory
|
||||
'transaction_type_id' => $type->id,
|
||||
'title' => $data['recurrence']['title'],
|
||||
'description' => $data['recurrence']['description'],
|
||||
'first_date' => $data['recurrence']['first_date']->format('Y-m-d'),
|
||||
'first_date' => $firstDate->format('Y-m-d'),
|
||||
'repeat_until' => $repetitions > 0 ? null : $data['recurrence']['repeat_until'],
|
||||
'latest_date' => null,
|
||||
'repetitions' => $data['recurrence']['repetitions'],
|
||||
@@ -88,4 +93,4 @@ class RecurrenceFactory
|
||||
$this->user = $user;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* TagFactory.php
|
||||
* Copyright (c) 2018 thegrumpydictator@gmail.com
|
||||
@@ -19,6 +18,7 @@
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Firefly III. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
/** @noinspection MultipleReturnStatementsInspection */
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user