mirror of
https://github.com/firefly-iii/firefly-iii.git
synced 2025-08-22 13:19:29 +00:00
Compare commits
320 Commits
Author | SHA1 | Date | |
---|---|---|---|
|
88c145ac3e | ||
|
4aba842624 | ||
|
936c2b8888 | ||
|
c3e971c419 | ||
|
19fee6a8fb | ||
|
477eebdbe7 | ||
|
093bff750c | ||
|
92e679a9ea | ||
|
43232ae45c | ||
|
1fb13d8697 | ||
|
9ac28b93ca | ||
|
067c01ca06 | ||
|
82040c2a5d | ||
|
62502c746c | ||
|
6ab79a87fe | ||
|
04ee3b4dc1 | ||
|
9c9af79ad5 | ||
|
dd794e409f | ||
|
67d29b8416 | ||
|
5ee80dd046 | ||
|
f62e93b487 | ||
|
a7cc70b975 | ||
|
60f0d8074a | ||
|
ed1fdf9382 | ||
|
9ea3c4224e | ||
|
71325de44e | ||
|
cdb041e647 | ||
|
b9d750bf59 | ||
|
461249737e | ||
|
1aeaa8b77d | ||
|
a59d7ccdc2 | ||
|
2c1ca428db | ||
|
224970f3bd | ||
|
742d934ddb | ||
|
1699513023 | ||
|
488a8a7e86 | ||
|
dd571d6221 | ||
|
4cc5128b4c | ||
|
2636a6557a | ||
|
0bf97ccf22 | ||
|
592fc71b4e | ||
|
0e7712d3b8 | ||
|
80f21d2a4f | ||
|
5513ec068e | ||
|
14a46a6197 | ||
|
b93ee5efd8 | ||
|
cdd4dc6065 | ||
|
0d8b2ae799 | ||
|
77dc79b638 | ||
|
f48723db40 | ||
|
ebf91078c5 | ||
|
90d0d85dd6 | ||
|
0c5b4f7f64 | ||
|
9c4bb08ed1 | ||
|
1d3bbde4b0 | ||
|
b6faee033d | ||
|
05e0f88d11 | ||
|
ae9a151140 | ||
|
da633e3c62 | ||
|
8cb384d3cf | ||
|
de2a34c3ec | ||
|
b7c65446a8 | ||
|
bc648b187c | ||
|
4de0828b5d | ||
|
b2364d26ec | ||
|
83d94cb792 | ||
|
66cc3f48bc | ||
|
63297c43b7 | ||
|
5b0637558f | ||
|
e9a8e104be | ||
|
0f524e7800 | ||
|
969e0bccc9 | ||
|
ba3e026927 | ||
|
0c6868d477 | ||
|
7f70cf47ec | ||
|
fa4492287d | ||
|
60809c688e | ||
|
2404f5299c | ||
|
21a394eaf5 | ||
|
419d7846c9 | ||
|
0827accc39 | ||
|
2e53f7d0b7 | ||
|
bdfcf8ec95 | ||
|
6a20170e00 | ||
|
0c974f1ff7 | ||
|
9c098d45c5 | ||
|
cfdf9aa8dc | ||
|
2ea74542e6 | ||
|
7fcaa2b5fb | ||
|
e9e905e495 | ||
|
f67ff98d78 | ||
|
e3c4dde4ff | ||
|
9787561000 | ||
|
cd041b4c75 | ||
|
60ee70c926 | ||
|
00de78b6f1 | ||
|
33a841b831 | ||
|
df66dcf102 | ||
|
086a7a0b1e | ||
|
ec0ba3d212 | ||
|
b0ab06b7eb | ||
|
965acd6d45 | ||
|
4d156870ef | ||
|
499720df46 | ||
|
610bc108e7 | ||
|
53f1b0218c | ||
|
0a7a099796 | ||
|
ed90ebc896 | ||
|
87fe518d45 | ||
|
5cb0891a27 | ||
|
b4bd66bd58 | ||
|
64d95fe845 | ||
|
a2d6d7a92c | ||
|
1d8a784586 | ||
|
3c8bfae8ff | ||
|
f65eccfe4c | ||
|
7ce6dc9f16 | ||
|
4a73caf4c3 | ||
|
1b9d8dd3c3 | ||
|
b11bfb0aae | ||
|
024e16bf4b | ||
|
daf753d76e | ||
|
4c90f66578 | ||
|
db94f18d46 | ||
|
a9bd0f551d | ||
|
e1ba2d9ad9 | ||
|
939c636a74 | ||
|
2b829cb645 | ||
|
4bbc898639 | ||
|
27d07d5807 | ||
|
f010ffefc1 | ||
|
fc0fee161e | ||
|
72c99d3834 | ||
|
a2984f299b | ||
|
3925077223 | ||
|
deb51bd8de | ||
|
03f39f53d8 | ||
|
e72314778c | ||
|
ced3e9387a | ||
|
02c906afe6 | ||
|
7a2d4c9bd2 | ||
|
dffddfda18 | ||
|
9bb62c865a | ||
|
a97ebf2b97 | ||
|
9a62a6c514 | ||
|
04dc162270 | ||
|
75d5a50328 | ||
|
eadb7d5dcb | ||
|
8dc07f1148 | ||
|
217ce85a9b | ||
|
ef88b25dbd | ||
|
4c2e2a3a5a | ||
|
1e8e1c6e51 | ||
|
a92944786c | ||
|
8ce760a0bf | ||
|
8d8e047d2c | ||
|
06a923db94 | ||
|
551408b801 | ||
|
e1915e365a | ||
|
e8c4eec536 | ||
|
e3f4e75561 | ||
|
fd640f9698 | ||
|
ffd8aef35f | ||
|
46412bdc66 | ||
|
d73c3476c8 | ||
|
ff737ae05e | ||
|
171ec0c630 | ||
|
b4a6c6fcbe | ||
|
4886084296 | ||
|
1a3dfbdef6 | ||
|
0c087f33c2 | ||
|
5f9f621fa6 | ||
|
cd3de7b545 | ||
|
8aeb513d54 | ||
|
bfc5c5d154 | ||
|
7c9f7f04b7 | ||
|
3352c2cf3c | ||
|
e61a433999 | ||
|
3517452ea1 | ||
|
8a1190b9ee | ||
|
fc78c9a1d6 | ||
|
8d55f7f2e5 | ||
|
8162b22d43 | ||
|
8504d55f17 | ||
|
75ae1bbde1 | ||
|
a20668e91b | ||
|
eb559bbb03 | ||
|
2eae96a895 | ||
|
4bbf35bca4 | ||
|
f1b5e45488 | ||
|
57ed1581ec | ||
|
c668381ab0 | ||
|
44f99991fc | ||
|
696c76102b | ||
|
fe4e00dc5c | ||
|
1a1b0ee27d | ||
|
298c4ec654 | ||
|
c6e3fa2cc6 | ||
|
61484dcfee | ||
|
99009cff88 | ||
|
673f68b07c | ||
|
d1232192ce | ||
|
b2084a94e5 | ||
|
ddcb246955 | ||
|
8796168580 | ||
|
dde7bcfc4c | ||
|
a6503fda39 | ||
|
455e311661 | ||
|
a4a919d7b7 | ||
|
a90ce3c944 | ||
|
a6d179b883 | ||
|
1b29e5e628 | ||
|
e8fd496bca | ||
|
3d61e27a47 | ||
|
f9a55ce3d8 | ||
|
c432757942 | ||
|
da740ccbef | ||
|
f1173263b6 | ||
|
68da1a7039 | ||
|
64414edf58 | ||
|
6b136d2c8c | ||
|
752a877b91 | ||
|
d11c36e476 | ||
|
b13232f06b | ||
|
cf6ed5af32 | ||
|
be531d777e | ||
|
190508fa54 | ||
|
2c2dddc071 | ||
|
c60858de5c | ||
|
6ab332e4fb | ||
|
9df43cc710 | ||
|
79d1b15d86 | ||
|
923debb299 | ||
|
f5fef8c036 | ||
|
982134c077 | ||
|
07aeb6cd20 | ||
|
30cca355ba | ||
|
d17cc15037 | ||
|
efade857bb | ||
|
15ac6a1195 | ||
|
a45a050e7d | ||
|
e435ff8b1c | ||
|
788dae1477 | ||
|
2bb4cc7954 | ||
|
ecead8a27b | ||
|
4a2681df14 | ||
|
5761d82635 | ||
|
36fce9db4e | ||
|
1227574bc1 | ||
|
47c2a66e1d | ||
|
c59e52bbbf | ||
|
81961fd632 | ||
|
b557805eeb | ||
|
e58da3c41d | ||
|
f43b539470 | ||
|
ab3dbf9218 | ||
|
d943a5ae9b | ||
|
449058dad7 | ||
|
b9cf8b3ef2 | ||
|
27037c2fbb | ||
|
10646099a0 | ||
|
43ad63fac6 | ||
|
221c59437c | ||
|
1a94ec5bbe | ||
|
f57c554c56 | ||
|
334aec58a4 | ||
|
7035da4d75 | ||
|
29a40ce8dd | ||
|
c6c98c4df5 | ||
|
277d7e6650 | ||
|
130c539006 | ||
|
2bdb2e12f0 | ||
|
25779206a1 | ||
|
92f72a5ad7 | ||
|
4e041248ac | ||
|
8cc5aa8aba | ||
|
4ba712b24e | ||
|
7af9169763 | ||
|
775504acb6 | ||
|
7840e37e1a | ||
|
720fff4595 | ||
|
551c1f4cda | ||
|
7f0db0de04 | ||
|
6ac3cc384b | ||
|
563879c218 | ||
|
dbb7ed3d5d | ||
|
4e3c2ba72c | ||
|
8e911491f6 | ||
|
03c5f3cc2d | ||
|
484565d600 | ||
|
163a979227 | ||
|
ed105fee1d | ||
|
3b82cfa486 | ||
|
834e52eb2e | ||
|
7eb938fe23 | ||
|
8db7a4c47d | ||
|
b055a5d6af | ||
|
ad0a1b9a24 | ||
|
05d190659a | ||
|
9c6eaffba6 | ||
|
3ee5e9aa04 | ||
|
93a544fe53 | ||
|
3bc98bee20 | ||
|
f6302bc29b | ||
|
43aa1704a9 | ||
|
14fe82e361 | ||
|
33317c15a2 | ||
|
ff1b56c5ef | ||
|
25e2063d70 | ||
|
1d36c74934 | ||
|
aebe7908f0 | ||
|
3e2b881296 | ||
|
c670a6991d | ||
|
f76a7d59e0 | ||
|
3d8bf3ec9b | ||
|
55e4479454 | ||
|
436fe9fea4 | ||
|
63a7a4b03b | ||
|
0cab974048 | ||
|
5fdcf37d06 |
@@ -301,7 +301,6 @@ PUSHER_ID=
|
||||
DEMO_USERNAME=
|
||||
DEMO_PASSWORD=
|
||||
USE_ENCRYPTION=false
|
||||
IS_HEROKU=false
|
||||
FIREFLY_III_LAYOUT=v1
|
||||
|
||||
#
|
||||
|
1
.ci/php-cs-fixer/.gitignore
vendored
1
.ci/php-cs-fixer/.gitignore
vendored
@@ -1 +1,2 @@
|
||||
vendor
|
||||
.php-cs-fixer.cache
|
||||
|
3883
.ci/php-cs-fixer/composer.lock
generated
3883
.ci/php-cs-fixer/composer.lock
generated
File diff suppressed because it is too large
Load Diff
24
.ci/phpmd/composer.lock
generated
24
.ci/phpmd/composer.lock
generated
@@ -470,16 +470,16 @@
|
||||
},
|
||||
{
|
||||
"name": "symfony/dependency-injection",
|
||||
"version": "v6.3.0",
|
||||
"version": "v6.3.1",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/dependency-injection.git",
|
||||
"reference": "ebf5f9c5bb5c21d75ab74995ce5e26c3fbbda44d"
|
||||
"reference": "7abf242af21f196b65f20ab00ff251fdf3889b8d"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/dependency-injection/zipball/ebf5f9c5bb5c21d75ab74995ce5e26c3fbbda44d",
|
||||
"reference": "ebf5f9c5bb5c21d75ab74995ce5e26c3fbbda44d",
|
||||
"url": "https://api.github.com/repos/symfony/dependency-injection/zipball/7abf242af21f196b65f20ab00ff251fdf3889b8d",
|
||||
"reference": "7abf242af21f196b65f20ab00ff251fdf3889b8d",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -531,7 +531,7 @@
|
||||
"description": "Allows you to standardize and centralize the way objects are constructed in your application",
|
||||
"homepage": "https://symfony.com",
|
||||
"support": {
|
||||
"source": "https://github.com/symfony/dependency-injection/tree/v6.3.0"
|
||||
"source": "https://github.com/symfony/dependency-injection/tree/v6.3.1"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
@@ -547,7 +547,7 @@
|
||||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2023-05-30T17:12:32+00:00"
|
||||
"time": "2023-06-24T11:51:27+00:00"
|
||||
},
|
||||
{
|
||||
"name": "symfony/deprecation-contracts",
|
||||
@@ -618,16 +618,16 @@
|
||||
},
|
||||
{
|
||||
"name": "symfony/filesystem",
|
||||
"version": "v6.3.0",
|
||||
"version": "v6.3.1",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/filesystem.git",
|
||||
"reference": "97b698e1d77d356304def77a8d0cd73090b359ea"
|
||||
"reference": "edd36776956f2a6fcf577edb5b05eb0e3bdc52ae"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/filesystem/zipball/97b698e1d77d356304def77a8d0cd73090b359ea",
|
||||
"reference": "97b698e1d77d356304def77a8d0cd73090b359ea",
|
||||
"url": "https://api.github.com/repos/symfony/filesystem/zipball/edd36776956f2a6fcf577edb5b05eb0e3bdc52ae",
|
||||
"reference": "edd36776956f2a6fcf577edb5b05eb0e3bdc52ae",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -661,7 +661,7 @@
|
||||
"description": "Provides basic utilities for the filesystem",
|
||||
"homepage": "https://symfony.com",
|
||||
"support": {
|
||||
"source": "https://github.com/symfony/filesystem/tree/v6.3.0"
|
||||
"source": "https://github.com/symfony/filesystem/tree/v6.3.1"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
@@ -677,7 +677,7 @@
|
||||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2023-05-30T17:12:32+00:00"
|
||||
"time": "2023-06-01T08:30:39+00:00"
|
||||
},
|
||||
{
|
||||
"name": "symfony/polyfill-ctype",
|
||||
|
@@ -1,13 +1,33 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ruleset name="pcsg-generated-ruleset"
|
||||
xmlns="http://pmd.sf.net/ruleset/1.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
<!--
|
||||
~ phpmd.xml
|
||||
~ Copyright (c) 2023 james@firefly-iii.org
|
||||
~
|
||||
~ This file is part of Firefly III (https://github.com/firefly-iii).
|
||||
~
|
||||
~ This program is free software: you can redistribute it and/or modify
|
||||
~ it under the terms of the GNU Affero General Public License as
|
||||
~ published by the Free Software Foundation, either version 3 of the
|
||||
~ License, or (at your option) any later version.
|
||||
~
|
||||
~ This program is distributed in the hope that it will be useful,
|
||||
~ but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
~ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
~ GNU Affero General Public License for more details.
|
||||
~
|
||||
~ You should have received a copy of the GNU Affero General Public License
|
||||
~ along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
-->
|
||||
|
||||
<ruleset name="pcsg-generated-ruleset"
|
||||
xmlns="http://pmd.sf.net/ruleset/1.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://pmd.sf.net/ruleset/1.0.0 http://pmd.sf.net/ruleset_xml_schema.xsd"
|
||||
xsi:noNamespaceSchemaLocation="http://pmd.sf.net/ruleset_xml_schema.xsd">
|
||||
<description>Bla bla</description>
|
||||
|
||||
<!--
|
||||
Commando vanuit firefly directory:
|
||||
<!--
|
||||
Commando vanuit firefly directory:
|
||||
phpmd database,app,tests html /gdrive-all/development/phpmd/phpmd.xml > public/report.html
|
||||
-->
|
||||
|
||||
@@ -15,7 +35,7 @@ phpmd database,app,tests html /gdrive-all/development/phpmd/phpmd.xml > public/r
|
||||
<rule ref="rulesets/controversial.xml">
|
||||
<exclude name="CamelCasePropertyName" />
|
||||
</rule>
|
||||
|
||||
|
||||
<!-- clean code -->
|
||||
<rule ref="rulesets/codesize.xml" />
|
||||
<rule ref="rulesets/design.xml" />
|
||||
@@ -49,4 +69,4 @@ phpmd database,app,tests html /gdrive-all/development/phpmd/phpmd.xml > public/r
|
||||
|
||||
<!-- no this one -->
|
||||
<!--<rule ref="rulesets/cleancode.xml/StaticAccess" />-->
|
||||
</ruleset>
|
||||
</ruleset>
|
||||
|
@@ -1,321 +0,0 @@
|
||||
# You can leave this on "local". If you change it to production most console commands will ask for extra confirmation.
|
||||
# Never set it to "testing".
|
||||
APP_ENV=heroku
|
||||
|
||||
# Set to true if you want to see debug information in error screens.
|
||||
APP_DEBUG=false
|
||||
|
||||
# This should be your email address.
|
||||
# If you use Docker or similar, you can set this variable from a file by using SITE_OWNER_FILE
|
||||
SITE_OWNER=heroku@example.com
|
||||
|
||||
# The encryption key for your sessions. Keep this very secure.
|
||||
# If you generate a new one all existing attachments must be considered LOST.
|
||||
# Change it to a string of exactly 32 chars or use something like `php artisan key:generate` to generate it.
|
||||
# If you use Docker or similar, you can set this variable from a file by using APP_KEY_FILE
|
||||
APP_KEY=7ahyYVPVsmxjdhsweWCauGeJfwc92NP2
|
||||
|
||||
#
|
||||
# Firefly III will launch using this language (for new users and unauthenticated visitors)
|
||||
# For a list of available languages: https://github.com/firefly-iii/firefly-iii/tree/main/resources/lang
|
||||
#
|
||||
# If text is still in English, remember that not everything may have been translated.
|
||||
DEFAULT_LANGUAGE=en_US
|
||||
|
||||
# The locale defines how numbers are formatted.
|
||||
# by default this value is the same as whatever the language is.
|
||||
DEFAULT_LOCALE=equal
|
||||
|
||||
# Change this value to your preferred time zone.
|
||||
# Example: Europe/Amsterdam
|
||||
# For a list of supported time zones, see https://en.wikipedia.org/wiki/List_of_tz_database_time_zones
|
||||
TZ=UTC
|
||||
|
||||
# TRUSTED_PROXIES is a useful variable when using Docker and/or a reverse proxy.
|
||||
# Set it to ** and reverse proxies work just fine.
|
||||
TRUSTED_PROXIES=**
|
||||
|
||||
# The log channel defines where your log entries go to.
|
||||
# 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.
|
||||
# A rotating log option is 'daily', creates 5 files that (surprise) rotate.
|
||||
# Default setting 'stack' will log to 'daily' and to 'stdout' at the same time.
|
||||
|
||||
# - Docker + versions <= 4.8.1.8 and before: use "stdout"
|
||||
# - Docker + versions > 4.8.1.8 : use "docker_out"
|
||||
# - Docker + versions >= 5.1.1 : use "stack"
|
||||
# - For everything else (als not Docker) : use 'stack'
|
||||
|
||||
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=notice
|
||||
|
||||
# Database credentials. Make sure the database exists. I recommend a dedicated user for Firefly III
|
||||
# For other database types, please see the FAQ: https://docs.firefly-iii.org/support/faq
|
||||
# If you use Docker or similar, you can set these variables from a file by appending them with _FILE
|
||||
# Use "pgsql" for PostgreSQL
|
||||
# Use "mysql" for MySQL and MariaDB.
|
||||
# Use "sqlite" for SQLite.
|
||||
DB_CONNECTION=pgsql
|
||||
|
||||
|
||||
# MySQL supports SSL. You can configure it here.
|
||||
# If you use Docker or similar, you can set these variables from a file by appending them with _FILE
|
||||
MYSQL_USE_SSL=false
|
||||
MYSQL_SSL_VERIFY_SERVER_CERT=true
|
||||
# You need to set at least of these options
|
||||
MYSQL_SSL_CAPATH=/etc/ssl/certs/
|
||||
MYSQL_SSL_CA=
|
||||
MYSQL_SSL_CERT=
|
||||
MYSQL_SSL_KEY=
|
||||
MYSQL_SSL_CIPHER=
|
||||
|
||||
# PostgreSQL supports SSL. You can configure it here.
|
||||
# If you use Docker or similar, you can set these variables from a file by appending them with _FILE
|
||||
PGSQL_SSL_MODE=prefer
|
||||
PGSQL_SSL_ROOT_CERT=null
|
||||
PGSQL_SSL_CERT=null
|
||||
PGSQL_SSL_KEY=null
|
||||
PGSQL_SSL_CRL_FILE=null
|
||||
|
||||
# If you're looking for performance improvements, you could install memcached.
|
||||
CACHE_DRIVER=file
|
||||
SESSION_DRIVER=file
|
||||
|
||||
# If you set either of these to 'redis', you might want to update these settings too
|
||||
# If you use Docker or similar, you can set REDIS_HOST_FILE, REDIS_PASSWORD_FILE or
|
||||
# REDIS_PORT_FILE to set the value from a file instead of from an environment variable
|
||||
|
||||
# can be tcp, unix or http
|
||||
REDIS_SCHEME=tcp
|
||||
|
||||
# use only when using 'unix' for REDIS_SCHEME. Leave empty otherwise.
|
||||
REDIS_PATH=
|
||||
|
||||
# use only when using 'tcp' or 'http' for REDIS_SCHEME. Leave empty otherwise.
|
||||
REDIS_HOST=127.0.0.1
|
||||
REDIS_PORT=6379
|
||||
|
||||
REDIS_PASSWORD=null
|
||||
# always use quotes and make sure redis db "0" and "1" exists. Otherwise change accordingly.
|
||||
REDIS_DB="0"
|
||||
REDIS_CACHE_DB="1"
|
||||
|
||||
# Cookie settings. Should not be necessary to change these.
|
||||
# If you use Docker or similar, you can set COOKIE_DOMAIN_FILE to set
|
||||
# the value from a file instead of from an environment variable
|
||||
COOKIE_PATH="/"
|
||||
COOKIE_DOMAIN=
|
||||
COOKIE_SECURE=false
|
||||
|
||||
# If you want Firefly III to mail you, update these settings
|
||||
# For instructions, see: https://docs.firefly-iii.org/advanced-installation/email
|
||||
# If you use Docker or similar, you can set these variables from a file by appending them with _FILE
|
||||
MAIL_MAILER=log
|
||||
MAIL_HOST=null
|
||||
MAIL_PORT=2525
|
||||
MAIL_FROM=changeme@example.com
|
||||
MAIL_USERNAME=null
|
||||
MAIL_PASSWORD=null
|
||||
MAIL_ENCRYPTION=null
|
||||
|
||||
# Other mail drivers:
|
||||
# If you use Docker or similar, you can set these variables from a file by appending them with _FILE
|
||||
MAILGUN_DOMAIN=
|
||||
MAILGUN_SECRET=
|
||||
|
||||
|
||||
# If you are on EU region in mailgun, use api.eu.mailgun.net, otherwise use api.mailgun.net
|
||||
# If you use Docker or similar, you can set this variable from a file by appending it with _FILE
|
||||
MAILGUN_ENDPOINT=api.mailgun.net
|
||||
|
||||
# If you use Docker or similar, you can set these variables from a file by appending them with _FILE
|
||||
MANDRILL_SECRET=
|
||||
SPARKPOST_SECRET=
|
||||
|
||||
|
||||
# Firefly III can send you the following messages
|
||||
SEND_REGISTRATION_MAIL=true
|
||||
SEND_ERROR_MESSAGE=true
|
||||
|
||||
# These messages contain (sensitive) transaction information:
|
||||
SEND_REPORT_JOURNALS=true
|
||||
|
||||
# Set a Mapbox API key here (see mapbox.com) so there might be a map available at various places.
|
||||
# If you use Docker or similar, you can set this variable from a file by appending it with _FILE
|
||||
MAPBOX_API_KEY=
|
||||
|
||||
# The map will default to this location:
|
||||
MAP_DEFAULT_LAT=51.983333
|
||||
MAP_DEFAULT_LONG=5.916667
|
||||
MAP_DEFAULT_ZOOM=6
|
||||
|
||||
# Firefly III currently supports two provider for live Currency Exchange Rates:
|
||||
# "fixer", and "ratesapi".
|
||||
# RatesApi.IO (see https://ratesapi.io) is a FREE and OPEN SOURCE live currency exchange rates,
|
||||
# built compatible with Fixer.IO, based on data published by European Central Bank, and doesn't require API key.
|
||||
CER_PROVIDER=ratesapi
|
||||
|
||||
# If you have select "fixer" as default currency exchange rates,
|
||||
# set a Fixer IO API key here (see https://fixer.io) to enable live currency exchange rates.
|
||||
# Please note that this WILL ONLY WORK FOR PAID fixer.io accounts because they severely limited
|
||||
# the free API up to the point where you might as well offer nothing.
|
||||
# If you use Docker or similar, you can set this variable from a file by appending it with _FILE
|
||||
FIXER_API_KEY=
|
||||
|
||||
# Firefly III has two options for user authentication. "eloquent" is the default,
|
||||
# and "ldap" for LDAP servers.
|
||||
# For full instructions on these settings please visit:
|
||||
# https://docs.firefly-iii.org/advanced-installation/authentication
|
||||
# If you use Docker or similar, you can set this variable from a file by appending it with _FILE
|
||||
LOGIN_PROVIDER=eloquent
|
||||
|
||||
#
|
||||
# It's also possible to change the way users are authenticated. You could use Authelia for example.
|
||||
# Authentication via the REMOTE_USER header is supported. Change the value below to "remote_user_guard".
|
||||
#
|
||||
# If you do this please read the documentation for instructions and warnings:
|
||||
# https://docs.firefly-iii.org/advanced-installation/authentication
|
||||
#
|
||||
# This function is available in Firefly III v5.3.0 and higher.
|
||||
AUTHENTICATION_GUARD=web
|
||||
|
||||
#
|
||||
# Likewise, it's impossible to log out users who's authentication is handled by an external system.
|
||||
# Enter a custom URL here that will force a logout (your authentication provider can tell you).
|
||||
# Setting this variable only works when AUTHENTICATION_GUARD != web
|
||||
#
|
||||
CUSTOM_LOGOUT_URL=
|
||||
|
||||
# LDAP connection configuration
|
||||
# OpenLDAP, FreeIPA or ActiveDirectory
|
||||
# # If you use Docker or similar, you can set this variable from a file by appending it with _FILE
|
||||
ADLDAP_CONNECTION_SCHEME=OpenLDAP
|
||||
ADLDAP_AUTO_CONNECT=true
|
||||
|
||||
# LDAP connection settings
|
||||
# You can set the following variables from a file by appending them with _FILE:
|
||||
# ADLDAP_CONTROLLERS, ADLDAP_PORT, ADLDAP_BASEDN
|
||||
ADLDAP_CONTROLLERS=
|
||||
ADLDAP_PORT=389
|
||||
ADLDAP_TIMEOUT=5
|
||||
ADLDAP_BASEDN=""
|
||||
ADLDAP_FOLLOW_REFFERALS=false
|
||||
|
||||
# SSL/TLS settings
|
||||
ADLDAP_USE_SSL=false
|
||||
ADLDAP_USE_TLS=false
|
||||
ADLDAP_SSL_CACERTDIR=
|
||||
ADLDAP_SSL_CACERTFILE=
|
||||
ADLDAP_SSL_CERTFILE=
|
||||
ADLDAP_SSL_KEYFILE=
|
||||
ADLDAP_SSL_CIPHER_SUITE=
|
||||
ADLDAP_SSL_REQUIRE_CERT=
|
||||
|
||||
# You can set the following variables from a file by appending them with _FILE:
|
||||
ADLDAP_ADMIN_USERNAME=
|
||||
ADLDAP_ADMIN_PASSWORD=
|
||||
|
||||
# You can set the following variables from a file by appending them with _FILE:
|
||||
ADLDAP_ACCOUNT_PREFIX=
|
||||
ADLDAP_ACCOUNT_SUFFIX=
|
||||
|
||||
|
||||
# LDAP authentication settings.
|
||||
ADLDAP_PASSWORD_SYNC=false
|
||||
ADLDAP_LOGIN_FALLBACK=false
|
||||
|
||||
ADLDAP_DISCOVER_FIELD=distinguishedname
|
||||
ADLDAP_AUTH_FIELD=distinguishedname
|
||||
|
||||
# Will allow SSO if your server provides an AUTH_USER field.
|
||||
# You can set the following variables from a file by appending them with _FILE:
|
||||
WINDOWS_SSO_ENABLED=false
|
||||
WINDOWS_SSO_DISCOVER=samaccountname
|
||||
WINDOWS_SSO_KEY=AUTH_USER
|
||||
|
||||
# field to sync as local username.
|
||||
# You can set the following variable from a file by appending it with _FILE:
|
||||
ADLDAP_SYNC_FIELD=userprincipalname
|
||||
|
||||
# You can disable the X-Frame-Options header if it interferes with tools like
|
||||
# Organizr. This is at your own risk. Applications running in frames run the risk
|
||||
# of leaking information to their parent frame.
|
||||
DISABLE_FRAME_HEADER=false
|
||||
|
||||
# You can disable the Content Security Policy header when you're using an ancient browser
|
||||
# or any version of Microsoft Edge / Internet Explorer (which amounts to the same thing really)
|
||||
# This leaves you with the risk of not being able to stop XSS bugs should they ever surface.
|
||||
# This is at your own risk.
|
||||
DISABLE_CSP_HEADER=false
|
||||
|
||||
# If you wish to track your own behavior over Firefly III, set valid analytics tracker information here.
|
||||
# Nobody uses this except for me on the demo site. But hey, feel free to use this if you want to.
|
||||
# Do not prepend the TRACKER_URL with http:// or https://
|
||||
# The only tracker supported is Matomo.
|
||||
# You can set the following variables from a file by appending them with _FILE:
|
||||
TRACKER_SITE_ID=
|
||||
TRACKER_URL=
|
||||
|
||||
# You can fine tune the start-up of a Docker container by editing these environment variables.
|
||||
# Use this at your own risk. Disabling certain checks and features may result in lost of inconsistent data.
|
||||
# However if you know what you're doing you can significantly speed up container start times.
|
||||
# Set each value to true to enable, or false to disable.
|
||||
|
||||
# Check if the SQLite database exists. Can be skipped if you're not using SQLite.
|
||||
# Won't significantly speed up things.
|
||||
DKR_CHECK_SQLITE=true
|
||||
|
||||
# Run database creation and migration commands. Disable this only if you're 100% sure the DB exists
|
||||
# and is up to date.
|
||||
DKR_RUN_MIGRATION=true
|
||||
|
||||
# Run database upgrade commands. Disable this only when you're 100% sure your DB is up-to-date
|
||||
# with the latest fixes (outside of migrations!)
|
||||
DKR_RUN_UPGRADE=true
|
||||
|
||||
# Verify database integrity. Includes all data checks and verifications.
|
||||
# Disabling this makes Firefly III assume your DB is intact.
|
||||
DKR_RUN_VERIFY=true
|
||||
|
||||
# Run database reporting commands. When disabled, Firefly III won't go over your data to report current state.
|
||||
# Disabling this should have no impact on data integrity or safety but it won't warn you of possible issues.
|
||||
DKR_RUN_REPORT=true
|
||||
|
||||
# Generate OAuth2 keys.
|
||||
# When disabled, Firefly III won't attempt to generate OAuth2 Passport keys. This won't be an issue, IFF (if and only if)
|
||||
# you had previously generated keys already and they're stored in your database for restoration.
|
||||
DKR_RUN_PASSPORT_INSTALL=true
|
||||
|
||||
# Leave the following configuration vars as is.
|
||||
# Unless you like to tinker and know what you're doing.
|
||||
APP_NAME=FireflyIII
|
||||
ADLDAP_CONNECTION=default
|
||||
BROADCAST_DRIVER=log
|
||||
QUEUE_DRIVER=sync
|
||||
CACHE_PREFIX=firefly
|
||||
SEARCH_RESULT_LIMIT=50
|
||||
PUSHER_KEY=
|
||||
PUSHER_SECRET=
|
||||
PUSHER_ID=
|
||||
DEMO_USERNAME=
|
||||
DEMO_PASSWORD=
|
||||
USE_ENCRYPTION=false
|
||||
IS_HEROKU=false
|
||||
FIREFLY_III_LAYOUT=v1
|
||||
|
||||
#
|
||||
# If you have trouble configuring your Firefly III installation, DON'T BOTHER setting this variable.
|
||||
# It won't work. It doesn't do ANYTHING. Don't believe the lies you read online. I'm not joking.
|
||||
# This configuration value WILL NOT HELP.
|
||||
#
|
||||
# This variable is ONLY used in some of the emails Firefly III sends around. Nowhere else.
|
||||
# So when configuring anything WEB related this variable doesn't do anything. Nothing
|
||||
#
|
||||
# If you're stuck I understand you get desperate but look SOMEWHERE ELSE.
|
||||
#
|
||||
APP_URL=http://localhost
|
@@ -1,32 +0,0 @@
|
||||
bg_BG
|
||||
ca_ES
|
||||
cs_CZ
|
||||
da_DK
|
||||
de_DE
|
||||
el_GR
|
||||
en_GB
|
||||
en_US
|
||||
es_ES
|
||||
fi_FI
|
||||
fr_FR
|
||||
hu_HU
|
||||
id_ID
|
||||
it_IT
|
||||
ja_JP
|
||||
ko_KR
|
||||
nb_NO
|
||||
nl_NL
|
||||
nn_NO
|
||||
pl_PL
|
||||
pt_BR
|
||||
pt_PT
|
||||
ro_RO
|
||||
ru_RU
|
||||
sk_SK
|
||||
sl_SI
|
||||
sv_SE
|
||||
tr_TR
|
||||
uk_UA
|
||||
vi_VN
|
||||
zh-hans_CN
|
||||
zh-hant_CN
|
18
.editorconfig
Normal file
18
.editorconfig
Normal file
@@ -0,0 +1,18 @@
|
||||
root = true
|
||||
|
||||
[*]
|
||||
charset = utf-8
|
||||
end_of_line = lf
|
||||
indent_size = 4
|
||||
indent_style = space
|
||||
insert_final_newline = true
|
||||
trim_trailing_whitespace = true
|
||||
|
||||
[*.md]
|
||||
trim_trailing_whitespace = false
|
||||
|
||||
[*.{yml,yaml}]
|
||||
indent_size = 2
|
||||
|
||||
[docker-compose.yml]
|
||||
indent_size = 4
|
35
.env.example
35
.env.example
@@ -45,12 +45,6 @@ TRUSTED_PROXIES=
|
||||
# Default setting 'stack' will log to 'daily' and to 'stdout' at the same time.
|
||||
LOG_CHANNEL=stack
|
||||
|
||||
#
|
||||
# Used when logging to papertrail:
|
||||
#
|
||||
PAPERTRAIL_HOST=
|
||||
PAPERTRAIL_PORT=
|
||||
|
||||
# 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
|
||||
@@ -58,8 +52,30 @@ PAPERTRAIL_PORT=
|
||||
APP_LOG_LEVEL=notice
|
||||
|
||||
# Audit log level.
|
||||
# Set this to "emergency" if you dont want to store audit logs, leave on info otherwise.
|
||||
AUDIT_LOG_LEVEL=info
|
||||
# The audit log is used to log notable Firefly III events on a separate channel.
|
||||
# These log entries may contain sensitive financial information.
|
||||
# The audit log is disabled by default.
|
||||
#
|
||||
# To enable it, set AUDIT_LOG_LEVEL to "info"
|
||||
# To disable it, set AUDIT_LOG_LEVEL to "emergency"
|
||||
AUDIT_LOG_LEVEL=emergency
|
||||
|
||||
#
|
||||
# If you want, you can redirect the audit logs to another channel.
|
||||
# Set 'audit_stdout', 'audit_syslog', 'audit_errorlog' to log to the system itself.
|
||||
# Use audit_daily to log to a rotating file.
|
||||
# Use audit_papertrail to log to papertrail.
|
||||
#
|
||||
# If you do this, the audit logs may be mixed with normal logs because the settings for these channels
|
||||
# are often the same as the settings for the normal logs.
|
||||
AUDIT_LOG_CHANNEL=
|
||||
|
||||
#
|
||||
# Used when logging to papertrail:
|
||||
# Also used when audit logs log to papertrail:
|
||||
#
|
||||
PAPERTRAIL_HOST=
|
||||
PAPERTRAIL_PORT=
|
||||
|
||||
# Database credentials. Make sure the database exists. I recommend a dedicated user for Firefly III
|
||||
# For other database types, please see the FAQ: https://docs.firefly-iii.org/firefly-iii/faq/self-hosted/#i-want-to-use-sqlite
|
||||
@@ -241,7 +257,7 @@ ALLOW_WEBHOOKS=false
|
||||
#
|
||||
# The static cron job token can be useful when you use Docker and wish to manage cron jobs.
|
||||
# 1. Set this token to any 32-character value (this is important!).
|
||||
# 2. Use this token in the cron URL instead of a user's command line token.
|
||||
# 2. Use this token in the cron URL instead of a user's command line token that you can find in /profile
|
||||
#
|
||||
# For more info: https://docs.firefly-iii.org/firefly-iii/advanced-installation/cron/
|
||||
#
|
||||
@@ -298,7 +314,6 @@ PUSHER_SECRET=
|
||||
PUSHER_ID=
|
||||
DEMO_USERNAME=
|
||||
DEMO_PASSWORD=
|
||||
IS_HEROKU=false
|
||||
FIREFLY_III_LAYOUT=v1
|
||||
|
||||
#
|
||||
|
17
.gitattributes
vendored
17
.gitattributes
vendored
@@ -1,8 +1,11 @@
|
||||
* text=auto
|
||||
*.css linguist-vendored
|
||||
*.scss linguist-vendored
|
||||
*.js linguist-vendored
|
||||
* text=auto eol=lf
|
||||
|
||||
*.blade.php diff=html
|
||||
*.css diff=css
|
||||
*.html diff=html
|
||||
*.md diff=markdown
|
||||
*.php diff=php
|
||||
|
||||
/.github export-ignore
|
||||
CHANGELOG.md export-ignore
|
||||
/tests export-ignore
|
||||
/phpunit.xml export-ignore
|
||||
/.ci export-ignore
|
||||
.styleci.yml export-ignore
|
||||
|
28
.github/workflows/sonarcloud.yml
vendored
28
.github/workflows/sonarcloud.yml
vendored
@@ -1,5 +1,6 @@
|
||||
name: Sonarcloud
|
||||
on:
|
||||
pull_request:
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
@@ -12,6 +13,33 @@ jobs:
|
||||
- uses: actions/checkout@v3
|
||||
with:
|
||||
fetch-depth: 0 # Shallow clones should be disabled for a better relevancy of analysis
|
||||
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v2
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Setup PHP with Xdebug
|
||||
uses: shivammathur/setup-php@v2
|
||||
with:
|
||||
php-version: '8.2'
|
||||
coverage: xdebug
|
||||
|
||||
- name: Install Composer dependencies
|
||||
run: composer install --prefer-dist --no-interaction --no-progress --no-scripts
|
||||
|
||||
- name: Copy environment file
|
||||
run: cp .env.example .env
|
||||
|
||||
- name: Generate app key
|
||||
run: php artisan key:generate
|
||||
|
||||
- name: "Run tests with coverage"
|
||||
run: composer coverage
|
||||
|
||||
- name: Fix code coverage paths
|
||||
run: sed -i 's@'$GITHUB_WORKSPACE'@/github/workspace/@g' coverage.xml
|
||||
|
||||
- name: SonarCloud Scan
|
||||
uses: SonarSource/sonarcloud-github-action@master
|
||||
env:
|
||||
|
2
.gitignore
vendored
2
.gitignore
vendored
@@ -7,4 +7,4 @@ npm-debug.log
|
||||
yarn-error.log
|
||||
.env
|
||||
/.ci/php-cs-fixer/vendor
|
||||
/.ci/coverage
|
||||
coverage.xml
|
||||
|
65
app.json
65
app.json
@@ -1,65 +0,0 @@
|
||||
{
|
||||
"name": "Firefly III",
|
||||
"description": "A free and open source personal finances manager",
|
||||
"repository": "https://github.com/firefly-iii/firefly-iii",
|
||||
"website": "https://firefly-iii.org/",
|
||||
"logo": "https://raw.githubusercontent.com/firefly-iii/firefly-iii/main/public/mstile-150x150.png",
|
||||
"keywords": [
|
||||
"finance",
|
||||
"finances",
|
||||
"manager",
|
||||
"management",
|
||||
"euro",
|
||||
"dollar",
|
||||
"laravel",
|
||||
"money",
|
||||
"currency",
|
||||
"financials",
|
||||
"financial",
|
||||
"budgets",
|
||||
"administration",
|
||||
"tool",
|
||||
"tooling",
|
||||
"help",
|
||||
"helper",
|
||||
"assistant",
|
||||
"planning",
|
||||
"organizing",
|
||||
"bills",
|
||||
"personal finance",
|
||||
"budgets",
|
||||
"budgeting",
|
||||
"budgeting tool",
|
||||
"budgeting application",
|
||||
"transactions",
|
||||
"self hosted",
|
||||
"self-hosted",
|
||||
"transfers",
|
||||
"management"
|
||||
],
|
||||
"addons": [
|
||||
{
|
||||
"plan": "heroku-postgresql",
|
||||
"options": {
|
||||
"version": "12"
|
||||
}
|
||||
}
|
||||
],
|
||||
"scripts": {
|
||||
"postdeploy": "php artisan migrate:refresh --seed;php artisan firefly:instructions install"
|
||||
},
|
||||
"buildpacks": [
|
||||
{
|
||||
"url": "heroku/php"
|
||||
},
|
||||
{
|
||||
"url": "https://github.com/heroku/heroku-buildpack-locale"
|
||||
}
|
||||
],
|
||||
"env": {
|
||||
"APP_KEY": {
|
||||
"description": "This key is used to create app cookies en secure attachments.",
|
||||
"value": "base64:If1gJN4pyycXTq+WS5TjneDympKuu+8SKvTl6RZnhJg="
|
||||
}
|
||||
}
|
||||
}
|
@@ -105,7 +105,7 @@ class AccountController extends Controller
|
||||
'name' => $account->name,
|
||||
'name_with_balance' => $nameWithBalance,
|
||||
'type' => $account->accountType->type,
|
||||
'currency_id' => $currency->id,
|
||||
'currency_id' => (string)$currency->id,
|
||||
'currency_name' => $currency->name,
|
||||
'currency_code' => $currency->code,
|
||||
'currency_symbol' => $currency->symbol,
|
||||
|
@@ -102,6 +102,7 @@ abstract class Controller extends BaseController
|
||||
} catch (BadRequestException $e) {
|
||||
Log::error(sprintf('Request field "%s" contains a non-scalar value. Value set to NULL.', $field));
|
||||
Log::error($e->getMessage());
|
||||
Log::error($e->getTraceAsString());
|
||||
$value = null;
|
||||
}
|
||||
$obj = null;
|
||||
@@ -130,6 +131,7 @@ abstract class Controller extends BaseController
|
||||
} catch (BadRequestException $e) {
|
||||
Log::error(sprintf('Request field "%s" contains a non-scalar value. Value set to NULL.', $integer));
|
||||
Log::error($e->getMessage());
|
||||
Log::error($e->getTraceAsString());
|
||||
$value = null;
|
||||
}
|
||||
if (null !== $value) {
|
||||
@@ -154,6 +156,7 @@ abstract class Controller extends BaseController
|
||||
} catch (BadRequestException $e) {
|
||||
Log::error('Request field "sort" contains a non-scalar value. Value set to NULL.');
|
||||
Log::error($e->getMessage());
|
||||
Log::error($e->getTraceAsString());
|
||||
$param = '';
|
||||
}
|
||||
if ('' === $param) {
|
||||
|
@@ -279,6 +279,9 @@ class DestroyController extends Controller
|
||||
$tagRepository->destroyAll();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return void
|
||||
*/
|
||||
private function destroyObjectGroups(): void
|
||||
{
|
||||
/** @var ObjectGroupRepositoryInterface $repository */
|
||||
|
@@ -29,6 +29,8 @@ use FireflyIII\Api\V1\Requests\Data\Export\ExportRequest;
|
||||
use FireflyIII\Exceptions\FireflyException;
|
||||
use FireflyIII\Support\Export\ExportDataGenerator;
|
||||
use Illuminate\Http\Response as LaravelResponse;
|
||||
use Psr\Container\ContainerExceptionInterface;
|
||||
use Psr\Container\NotFoundExceptionInterface;
|
||||
|
||||
/**
|
||||
* Class ExportController
|
||||
@@ -74,6 +76,8 @@ class ExportController extends Controller
|
||||
*
|
||||
* @return LaravelResponse
|
||||
* @throws FireflyException
|
||||
* @throws ContainerExceptionInterface
|
||||
* @throws NotFoundExceptionInterface
|
||||
*/
|
||||
private function returnExport(string $key): LaravelResponse
|
||||
{
|
||||
|
@@ -37,6 +37,9 @@ use FireflyIII\Models\TransactionGroup;
|
||||
use FireflyIII\Models\TransactionJournal;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
|
||||
/**
|
||||
* Class PurgeController
|
||||
*/
|
||||
class PurgeController extends Controller
|
||||
{
|
||||
/**
|
||||
|
@@ -78,7 +78,8 @@ class UpdateController extends Controller
|
||||
public function update(UpdateRequest $request, TransactionGroup $transactionGroup): JsonResponse
|
||||
{
|
||||
Log::debug('Now in update routine for transaction group!');
|
||||
$data = $request->getAll();
|
||||
$data = $request->getAll();
|
||||
|
||||
$transactionGroup = $this->groupRepository->update($transactionGroup, $data);
|
||||
$manager = $this->getManager();
|
||||
|
||||
|
@@ -30,6 +30,9 @@ use FireflyIII\Repositories\LinkType\LinkTypeRepositoryInterface;
|
||||
use FireflyIII\User;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
|
||||
/**
|
||||
* Class DestroyController
|
||||
*/
|
||||
class DestroyController extends Controller
|
||||
{
|
||||
private LinkTypeRepositoryInterface $repository;
|
||||
|
@@ -37,6 +37,9 @@ use League\Fractal\Pagination\IlluminatePaginatorAdapter;
|
||||
use League\Fractal\Resource\Collection as FractalCollection;
|
||||
use League\Fractal\Resource\Item;
|
||||
|
||||
/**
|
||||
* Class ShowController
|
||||
*/
|
||||
class ShowController extends Controller
|
||||
{
|
||||
private LinkTypeRepositoryInterface $repository;
|
||||
|
@@ -35,6 +35,9 @@ use FireflyIII\User;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use League\Fractal\Resource\Item;
|
||||
|
||||
/**
|
||||
* Class StoreController
|
||||
*/
|
||||
class StoreController extends Controller
|
||||
{
|
||||
use TransactionFilter;
|
||||
|
@@ -34,6 +34,9 @@ use FireflyIII\User;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use League\Fractal\Resource\Item;
|
||||
|
||||
/**
|
||||
* Class UpdateController
|
||||
*/
|
||||
class UpdateController extends Controller
|
||||
{
|
||||
private JournalRepositoryInterface $journalRepository;
|
||||
|
@@ -190,7 +190,7 @@ class BasicController extends Controller
|
||||
'key' => sprintf('balance-in-%s', $currency->code),
|
||||
'title' => trans('firefly.box_balance_in_currency', ['currency' => $currency->symbol]),
|
||||
'monetary_value' => $sums[$currencyId] ?? '0',
|
||||
'currency_id' => $currency->id,
|
||||
'currency_id' => (string)$currency->id,
|
||||
'currency_code' => $currency->code,
|
||||
'currency_symbol' => $currency->symbol,
|
||||
'currency_decimal_places' => $currency->decimal_places,
|
||||
@@ -203,7 +203,7 @@ class BasicController extends Controller
|
||||
'key' => sprintf('spent-in-%s', $currency->code),
|
||||
'title' => trans('firefly.box_spent_in_currency', ['currency' => $currency->symbol]),
|
||||
'monetary_value' => $expenses[$currencyId] ?? '0',
|
||||
'currency_id' => $currency->id,
|
||||
'currency_id' => (string)$currency->id,
|
||||
'currency_code' => $currency->code,
|
||||
'currency_symbol' => $currency->symbol,
|
||||
'currency_decimal_places' => $currency->decimal_places,
|
||||
@@ -215,7 +215,7 @@ class BasicController extends Controller
|
||||
'key' => sprintf('earned-in-%s', $currency->code),
|
||||
'title' => trans('firefly.box_earned_in_currency', ['currency' => $currency->symbol]),
|
||||
'monetary_value' => $incomes[$currencyId] ?? '0',
|
||||
'currency_id' => $currency->id,
|
||||
'currency_id' => (string)$currency->id,
|
||||
'currency_code' => $currency->code,
|
||||
'currency_symbol' => $currency->symbol,
|
||||
'currency_decimal_places' => $currency->decimal_places,
|
||||
@@ -253,7 +253,7 @@ class BasicController extends Controller
|
||||
'key' => sprintf('bills-paid-in-%s', $info['code']),
|
||||
'title' => trans('firefly.box_bill_paid_in_currency', ['currency' => $info['symbol']]),
|
||||
'monetary_value' => $amount,
|
||||
'currency_id' => $info['id'],
|
||||
'currency_id' => (string)$info['id'],
|
||||
'currency_code' => $info['code'],
|
||||
'currency_symbol' => $info['symbol'],
|
||||
'currency_decimal_places' => $info['decimal_places'],
|
||||
@@ -272,7 +272,7 @@ class BasicController extends Controller
|
||||
'key' => sprintf('bills-unpaid-in-%s', $info['code']),
|
||||
'title' => trans('firefly.box_bill_unpaid_in_currency', ['currency' => $info['symbol']]),
|
||||
'monetary_value' => $amount,
|
||||
'currency_id' => $info['id'],
|
||||
'currency_id' => (string)$info['id'],
|
||||
'currency_code' => $info['code'],
|
||||
'currency_symbol' => $info['symbol'],
|
||||
'currency_decimal_places' => $info['decimal_places'],
|
||||
@@ -302,7 +302,7 @@ class BasicController extends Controller
|
||||
|
||||
foreach ($spent as $row) {
|
||||
// either an amount was budgeted or 0 is available.
|
||||
$amount = $available[$row['currency_id']] ?? '0';
|
||||
$amount = (string)($available[$row['currency_id']] ?? '0');
|
||||
$spentInCurrency = $row['sum'];
|
||||
$leftToSpend = bcadd($amount, $spentInCurrency);
|
||||
|
||||
@@ -316,22 +316,17 @@ class BasicController extends Controller
|
||||
'key' => sprintf('left-to-spend-in-%s', $row['currency_code']),
|
||||
'title' => trans('firefly.box_left_to_spend_in_currency', ['currency' => $row['currency_symbol']]),
|
||||
'monetary_value' => $leftToSpend,
|
||||
'currency_id' => $row['currency_id'],
|
||||
'currency_id' => (string)$row['currency_id'],
|
||||
'currency_code' => $row['currency_code'],
|
||||
'currency_symbol' => $row['currency_symbol'],
|
||||
'currency_decimal_places' => $row['currency_decimal_places'],
|
||||
'value_parsed' => app('amount')->formatFlat($row['currency_symbol'], $row['currency_decimal_places'], $leftToSpend, false),
|
||||
'local_icon' => 'money',
|
||||
'sub_title' => (string)trans(
|
||||
'firefly.box_spend_per_day',
|
||||
[
|
||||
'amount' => app('amount')->formatFlat(
|
||||
$row['currency_symbol'],
|
||||
$row['currency_decimal_places'],
|
||||
$perDay,
|
||||
false
|
||||
),
|
||||
]
|
||||
'sub_title' => app('amount')->formatFlat(
|
||||
$row['currency_symbol'],
|
||||
$row['currency_decimal_places'],
|
||||
$perDay,
|
||||
false
|
||||
),
|
||||
];
|
||||
}
|
||||
@@ -386,7 +381,7 @@ class BasicController extends Controller
|
||||
'key' => sprintf('net-worth-in-%s', $currency->code),
|
||||
'title' => trans('firefly.box_net_worth_in_currency', ['currency' => $currency->symbol]),
|
||||
'monetary_value' => $amount,
|
||||
'currency_id' => $currency->id,
|
||||
'currency_id' => (string)$currency->id,
|
||||
'currency_code' => $currency->code,
|
||||
'currency_symbol' => $currency->symbol,
|
||||
'currency_decimal_places' => $currency->decimal_places,
|
||||
|
@@ -138,7 +138,6 @@ class ConfigurationController extends Controller
|
||||
*
|
||||
* @return JsonResponse
|
||||
* @throws ContainerExceptionInterface
|
||||
* @throws FireflyException
|
||||
* @throws NotFoundExceptionInterface
|
||||
*/
|
||||
public function show(string $configKey): JsonResponse
|
||||
|
@@ -28,6 +28,8 @@ use FireflyIII\Api\V1\Requests\System\CronRequest;
|
||||
use FireflyIII\Support\Http\Controllers\CronRunner;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
use Psr\Container\ContainerExceptionInterface;
|
||||
use Psr\Container\NotFoundExceptionInterface;
|
||||
|
||||
/**
|
||||
* Class CronController
|
||||
@@ -44,6 +46,8 @@ class CronController extends Controller
|
||||
* @param string $token
|
||||
*
|
||||
* @return JsonResponse
|
||||
* @throws ContainerExceptionInterface
|
||||
* @throws NotFoundExceptionInterface
|
||||
*/
|
||||
public function cron(CronRequest $request, string $token): JsonResponse
|
||||
{
|
||||
@@ -54,7 +58,7 @@ class CronController extends Controller
|
||||
$return = [];
|
||||
$return['recurring_transactions'] = $this->runRecurring($config['force'], $config['date']);
|
||||
$return['auto_budgets'] = $this->runAutoBudget($config['force'], $config['date']);
|
||||
if (true === config('cer.enabled')) {
|
||||
if (true === config('cer.download_enabled')) {
|
||||
$return['exchange_rates'] = $this->exchangeRatesCronJob($config['force'], $config['date']);
|
||||
}
|
||||
$return['bill_warnings'] = $this->billWarningCronJob($config['force'], $config['date']);
|
||||
|
@@ -35,6 +35,9 @@ use League\Fractal\Pagination\IlluminatePaginatorAdapter;
|
||||
use League\Fractal\Resource\Collection as FractalCollection;
|
||||
use League\Fractal\Resource\Item;
|
||||
|
||||
/**
|
||||
* Class MessageController
|
||||
*/
|
||||
class MessageController extends Controller
|
||||
{
|
||||
public const RESOURCE_KEY = 'webhook_messages';
|
||||
|
@@ -127,6 +127,7 @@ class ShowController extends Controller
|
||||
*/
|
||||
public function triggerTransaction(Webhook $webhook, TransactionGroup $group): JsonResponse
|
||||
{
|
||||
app('log')->debug(sprintf('Now in triggerTransaction(%d, %d)', $webhook->id, $group->id));
|
||||
/** @var MessageGeneratorInterface $engine */
|
||||
$engine = app(MessageGeneratorInterface::class);
|
||||
$engine->setUser(auth()->user());
|
||||
@@ -141,6 +142,7 @@ class ShowController extends Controller
|
||||
$engine->generateMessages();
|
||||
|
||||
// trigger event to send them:
|
||||
app('log')->debug('send event RequestedSendWebhookMessages');
|
||||
event(new RequestedSendWebhookMessages());
|
||||
|
||||
return response()->json([], 204);
|
||||
|
@@ -38,6 +38,9 @@ class ExportRequest extends FormRequest
|
||||
use ChecksLogin;
|
||||
use ConvertsDataTypes;
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function getAll(): array
|
||||
{
|
||||
$result = [
|
||||
|
@@ -59,6 +59,7 @@ class UpdateRequest extends FormRequest
|
||||
* Get all data. Is pretty complex because of all the ??-statements.
|
||||
*
|
||||
* @return array
|
||||
* @throws FireflyException
|
||||
*/
|
||||
public function getAll(): array
|
||||
{
|
||||
@@ -152,6 +153,7 @@ class UpdateRequest extends FormRequest
|
||||
* Get transaction data.
|
||||
*
|
||||
* @return array
|
||||
* @throws FireflyException
|
||||
*/
|
||||
private function getTransactionData(): array
|
||||
{
|
||||
@@ -322,7 +324,7 @@ class UpdateRequest extends FormRequest
|
||||
|
||||
return [
|
||||
// basic fields for group:
|
||||
'group_title' => 'between:1,1000',
|
||||
'group_title' => 'between:1,1000|nullable',
|
||||
'apply_rules' => [new IsBoolean()],
|
||||
|
||||
// transaction rules (in array for splits):
|
||||
@@ -335,8 +337,8 @@ class UpdateRequest extends FormRequest
|
||||
|
||||
|
||||
// currency info
|
||||
'transactions.*.currency_id' => 'numeric|exists:transaction_currencies,id',
|
||||
'transactions.*.currency_code' => 'min:3|max:51|exists:transaction_currencies,code',
|
||||
'transactions.*.currency_id' => 'numeric|exists:transaction_currencies,id|nullable',
|
||||
'transactions.*.currency_code' => 'min:3|max:51|exists:transaction_currencies,code|nullable',
|
||||
'transactions.*.foreign_currency_id' => 'nullable|numeric|exists:transaction_currencies,id',
|
||||
'transactions.*.foreign_currency_code' => 'nullable|min:3|max:51|exists:transaction_currencies,code',
|
||||
|
||||
@@ -356,9 +358,9 @@ class UpdateRequest extends FormRequest
|
||||
'transactions.*.destination_name' => 'between:1,255|nullable',
|
||||
|
||||
// budget, category, bill and piggy
|
||||
'transactions.*.budget_id' => ['mustExist:budgets,id', new BelongsUser()],
|
||||
'transactions.*.budget_id' => ['mustExist:budgets,id', new BelongsUser(), 'nullable'],
|
||||
'transactions.*.budget_name' => ['between:1,255', 'nullable', new BelongsUser()],
|
||||
'transactions.*.category_id' => ['mustExist:categories,id', new BelongsUser()],
|
||||
'transactions.*.category_id' => ['mustExist:categories,id', new BelongsUser(), 'nullable'],
|
||||
'transactions.*.category_name' => 'between:1,255|nullable',
|
||||
'transactions.*.bill_id' => ['numeric', 'nullable', 'mustExist:bills,id', new BelongsUser()],
|
||||
'transactions.*.bill_name' => ['between:1,255', 'nullable', new BelongsUser()],
|
||||
@@ -366,7 +368,7 @@ class UpdateRequest extends FormRequest
|
||||
// other interesting fields
|
||||
'transactions.*.reconciled' => [new IsBoolean()],
|
||||
'transactions.*.notes' => 'min:1|max:50000|nullable',
|
||||
'transactions.*.tags' => 'between:0,255',
|
||||
'transactions.*.tags' => 'between:0,255|nullable',
|
||||
|
||||
// meta info fields
|
||||
'transactions.*.internal_reference' => 'min:1|max:255|nullable',
|
||||
|
@@ -27,6 +27,9 @@ use FireflyIII\Support\Request\ChecksLogin;
|
||||
use FireflyIII\Support\Request\ConvertsDataTypes;
|
||||
use Illuminate\Foundation\Http\FormRequest;
|
||||
|
||||
/**
|
||||
* Class PreferenceStoreRequest
|
||||
*/
|
||||
class PreferenceStoreRequest extends FormRequest
|
||||
{
|
||||
use ChecksLogin;
|
||||
|
@@ -28,6 +28,9 @@ use FireflyIII\Support\Request\ChecksLogin;
|
||||
use FireflyIII\Support\Request\ConvertsDataTypes;
|
||||
use Illuminate\Foundation\Http\FormRequest;
|
||||
|
||||
/**
|
||||
* Class PreferenceUpdateRequest
|
||||
*/
|
||||
class PreferenceUpdateRequest extends FormRequest
|
||||
{
|
||||
use ChecksLogin;
|
||||
|
@@ -33,7 +33,6 @@ use FireflyIII\Repositories\Account\AccountRepositoryInterface;
|
||||
use FireflyIII\Repositories\Administration\Account\AccountRepositoryInterface as AdminAccountRepositoryInterface;
|
||||
use FireflyIII\Support\Http\Api\AccountFilter;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use JsonException;
|
||||
|
||||
/**
|
||||
* Class AccountController
|
||||
@@ -65,12 +64,16 @@ class AccountController extends Controller
|
||||
|
||||
/**
|
||||
* Documentation for this endpoint:
|
||||
* TODO endpoint is not documented.
|
||||
* TODO list of checks
|
||||
* 1. use dates from ParameterBag
|
||||
* 2. Request validates dates
|
||||
* 3. Request includes user_group_id as administration_id
|
||||
* 4. Endpoint is documented.
|
||||
* 5. Collector uses administration_id
|
||||
*
|
||||
* @param AutocompleteRequest $request
|
||||
*
|
||||
* @return JsonResponse
|
||||
* @throws JsonException
|
||||
* @throws FireflyException
|
||||
* @throws FireflyException
|
||||
*/
|
||||
@@ -79,7 +82,7 @@ class AccountController extends Controller
|
||||
$data = $request->getData();
|
||||
$types = $data['types'];
|
||||
$query = $data['query'];
|
||||
$date = $data['date'] ?? today(config('app.timezone'));
|
||||
$date = $this->parameters->get('date') ?? today(config('app.timezone'));
|
||||
$this->adminRepository->setAdministrationId($data['administration_id']);
|
||||
|
||||
$return = [];
|
||||
@@ -101,7 +104,7 @@ class AccountController extends Controller
|
||||
'name' => $account->name,
|
||||
'name_with_balance' => $nameWithBalance,
|
||||
'type' => $account->accountType->type,
|
||||
'currency_id' => $currency->id,
|
||||
'currency_id' => (string)$currency->id,
|
||||
'currency_name' => $currency->name,
|
||||
'currency_code' => $currency->code,
|
||||
'currency_symbol' => $currency->symbol,
|
||||
|
@@ -27,10 +27,12 @@ namespace FireflyIII\Api\V2\Controllers\Chart;
|
||||
use Carbon\Carbon;
|
||||
use FireflyIII\Api\V2\Controllers\Controller;
|
||||
use FireflyIII\Api\V2\Request\Generic\DateRequest;
|
||||
use FireflyIII\Exceptions\FireflyException;
|
||||
use FireflyIII\Models\Account;
|
||||
use FireflyIII\Models\AccountType;
|
||||
use FireflyIII\Repositories\Account\AccountRepositoryInterface;
|
||||
use FireflyIII\Support\Http\Api\ConvertsExchangeRates;
|
||||
use FireflyIII\Models\TransactionCurrency;
|
||||
use FireflyIII\Repositories\Administration\Account\AccountRepositoryInterface;
|
||||
use FireflyIII\Support\Http\Api\CleansChartData;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Psr\Container\ContainerExceptionInterface;
|
||||
use Psr\Container\NotFoundExceptionInterface;
|
||||
@@ -40,7 +42,7 @@ use Psr\Container\NotFoundExceptionInterface;
|
||||
*/
|
||||
class AccountController extends Controller
|
||||
{
|
||||
use ConvertsExchangeRates;
|
||||
use CleansChartData;
|
||||
|
||||
private AccountRepositoryInterface $repository;
|
||||
|
||||
@@ -53,7 +55,7 @@ class AccountController extends Controller
|
||||
$this->middleware(
|
||||
function ($request, $next) {
|
||||
$this->repository = app(AccountRepositoryInterface::class);
|
||||
|
||||
$this->repository->setAdministrationId(auth()->user()->user_group_id);
|
||||
return $next($request);
|
||||
}
|
||||
);
|
||||
@@ -63,73 +65,87 @@ class AccountController extends Controller
|
||||
* This endpoint is documented at
|
||||
* https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v2)#/charts/getChartAccountOverview
|
||||
*
|
||||
* The native currency is the preferred currency on the page /currencies.
|
||||
*
|
||||
* If a transaction has foreign currency = native currency, the foreign amount will be used, no conversion
|
||||
* will take place.
|
||||
*
|
||||
* TODO validate and set administration_id from request
|
||||
*
|
||||
* @param DateRequest $request
|
||||
*
|
||||
* @return JsonResponse
|
||||
* @throws ContainerExceptionInterface
|
||||
* @throws NotFoundExceptionInterface
|
||||
* @throws FireflyException
|
||||
*/
|
||||
public function dashboard(DateRequest $request): JsonResponse
|
||||
{
|
||||
// parameters for chart:
|
||||
$dates = $request->getAll();
|
||||
/** @var Carbon $start */
|
||||
$start = $dates['start'];
|
||||
$start = $this->parameters->get('start');
|
||||
/** @var Carbon $end */
|
||||
$end = $dates['end'];
|
||||
$end = $this->parameters->get('end');
|
||||
$end->endOfDay();
|
||||
|
||||
// user's preferences
|
||||
$defaultSet = $this->repository->getAccountsByType([AccountType::ASSET, AccountType::DEFAULT])->pluck('id')->toArray();
|
||||
$frontPage = app('preferences')->get('frontPageAccounts', $defaultSet);
|
||||
$default = app('amount')->getDefaultCurrency();
|
||||
$accounts = $this->repository->getAccountsById($frontPage->data);
|
||||
$chartData = [];
|
||||
/** @var TransactionCurrency $default */
|
||||
$default = app('amount')->getDefaultCurrency();
|
||||
$accounts = $this->repository->getAccountsById($frontPage->data);
|
||||
$chartData = [];
|
||||
|
||||
if (!(is_array($frontPage->data) && count($frontPage->data) > 0)) {
|
||||
$frontPage->data = $defaultSet;
|
||||
$frontPage->save();
|
||||
}
|
||||
|
||||
/** @var Account $account */
|
||||
foreach ($accounts as $account) {
|
||||
$currency = $this->repository->getAccountCurrency($account);
|
||||
if (null === $currency) {
|
||||
$currency = $default;
|
||||
}
|
||||
$currentSet = [
|
||||
$currentSet = [
|
||||
'label' => $account->name,
|
||||
// the currency that belongs to the account.
|
||||
'currency_id' => (string)$currency->id,
|
||||
'currency_code' => $currency->code,
|
||||
'currency_symbol' => $currency->symbol,
|
||||
'currency_decimal_places' => $currency->decimal_places,
|
||||
'native_id' => null,
|
||||
'native_code' => null,
|
||||
'native_symbol' => null,
|
||||
'native_decimal_places' => null,
|
||||
'start_date' => $start->toAtomString(),
|
||||
'end_date' => $end->toAtomString(),
|
||||
'type' => 'line', // line, area or bar
|
||||
'yAxisID' => 0, // 0, 1, 2
|
||||
|
||||
// the default currency of the user (could be the same!)
|
||||
'native_id' => (string)$default->id,
|
||||
'native_code' => $default->code,
|
||||
'native_symbol' => $default->symbol,
|
||||
'native_decimal_places' => (int)$default->decimal_places,
|
||||
'start' => $start->toAtomString(),
|
||||
'end' => $end->toAtomString(),
|
||||
'period' => '1D',
|
||||
'entries' => [],
|
||||
'native_entries' => [],
|
||||
];
|
||||
$currentStart = clone $start;
|
||||
$range = app('steam')->balanceInRange($account, $start, clone $end);
|
||||
$currentStart = clone $start;
|
||||
$range = app('steam')->balanceInRange($account, $start, clone $end, $currency);
|
||||
$rangeConverted = app('steam')->balanceInRangeConverted($account, $start, clone $end, $default);
|
||||
|
||||
// 2022-10-11: this method no longer converts to floats
|
||||
|
||||
$previous = array_values($range)[0];
|
||||
$previous = array_values($range)[0];
|
||||
$previousConverted = array_values($rangeConverted)[0];
|
||||
while ($currentStart <= $end) {
|
||||
$format = $currentStart->format('Y-m-d');
|
||||
$label = $currentStart->toAtomString();
|
||||
$balance = array_key_exists($format, $range) ? $range[$format] : $previous;
|
||||
$previous = $balance;
|
||||
$format = $currentStart->format('Y-m-d');
|
||||
$label = $currentStart->toAtomString();
|
||||
$balance = array_key_exists($format, $range) ? $range[$format] : $previous;
|
||||
$balanceConverted = array_key_exists($format, $rangeConverted) ? $rangeConverted[$format] : $previousConverted;
|
||||
$previous = $balance;
|
||||
$previousConverted = $balanceConverted;
|
||||
|
||||
$currentStart->addDay();
|
||||
$currentSet['entries'][$label] = $balance;
|
||||
$currentSet['entries'][$label] = $balance;
|
||||
$currentSet['native_entries'][$label] = $balanceConverted;
|
||||
}
|
||||
$currentSet = $this->cerChartSet($currentSet);
|
||||
$chartData[] = $currentSet;
|
||||
}
|
||||
|
||||
return response()->json($chartData);
|
||||
return response()->json($this->clean($chartData));
|
||||
}
|
||||
|
||||
}
|
||||
|
260
app/Api/V2/Controllers/Chart/BalanceController.php
Normal file
260
app/Api/V2/Controllers/Chart/BalanceController.php
Normal file
@@ -0,0 +1,260 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
/*
|
||||
* BalanceController.php
|
||||
* Copyright (c) 2023 james@firefly-iii.org
|
||||
*
|
||||
* This file is part of Firefly III (https://github.com/firefly-iii).
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
namespace FireflyIII\Api\V2\Controllers\Chart;
|
||||
|
||||
use Carbon\Carbon;
|
||||
use FireflyIII\Api\V2\Controllers\Controller;
|
||||
use FireflyIII\Api\V2\Request\Chart\BalanceChartRequest;
|
||||
use FireflyIII\Exceptions\FireflyException;
|
||||
use FireflyIII\Helpers\Collector\GroupCollectorInterface;
|
||||
use FireflyIII\Models\TransactionCurrency;
|
||||
use FireflyIII\Models\TransactionType;
|
||||
use FireflyIII\Repositories\Administration\Account\AccountRepositoryInterface;
|
||||
use FireflyIII\Support\Http\Api\CleansChartData;
|
||||
use FireflyIII\Support\Http\Api\ExchangeRateConverter;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Support\Collection;
|
||||
|
||||
/**
|
||||
* Class BalanceController
|
||||
*/
|
||||
class BalanceController extends Controller
|
||||
{
|
||||
use CleansChartData;
|
||||
|
||||
private AccountRepositoryInterface $repository;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
$this->middleware(
|
||||
function ($request, $next) {
|
||||
$this->repository = app(AccountRepositoryInterface::class);
|
||||
|
||||
return $next($request);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* The code is practically a duplicate of ReportController::operations.
|
||||
*
|
||||
* Currency is up to the account/transactions in question, but conversion to the default
|
||||
* currency is possible.
|
||||
*
|
||||
* If the transaction being processed is already in native currency OR if the
|
||||
* foreign amount is in the native currency, the amount will not be converted.
|
||||
*
|
||||
* TODO validate and set administration_id
|
||||
* TODO collector set group, not user
|
||||
*
|
||||
* @param BalanceChartRequest $request
|
||||
*
|
||||
* @return JsonResponse
|
||||
* @throws FireflyException
|
||||
*/
|
||||
public function balance(BalanceChartRequest $request): JsonResponse
|
||||
{
|
||||
$params = $request->getAll();
|
||||
/** @var Carbon $start */
|
||||
$start = $this->parameters->get('start');
|
||||
/** @var Carbon $end */
|
||||
$end = $this->parameters->get('end');
|
||||
$end->endOfDay();
|
||||
/** @var Collection $accounts */
|
||||
$accounts = $params['accounts'];
|
||||
$preferredRange = $params['period'];
|
||||
|
||||
// set some formats, based on input parameters.
|
||||
$format = app('navigation')->preferredCarbonFormatByPeriod($preferredRange);
|
||||
|
||||
// prepare for currency conversion and data collection:
|
||||
$ids = $accounts->pluck('id')->toArray();
|
||||
/** @var TransactionCurrency $default */
|
||||
$default = app('amount')->getDefaultCurrency();
|
||||
$converter = new ExchangeRateConverter();
|
||||
$currencies = [(int)$default->id => $default,]; // currency cache
|
||||
$data = [];
|
||||
$chartData = [];
|
||||
|
||||
// get journals for entire period:
|
||||
/** @var GroupCollectorInterface $collector */
|
||||
$collector = app(GroupCollectorInterface::class);
|
||||
$collector->setRange($start, $end)->withAccountInformation();
|
||||
$collector->setXorAccounts($accounts);
|
||||
$collector->setTypes([TransactionType::WITHDRAWAL, TransactionType::DEPOSIT, TransactionType::RECONCILIATION, TransactionType::TRANSFER]);
|
||||
$journals = $collector->getExtractedJournals();
|
||||
|
||||
// set array for default currency (even if unused later on)
|
||||
$defaultCurrencyId = (int)$default->id;
|
||||
$data[$defaultCurrencyId] = [
|
||||
'currency_id' => (string)$defaultCurrencyId,
|
||||
'currency_symbol' => $default->symbol,
|
||||
'currency_code' => $default->code,
|
||||
'currency_name' => $default->name,
|
||||
'currency_decimal_places' => (int)$default->decimal_places,
|
||||
'native_id' => (string)$defaultCurrencyId,
|
||||
'native_symbol' => $default->symbol,
|
||||
'native_code' => $default->code,
|
||||
'native_name' => $default->name,
|
||||
'native_decimal_places' => (int)$default->decimal_places,
|
||||
];
|
||||
|
||||
|
||||
// loop. group by currency and by period.
|
||||
/** @var array $journal */
|
||||
foreach ($journals as $journal) {
|
||||
// format the date according to the period
|
||||
$period = $journal['date']->format($format);
|
||||
|
||||
// collect (and cache) currency information for this journal.
|
||||
$currencyId = (int)$journal['currency_id'];
|
||||
$currency = $currencies[$currencyId] ?? TransactionCurrency::find($currencyId);
|
||||
$currencies[$currencyId] = $currency; // may just re-assign itself, don't mind.
|
||||
|
||||
// set the array with monetary info, if it does not exist.
|
||||
$data[$currencyId] = $data[$currencyId] ?? [
|
||||
'currency_id' => (string)$currencyId,
|
||||
'currency_symbol' => $journal['currency_symbol'],
|
||||
'currency_code' => $journal['currency_code'],
|
||||
'currency_name' => $journal['currency_name'],
|
||||
'currency_decimal_places' => $journal['currency_decimal_places'],
|
||||
// native currency info (could be the same)
|
||||
'native_id' => (string)$default->id,
|
||||
'native_code' => $default->code,
|
||||
'native_symbol' => $default->symbol,
|
||||
'native_decimal_places' => (int)$default->decimal_places,
|
||||
];
|
||||
|
||||
// set the array (in monetary info) with spent/earned in this $period, if it does not exist.
|
||||
$data[$currencyId][$period] = $data[$currencyId][$period] ?? [
|
||||
'period' => $period,
|
||||
'spent' => '0',
|
||||
'earned' => '0',
|
||||
'native_spent' => '0',
|
||||
'native_earned' => '0',
|
||||
];
|
||||
// is this journal's amount in- our outgoing?
|
||||
$key = 'spent';
|
||||
$amount = app('steam')->negative($journal['amount']);
|
||||
// deposit = incoming
|
||||
// transfer or reconcile or opening balance, and these accounts are the destination.
|
||||
if (
|
||||
TransactionType::DEPOSIT === $journal['transaction_type_type']
|
||||
||
|
||||
|
||||
(
|
||||
(
|
||||
TransactionType::TRANSFER === $journal['transaction_type_type']
|
||||
|| TransactionType::RECONCILIATION === $journal['transaction_type_type']
|
||||
|| TransactionType::OPENING_BALANCE === $journal['transaction_type_type']
|
||||
)
|
||||
&& in_array($journal['destination_account_id'], $ids, true)
|
||||
)
|
||||
) {
|
||||
$key = 'earned';
|
||||
$amount = app('steam')->positive($journal['amount']);
|
||||
}
|
||||
// get conversion rate
|
||||
$rate = $converter->getCurrencyRate($currency, $default, $journal['date']);
|
||||
$amountConverted = bcmul($amount, $rate);
|
||||
|
||||
// perhaps transaction already has the foreign amount in the native currency.
|
||||
if ((int)$journal['foreign_currency_id'] === (int)$default->id) {
|
||||
$amountConverted = $journal['foreign_amount'] ?? '0';
|
||||
$amountConverted = 'earned' === $key ? app('steam')->positive($amountConverted) : app('steam')->negative($amountConverted);
|
||||
}
|
||||
|
||||
// add normal entry
|
||||
$data[$currencyId][$period][$key] = bcadd($data[$currencyId][$period][$key], $amount);
|
||||
|
||||
// add converted entry
|
||||
$convertedKey = sprintf('native_%s', $key);
|
||||
$data[$currencyId][$period][$convertedKey] = bcadd($data[$currencyId][$period][$convertedKey], $amountConverted);
|
||||
}
|
||||
|
||||
// loop this data, make chart bars for each currency:
|
||||
/** @var array $currency */
|
||||
foreach ($data as $currency) {
|
||||
// income and expense array prepped:
|
||||
$income = [
|
||||
'label' => 'earned',
|
||||
'currency_id' => (string)$currency['currency_id'],
|
||||
'currency_symbol' => $currency['currency_symbol'],
|
||||
'currency_code' => $currency['currency_code'],
|
||||
'currency_decimal_places' => $currency['currency_decimal_places'],
|
||||
'native_id' => (string)$currency['native_id'],
|
||||
'native_symbol' => $currency['native_symbol'],
|
||||
'native_code' => $currency['native_code'],
|
||||
'native_decimal_places' => $currency['native_decimal_places'],
|
||||
'start' => $start->toAtomString(),
|
||||
'end' => $end->toAtomString(),
|
||||
'period' => $preferredRange,
|
||||
'entries' => [],
|
||||
'native_entries' => [],
|
||||
];
|
||||
$expense = [
|
||||
'label' => 'spent',
|
||||
'currency_id' => (string)$currency['currency_id'],
|
||||
'currency_symbol' => $currency['currency_symbol'],
|
||||
'currency_code' => $currency['currency_code'],
|
||||
'currency_decimal_places' => $currency['currency_decimal_places'],
|
||||
'native_id' => (string)$currency['native_id'],
|
||||
'native_symbol' => $currency['native_symbol'],
|
||||
'native_code' => $currency['native_code'],
|
||||
'native_decimal_places' => $currency['native_decimal_places'],
|
||||
'start' => $start->toAtomString(),
|
||||
'end' => $end->toAtomString(),
|
||||
'period' => $preferredRange,
|
||||
'entries' => [],
|
||||
'native_entries' => [],
|
||||
|
||||
];
|
||||
// loop all possible periods between $start and $end, and add them to the correct dataset.
|
||||
$currentStart = clone $start;
|
||||
while ($currentStart <= $end) {
|
||||
$key = $currentStart->format($format);
|
||||
$label = $currentStart->toAtomString();
|
||||
// normal entries
|
||||
$income['entries'][$label] = app('steam')->bcround(($currency[$key]['earned'] ?? '0'), $currency['currency_decimal_places']);
|
||||
$expense['entries'][$label] = app('steam')->bcround(($currency[$key]['spent'] ?? '0'), $currency['currency_decimal_places']);
|
||||
|
||||
// converted entries
|
||||
$income['native_entries'][$label] = app('steam')->bcround(($currency[$key]['native_earned'] ?? '0'), $currency['native_decimal_places']);
|
||||
$expense['native_entries'][$label] = app('steam')->bcround(($currency[$key]['native_spent'] ?? '0'), $currency['native_decimal_places']);
|
||||
|
||||
// next loop
|
||||
$currentStart = app('navigation')->addPeriod($currentStart, $preferredRange, 0);
|
||||
}
|
||||
|
||||
$chartData[] = $income;
|
||||
$chartData[] = $expense;
|
||||
}
|
||||
return response()->json($this->clean($chartData));
|
||||
}
|
||||
|
||||
}
|
313
app/Api/V2/Controllers/Chart/BudgetController.php
Normal file
313
app/Api/V2/Controllers/Chart/BudgetController.php
Normal file
@@ -0,0 +1,313 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
/*
|
||||
* BudgetController.php
|
||||
* Copyright (c) 2023 james@firefly-iii.org
|
||||
*
|
||||
* This file is part of Firefly III (https://github.com/firefly-iii).
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
namespace FireflyIII\Api\V2\Controllers\Chart;
|
||||
|
||||
use Carbon\Carbon;
|
||||
use FireflyIII\Api\V2\Controllers\Controller;
|
||||
use FireflyIII\Api\V2\Request\Generic\DateRequest;
|
||||
use FireflyIII\Exceptions\FireflyException;
|
||||
use FireflyIII\Models\Budget;
|
||||
use FireflyIII\Models\BudgetLimit;
|
||||
use FireflyIII\Models\TransactionCurrency;
|
||||
use FireflyIII\Repositories\Administration\Budget\BudgetRepositoryInterface;
|
||||
use FireflyIII\Repositories\Administration\Budget\OperationsRepositoryInterface;
|
||||
use FireflyIII\Repositories\Budget\BudgetLimitRepositoryInterface;
|
||||
use FireflyIII\Support\Http\Api\CleansChartData;
|
||||
use FireflyIII\Support\Http\Api\ExchangeRateConverter;
|
||||
use FireflyIII\User;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Support\Collection;
|
||||
|
||||
/**
|
||||
* Class BudgetController
|
||||
*/
|
||||
class BudgetController extends Controller
|
||||
{
|
||||
use CleansChartData;
|
||||
|
||||
protected OperationsRepositoryInterface $opsRepository;
|
||||
private BudgetLimitRepositoryInterface $blRepository;
|
||||
private array $currencies = [];
|
||||
private TransactionCurrency $currency;
|
||||
private BudgetRepositoryInterface $repository;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
$this->middleware(
|
||||
function ($request, $next) {
|
||||
$this->repository = app(BudgetRepositoryInterface::class);
|
||||
$this->blRepository = app(BudgetLimitRepositoryInterface::class);
|
||||
$this->opsRepository = app(OperationsRepositoryInterface::class);
|
||||
$this->currency = app('amount')->getDefaultCurrency();
|
||||
return $next($request);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param DateRequest $request
|
||||
*
|
||||
* TODO see autocomplete/accountcontroller
|
||||
*
|
||||
* @return JsonResponse
|
||||
* @throws FireflyException
|
||||
*/
|
||||
public function dashboard(DateRequest $request): JsonResponse
|
||||
{
|
||||
// get user.
|
||||
/** @var User $user */
|
||||
$user = auth()->user();
|
||||
// group ID
|
||||
$administrationId = $user->getAdministrationId();
|
||||
$this->repository->setAdministrationId($administrationId);
|
||||
$this->opsRepository->setAdministrationId($administrationId);
|
||||
|
||||
$params = $request->getAll();
|
||||
/** @var Carbon $start */
|
||||
$start = $params['start'];
|
||||
/** @var Carbon $end */
|
||||
$end = $params['end'];
|
||||
|
||||
// code from FrontpageChartGenerator, but not in separate class
|
||||
$budgets = $this->repository->getActiveBudgets();
|
||||
$data = [];
|
||||
/** @var Budget $budget */
|
||||
foreach ($budgets as $budget) {
|
||||
// could return multiple arrays, so merge.
|
||||
$data = array_merge($data, $this->processBudget($budget, $start, $end));
|
||||
}
|
||||
return response()->json($this->clean($data));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Budget $budget
|
||||
* @param Carbon $start
|
||||
* @param Carbon $end
|
||||
*
|
||||
* @return array
|
||||
* @throws FireflyException
|
||||
*/
|
||||
private function processBudget(Budget $budget, Carbon $start, Carbon $end): array
|
||||
{
|
||||
// get all limits:
|
||||
$limits = $this->blRepository->getBudgetLimits($budget, $start, $end);
|
||||
$rows = [];
|
||||
|
||||
// if no limits
|
||||
if (0 === $limits->count()) {
|
||||
// return as a single item in an array
|
||||
$rows = $this->noBudgetLimits($budget, $start, $end);
|
||||
}
|
||||
if ($limits->count() > 0) {
|
||||
$rows = $this->budgetLimits($budget, $limits);
|
||||
}
|
||||
// is always an array
|
||||
$return = [];
|
||||
foreach ($rows as $row) {
|
||||
$current = [
|
||||
'label' => $budget->name,
|
||||
'currency_id' => (string)$row['currency_id'],
|
||||
'currency_code' => $row['currency_code'],
|
||||
'currency_name' => $row['currency_name'],
|
||||
'currency_decimal_places' => $row['currency_decimal_places'],
|
||||
'native_id' => (string)$row['native_id'],
|
||||
'native_code' => $row['native_code'],
|
||||
'native_name' => $row['native_name'],
|
||||
'native_decimal_places' => $row['native_decimal_places'],
|
||||
'period' => null,
|
||||
'start' => $row['start'],
|
||||
'end' => $row['end'],
|
||||
'entries' => [
|
||||
'spent' => $row['spent'],
|
||||
'left' => $row['left'],
|
||||
'overspent' => $row['overspent'],
|
||||
],
|
||||
'native_entries' => [
|
||||
'spent' => $row['native_spent'],
|
||||
'left' => $row['native_left'],
|
||||
'overspent' => $row['native_overspent'],
|
||||
],
|
||||
];
|
||||
$return[] = $current;
|
||||
}
|
||||
return $return;
|
||||
}
|
||||
|
||||
/**
|
||||
* When no budget limits are present, the expenses of the whole period are collected and grouped.
|
||||
* This is grouped per currency. Because there is no limit set, "left to spend" and "overspent" are empty.
|
||||
*
|
||||
* @param Budget $budget
|
||||
* @param Carbon $start
|
||||
* @param Carbon $end
|
||||
*
|
||||
* @return array
|
||||
* @throws FireflyException
|
||||
*/
|
||||
private function noBudgetLimits(Budget $budget, Carbon $start, Carbon $end): array
|
||||
{
|
||||
$budgetId = (int)$budget->id;
|
||||
$spent = $this->opsRepository->listExpenses($start, $end, null, new Collection([$budget]));
|
||||
return $this->processExpenses($budgetId, $spent, $start, $end);
|
||||
}
|
||||
|
||||
/**
|
||||
* Shared between the "noBudgetLimits" function and "processLimit".
|
||||
*
|
||||
* Will take a single set of expenses and return its info.
|
||||
*
|
||||
* @param int $budgetId
|
||||
* @param array $array
|
||||
*
|
||||
* @return array
|
||||
* @throws FireflyException
|
||||
*/
|
||||
private function processExpenses(int $budgetId, array $array, Carbon $start, Carbon $end): array
|
||||
{
|
||||
$converter = new ExchangeRateConverter();
|
||||
$return = [];
|
||||
|
||||
/**
|
||||
* This array contains the expenses in this budget. Grouped per currency.
|
||||
* The grouping is on the main currency only.
|
||||
*
|
||||
* @var int $currencyId
|
||||
* @var array $block
|
||||
*/
|
||||
foreach ($array as $currencyId => $block) {
|
||||
$this->currencies[$currencyId] = $this->currencies[$currencyId] ?? TransactionCurrency::find($currencyId);
|
||||
$return[$currencyId] = $return[$currencyId] ?? [
|
||||
'currency_id' => (string)$currencyId,
|
||||
'currency_code' => $block['currency_code'],
|
||||
'currency_name' => $block['currency_name'],
|
||||
'currency_symbol' => $block['currency_symbol'],
|
||||
'currency_decimal_places' => (int)$block['currency_decimal_places'],
|
||||
'native_id' => (string)$this->currency->id,
|
||||
'native_code' => $this->currency->code,
|
||||
'native_name' => $this->currency->name,
|
||||
'native_symbol' => $this->currency->symbol,
|
||||
'native_decimal_places' => (int)$this->currency->decimal_places,
|
||||
'start' => $start->toAtomString(),
|
||||
'end' => $end->toAtomString(),
|
||||
'spent' => '0',
|
||||
'native_spent' => '0',
|
||||
'left' => '0',
|
||||
'native_left' => '0',
|
||||
'overspent' => '0',
|
||||
'native_overspent' => '0',
|
||||
|
||||
];
|
||||
$currentBudgetArray = $block['budgets'][$budgetId];
|
||||
//var_dump($return);
|
||||
/** @var array $journal */
|
||||
foreach ($currentBudgetArray['transaction_journals'] as $journal) {
|
||||
|
||||
// convert the amount to the native currency.
|
||||
$rate = $converter->getCurrencyRate($this->currencies[$currencyId], $this->currency, $journal['date']);
|
||||
$convertedAmount = bcmul($journal['amount'], $rate);
|
||||
if ($journal['foreign_currency_id'] === $this->currency->id) {
|
||||
$convertedAmount = $journal['foreign_amount'];
|
||||
}
|
||||
|
||||
$return[$currencyId]['spent'] = bcadd($return[$currencyId]['spent'], $journal['amount']);
|
||||
$return[$currencyId]['native_spent'] = bcadd($return[$currencyId]['native_spent'], $convertedAmount);
|
||||
}
|
||||
}
|
||||
return $return;
|
||||
}
|
||||
|
||||
/**
|
||||
* Function that processes each budget limit (per budget).
|
||||
*
|
||||
* If you have a budget limit in EUR, only transactions in EUR will be considered.
|
||||
* If you have a budget limit in GBP, only transactions in GBP will be considered.
|
||||
*
|
||||
* If you have a budget limit in EUR, and a transaction in GBP, it will not be considered for the EUR budget limit.
|
||||
*
|
||||
* @param Budget $budget
|
||||
* @param Collection $limits
|
||||
*
|
||||
* @return array
|
||||
* @throws FireflyException
|
||||
*/
|
||||
private function budgetLimits(Budget $budget, Collection $limits): array
|
||||
{
|
||||
app('log')->debug(sprintf('Now in budgetLimits(#%d)', $budget->id));
|
||||
$data = [];
|
||||
/** @var BudgetLimit $limit */
|
||||
foreach ($limits as $limit) {
|
||||
$data = array_merge($data, $this->processLimit($budget, $limit));
|
||||
}
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Budget $budget
|
||||
* @param BudgetLimit $limit
|
||||
*
|
||||
* @return array
|
||||
* @throws FireflyException
|
||||
*/
|
||||
private function processLimit(Budget $budget, BudgetLimit $limit): array
|
||||
{
|
||||
$budgetId = (int)$budget->id;
|
||||
$end = clone $limit->end_date;
|
||||
$end->endOfDay();
|
||||
$spent = $this->opsRepository->listExpenses($limit->start_date, $end, null, new Collection([$budget]));
|
||||
$limitCurrencyId = (int)$limit->transaction_currency_id;
|
||||
$limitCurrency = $limit->transactionCurrency;
|
||||
$converter = new ExchangeRateConverter();
|
||||
$filtered = [];
|
||||
$rate = $converter->getCurrencyRate($limitCurrency, $this->currency, $limit->start_date);
|
||||
$convertedLimitAmount = bcmul($limit->amount, $rate);
|
||||
|
||||
|
||||
/** @var array $entry */
|
||||
foreach ($spent as $currencyId => $entry) {
|
||||
// only spent the entry where the entry's currency matches the budget limit's currency
|
||||
// so $filtered will only have 1 or 0 entries
|
||||
if ($entry['currency_id'] === $limitCurrencyId) {
|
||||
$filtered[$currencyId] = $entry;
|
||||
}
|
||||
}
|
||||
$result = $this->processExpenses($budgetId, $filtered, $limit->start_date, $end);
|
||||
if (1 === count($result)) {
|
||||
$compare = bccomp((string)$limit->amount, app('steam')->positive($result[$limitCurrencyId]['spent']));
|
||||
if (1 === $compare) {
|
||||
// convert this amount into the native currency:
|
||||
$result[$limitCurrencyId]['left'] = bcadd($limit->amount, $result[$limitCurrencyId]['spent']);
|
||||
$result[$limitCurrencyId]['native_left'] = bcadd($convertedLimitAmount, $result[$limitCurrencyId]['native_spent']);
|
||||
}
|
||||
if ($compare <= 0) {
|
||||
$result[$limitCurrencyId]['overspent'] = app('steam')->positive(bcadd($limit->amount, $result[$limitCurrencyId]['spent']));
|
||||
$result[$limitCurrencyId]['native_overspent'] = app('steam')->positive(bcadd($convertedLimitAmount, $result[$limitCurrencyId]['native_spent']));
|
||||
}
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
|
||||
}
|
137
app/Api/V2/Controllers/Chart/CategoryController.php
Normal file
137
app/Api/V2/Controllers/Chart/CategoryController.php
Normal file
@@ -0,0 +1,137 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
/*
|
||||
* BudgetController.php
|
||||
* Copyright (c) 2023 james@firefly-iii.org
|
||||
*
|
||||
* This file is part of Firefly III (https://github.com/firefly-iii).
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
namespace FireflyIII\Api\V2\Controllers\Chart;
|
||||
|
||||
use Carbon\Carbon;
|
||||
use FireflyIII\Api\V2\Controllers\Controller;
|
||||
use FireflyIII\Api\V2\Request\Generic\DateRequest;
|
||||
use FireflyIII\Exceptions\FireflyException;
|
||||
use FireflyIII\Helpers\Collector\GroupCollectorInterface;
|
||||
use FireflyIII\Models\AccountType;
|
||||
use FireflyIII\Models\TransactionType;
|
||||
use FireflyIII\Repositories\Administration\Account\AccountRepositoryInterface;
|
||||
use FireflyIII\Repositories\Currency\CurrencyRepositoryInterface;
|
||||
use FireflyIII\Support\Http\Api\CleansChartData;
|
||||
use FireflyIII\Support\Http\Api\ExchangeRateConverter;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
|
||||
/**
|
||||
* Class BudgetController
|
||||
*/
|
||||
class CategoryController extends Controller
|
||||
{
|
||||
use CleansChartData;
|
||||
|
||||
private AccountRepositoryInterface $accountRepos;
|
||||
private CurrencyRepositoryInterface $currencyRepos;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
$this->middleware(
|
||||
function ($request, $next) {
|
||||
$this->accountRepos = app(AccountRepositoryInterface::class);
|
||||
$this->currencyRepos = app(CurrencyRepositoryInterface::class);
|
||||
$this->accountRepos->setAdministrationId(auth()->user()->user_group_id);
|
||||
return $next($request);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* TODO may be worth to move to a handler but the data is simple enough.
|
||||
* TODO see autoComplete/account controller
|
||||
*
|
||||
* @param DateRequest $request
|
||||
*
|
||||
* @return JsonResponse
|
||||
* @throws FireflyException
|
||||
*/
|
||||
public function dashboard(DateRequest $request): JsonResponse
|
||||
{
|
||||
/** @var Carbon $start */
|
||||
$start = $this->parameters->get('start');
|
||||
/** @var Carbon $end */
|
||||
$end = $this->parameters->get('end');
|
||||
$accounts = $this->accountRepos->getAccountsByType([AccountType::DEBT, AccountType::LOAN, AccountType::MORTGAGE, AccountType::ASSET, AccountType::DEFAULT]);
|
||||
$default = app('amount')->getDefaultCurrency();
|
||||
$converter = new ExchangeRateConverter();
|
||||
$currencies = [];
|
||||
$return = [];
|
||||
|
||||
// get journals for entire period:
|
||||
/** @var GroupCollectorInterface $collector */
|
||||
$collector = app(GroupCollectorInterface::class);
|
||||
$collector->setRange($start, $end)->withAccountInformation();
|
||||
$collector->setXorAccounts($accounts)->withCategoryInformation();
|
||||
$collector->setTypes([TransactionType::WITHDRAWAL, TransactionType::RECONCILIATION]);
|
||||
$journals = $collector->getExtractedJournals();
|
||||
|
||||
/** @var array $journal */
|
||||
foreach ($journals as $journal) {
|
||||
$currencyId = (int)$journal['currency_id'];
|
||||
$currency = $currencies[$currencyId] ?? $this->currencyRepos->find($currencyId);
|
||||
$currencies[$currencyId] = $currency;
|
||||
$categoryName = null === $journal['category_name'] ? (string)trans('firefly.no_category') : $journal['category_name'];
|
||||
$amount = app('steam')->positive($journal['amount']);
|
||||
$nativeAmount = $converter->convert($default, $currency, $journal['date'], $amount);
|
||||
$key = sprintf('%s-%s', $categoryName, $currency->code);
|
||||
if ((int)$journal['foreign_currency_id'] === (int)$default->id) {
|
||||
$nativeAmount = app('steam')->positive($journal['foreign_amount']);
|
||||
}
|
||||
// create arrays
|
||||
$return[$key] = $return[$key] ?? [
|
||||
'label' => $categoryName,
|
||||
'currency_id' => (string)$currency->id,
|
||||
'currency_code' => $currency->code,
|
||||
'currency_name' => $currency->name,
|
||||
'currency_symbol' => $currency->symbol,
|
||||
'currency_decimal_places' => (int)$currency->decimal_places,
|
||||
'native_id' => (string)$default->id,
|
||||
'native_code' => $default->code,
|
||||
'native_name' => $default->name,
|
||||
'native_symbol' => $default->symbol,
|
||||
'native_decimal_places' => (int)$default->decimal_places,
|
||||
'period' => null,
|
||||
'start' => $start->toAtomString(),
|
||||
'end' => $end->toAtomString(),
|
||||
'amount' => '0',
|
||||
'native_amount' => '0',
|
||||
];
|
||||
|
||||
|
||||
// add monies
|
||||
$return[$key]['amount'] = bcadd($return[$key]['amount'], $amount);
|
||||
$return[$key]['native_amount'] = bcadd($return[$key]['native_amount'], $nativeAmount);
|
||||
}
|
||||
$return = array_values($return);
|
||||
|
||||
// order by native amount
|
||||
usort($return, function (array $a, array $b) {
|
||||
return (float)$a['native_amount'] < (float)$b['native_amount'] ? 1 : -1;
|
||||
});
|
||||
return response()->json($this->clean($return));
|
||||
}
|
||||
|
||||
}
|
@@ -93,21 +93,26 @@ class Controller extends BaseController
|
||||
// some date fields:
|
||||
foreach ($dates as $field) {
|
||||
$date = null;
|
||||
$obj = null;
|
||||
try {
|
||||
$date = request()->query->get($field);
|
||||
} catch (BadRequestException $e) {
|
||||
Log::error(sprintf('Request field "%s" contains a non-scalar value. Value set to NULL.', $field));
|
||||
Log::error($e->getMessage());
|
||||
$value = null;
|
||||
Log::error($e->getTraceAsString());
|
||||
}
|
||||
$obj = null;
|
||||
if (null !== $date) {
|
||||
try {
|
||||
$obj = Carbon::parse($date);
|
||||
$obj = Carbon::parse($date, config('app.timezone'));
|
||||
} catch (InvalidDateException | InvalidFormatException $e) {
|
||||
// don't care
|
||||
app('log')->warning(sprintf('Ignored invalid date "%s" in API v2 controller parameter check: %s', substr($date, 0, 20), $e->getMessage()));
|
||||
}
|
||||
// out of range? set to null.
|
||||
if (null !== $obj && ($obj->year <= 1900 || $obj->year > 2099)) {
|
||||
app('log')->warning(sprintf('Refuse to use date "%s" in API v2 controller parameter check: %s', $field, $obj->toAtomString()));
|
||||
$obj = null;
|
||||
}
|
||||
}
|
||||
$bag->set($field, $obj);
|
||||
}
|
||||
@@ -148,7 +153,7 @@ class Controller extends BaseController
|
||||
$objects = $paginator->getCollection();
|
||||
|
||||
// the transformer, at this point, needs to collect information that ALL items in the collection
|
||||
// require, like meta data and stuff like that, and save it for later.
|
||||
// require, like meta-data and stuff like that, and save it for later.
|
||||
$transformer->collectMetaData($objects);
|
||||
|
||||
$resource = new FractalCollection($objects, $transformer, $key);
|
||||
|
89
app/Api/V2/Controllers/Model/Bill/ShowController.php
Normal file
89
app/Api/V2/Controllers/Model/Bill/ShowController.php
Normal file
@@ -0,0 +1,89 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
/*
|
||||
* ShowController.php
|
||||
* Copyright (c) 2023 james@firefly-iii.org
|
||||
*
|
||||
* This file is part of Firefly III (https://github.com/firefly-iii).
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
namespace FireflyIII\Api\V2\Controllers\Model\Bill;
|
||||
|
||||
use FireflyIII\Api\V2\Controllers\Controller;
|
||||
use FireflyIII\Models\Bill;
|
||||
use FireflyIII\Repositories\Administration\Bill\BillRepositoryInterface;
|
||||
use FireflyIII\Transformers\V2\AccountTransformer;
|
||||
use FireflyIII\Transformers\V2\BillTransformer;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Pagination\LengthAwarePaginator;
|
||||
|
||||
/**
|
||||
* Class ShowController
|
||||
*/
|
||||
class ShowController extends Controller
|
||||
{
|
||||
private BillRepositoryInterface $repository;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
$this->middleware(
|
||||
function ($request, $next) {
|
||||
$this->repository = app(BillRepositoryInterface::class);
|
||||
$this->repository->setAdministrationId(auth()->user()->user_group_id);
|
||||
return $next($request);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Request $request
|
||||
*
|
||||
* TODO see autocomplete/accountcontroller for list.
|
||||
*
|
||||
* @return JsonResponse
|
||||
*/
|
||||
public function index(Request $request): JsonResponse
|
||||
{
|
||||
$this->repository->correctOrder();
|
||||
$bills = $this->repository->getBills();
|
||||
$pageSize = (int)app('preferences')->getForUser(auth()->user(), 'listPageSize', 50)->data;
|
||||
$count = $bills->count();
|
||||
$bills = $bills->slice(($this->parameters->get('page') - 1) * $pageSize, $pageSize);
|
||||
$paginator = new LengthAwarePaginator($bills, $count, $pageSize, $this->parameters->get('page'));
|
||||
$transformer = new BillTransformer();
|
||||
$transformer->setParameters($this->parameters); // give params to transformer
|
||||
|
||||
return response()
|
||||
->json($this->jsonApiList('subscriptions', $paginator, $transformer))
|
||||
->header('Content-Type', self::CONTENT_TYPE);
|
||||
}
|
||||
|
||||
/**
|
||||
* TODO this endpoint is not documented
|
||||
*/
|
||||
public function show(Request $request, Bill $bill): JsonResponse
|
||||
{
|
||||
$transformer = new BillTransformer();
|
||||
$transformer->setParameters($this->parameters);
|
||||
|
||||
return response()
|
||||
->api($this->jsonApiObject('subscriptions', $bill, $transformer))
|
||||
->header('Content-Type', self::CONTENT_TYPE);
|
||||
}
|
||||
}
|
@@ -26,8 +26,7 @@ namespace FireflyIII\Api\V2\Controllers\Model\Bill;
|
||||
|
||||
use FireflyIII\Api\V2\Controllers\Controller;
|
||||
use FireflyIII\Api\V2\Request\Generic\DateRequest;
|
||||
use FireflyIII\Repositories\Bill\BillRepositoryInterface;
|
||||
use FireflyIII\Support\Http\Api\ConvertsExchangeRates;
|
||||
use FireflyIII\Repositories\Administration\Bill\BillRepositoryInterface;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
|
||||
/**
|
||||
@@ -35,8 +34,6 @@ use Illuminate\Http\JsonResponse;
|
||||
*/
|
||||
class SumController extends Controller
|
||||
{
|
||||
use ConvertsExchangeRates;
|
||||
|
||||
private BillRepositoryInterface $repository;
|
||||
|
||||
/**
|
||||
@@ -58,35 +55,37 @@ class SumController extends Controller
|
||||
* This endpoint is documented at:
|
||||
* https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v2)#/transactions-sum/getBillsPaidTrSum
|
||||
*
|
||||
* TODO see autocomplete/accountcontroller for list.
|
||||
*
|
||||
* @param DateRequest $request
|
||||
*
|
||||
* @return JsonResponse
|
||||
*/
|
||||
public function paid(DateRequest $request): JsonResponse
|
||||
{
|
||||
$dates = $request->getAll();
|
||||
$result = $this->repository->sumPaidInRange($dates['start'], $dates['end']);
|
||||
$converted = $this->cerSum($result);
|
||||
$this->repository->setAdministrationId(auth()->user()->user_group_id);
|
||||
$result = $this->repository->sumPaidInRange($this->parameters->get('start'), $this->parameters->get('end'));
|
||||
|
||||
// convert to JSON response:
|
||||
return response()->api($converted);
|
||||
return response()->api(array_values($result));
|
||||
}
|
||||
|
||||
/**
|
||||
* This endpoint is documented at:
|
||||
* https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v2)#/transactions-sum/getBillsUnpaidTrSum
|
||||
*
|
||||
* TODO see autocomplete/accountcontroller for list.
|
||||
*
|
||||
* @param DateRequest $request
|
||||
*
|
||||
* @return JsonResponse
|
||||
*/
|
||||
public function unpaid(DateRequest $request): JsonResponse
|
||||
{
|
||||
$dates = $request->getAll();
|
||||
$result = $this->repository->sumUnpaidInRange($dates['start'], $dates['end']);
|
||||
$converted = $this->cerSum($result);
|
||||
$this->repository->setAdministrationId(auth()->user()->user_group_id);
|
||||
$result = $this->repository->sumUnpaidInRange($this->parameters->get('start'), $this->parameters->get('end'));
|
||||
|
||||
// convert to JSON response:
|
||||
return response()->api($converted);
|
||||
return response()->api(array_values($result));
|
||||
}
|
||||
}
|
||||
|
@@ -31,6 +31,9 @@ use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Pagination\LengthAwarePaginator;
|
||||
|
||||
/**
|
||||
* Class ListController
|
||||
*/
|
||||
class ListController extends Controller
|
||||
{
|
||||
private BudgetRepositoryInterface $repository;
|
||||
@@ -57,6 +60,8 @@ class ListController extends Controller
|
||||
*/
|
||||
public function index(Request $request): JsonResponse
|
||||
{
|
||||
echo 'this needs move to Administration';
|
||||
exit;
|
||||
$collection = $this->repository->getActiveBudgets();
|
||||
$total = $collection->count();
|
||||
$collection->slice($this->pageSize * $this->parameters->get('page'), $this->pageSize);
|
||||
|
@@ -1,6 +1,6 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
/*
|
||||
* ShowController.php
|
||||
* Copyright (c) 2023 james@firefly-iii.org
|
||||
@@ -21,13 +21,14 @@ declare(strict_types=1);
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace FireflyIII\Api\V2\Controllers\Model\Budget;
|
||||
|
||||
use FireflyIII\Api\V2\Controllers\Controller;
|
||||
use FireflyIII\Api\V2\Request\Generic\DateRequest;
|
||||
use FireflyIII\Models\Budget;
|
||||
use FireflyIII\Repositories\Budget\BudgetRepositoryInterface;
|
||||
use FireflyIII\Support\Http\Api\ConvertsExchangeRates;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
|
||||
/**
|
||||
@@ -35,8 +36,6 @@ use Illuminate\Http\JsonResponse;
|
||||
*/
|
||||
class ShowController extends Controller
|
||||
{
|
||||
use ConvertsExchangeRates;
|
||||
|
||||
private BudgetRepositoryInterface $repository;
|
||||
|
||||
/**
|
||||
@@ -61,6 +60,7 @@ class ShowController extends Controller
|
||||
*/
|
||||
public function budgeted(DateRequest $request, Budget $budget): JsonResponse
|
||||
{
|
||||
die('deprecated use of thing.');
|
||||
$data = $request->getAll();
|
||||
$result = $this->repository->budgetedInPeriodForBudget($budget, $data['start'], $data['end']);
|
||||
$converted = $this->cerSum(array_values($result));
|
||||
@@ -75,6 +75,7 @@ class ShowController extends Controller
|
||||
*/
|
||||
public function spent(DateRequest $request, Budget $budget): JsonResponse
|
||||
{
|
||||
die('deprecated use of thing.');
|
||||
$data = $request->getAll();
|
||||
$result = $this->repository->spentInPeriodForBudget($budget, $data['start'], $data['end']);
|
||||
$converted = $this->cerSum(array_values($result));
|
||||
|
@@ -27,7 +27,6 @@ namespace FireflyIII\Api\V2\Controllers\Model\Budget;
|
||||
use FireflyIII\Api\V2\Controllers\Controller;
|
||||
use FireflyIII\Api\V2\Request\Generic\DateRequest;
|
||||
use FireflyIII\Repositories\Budget\BudgetRepositoryInterface;
|
||||
use FireflyIII\Support\Http\Api\ConvertsExchangeRates;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
|
||||
/**
|
||||
@@ -35,8 +34,6 @@ use Illuminate\Http\JsonResponse;
|
||||
*/
|
||||
class SumController extends Controller
|
||||
{
|
||||
use ConvertsExchangeRates;
|
||||
|
||||
private BudgetRepositoryInterface $repository;
|
||||
|
||||
/**
|
||||
@@ -64,6 +61,7 @@ class SumController extends Controller
|
||||
*/
|
||||
public function budgeted(DateRequest $request): JsonResponse
|
||||
{
|
||||
die('deprecated use of thing.');
|
||||
$data = $request->getAll();
|
||||
$result = $this->repository->budgetedInPeriod($data['start'], $data['end']);
|
||||
$converted = $this->cerSum(array_values($result));
|
||||
@@ -81,6 +79,7 @@ class SumController extends Controller
|
||||
*/
|
||||
public function spent(DateRequest $request): JsonResponse
|
||||
{
|
||||
die('deprecated use of thing.');
|
||||
$data = $request->getAll();
|
||||
$result = $this->repository->spentInPeriod($data['start'], $data['end']);
|
||||
$converted = $this->cerSum(array_values($result));
|
||||
|
@@ -32,6 +32,9 @@ use FireflyIII\Transformers\V2\BudgetLimitTransformer;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Pagination\LengthAwarePaginator;
|
||||
|
||||
/**
|
||||
* Class ListController
|
||||
*/
|
||||
class ListController extends Controller
|
||||
{
|
||||
private BudgetLimitRepositoryInterface $repository;
|
||||
|
73
app/Api/V2/Controllers/Model/PiggyBank/ShowController.php
Normal file
73
app/Api/V2/Controllers/Model/PiggyBank/ShowController.php
Normal file
@@ -0,0 +1,73 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
/*
|
||||
* ShowController.php
|
||||
* Copyright (c) 2023 james@firefly-iii.org
|
||||
*
|
||||
* This file is part of Firefly III (https://github.com/firefly-iii).
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
namespace FireflyIII\Api\V2\Controllers\Model\PiggyBank;
|
||||
|
||||
use FireflyIII\Api\V2\Controllers\Controller;
|
||||
use FireflyIII\Repositories\Administration\PiggyBank\PiggyBankRepositoryInterface;
|
||||
use FireflyIII\Transformers\V2\PiggyBankTransformer;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Pagination\LengthAwarePaginator;
|
||||
|
||||
/**
|
||||
* Class ShowController
|
||||
*/
|
||||
class ShowController extends Controller
|
||||
{
|
||||
private PiggyBankRepositoryInterface $repository;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
$this->middleware(
|
||||
function ($request, $next) {
|
||||
$this->repository = app(PiggyBankRepositoryInterface::class);
|
||||
$this->repository->setAdministrationId(auth()->user()->user_group_id);
|
||||
return $next($request);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Request $request
|
||||
*
|
||||
* TODO see autocomplete/accountcontroller for list.
|
||||
*
|
||||
* @return JsonResponse
|
||||
*/
|
||||
public function index(Request $request): JsonResponse
|
||||
{
|
||||
$piggies = $this->repository->getPiggyBanks();
|
||||
$pageSize = (int)app('preferences')->getForUser(auth()->user(), 'listPageSize', 50)->data;
|
||||
$count = $piggies->count();
|
||||
$piggies = $piggies->slice(($this->parameters->get('page') - 1) * $pageSize, $pageSize);
|
||||
$paginator = new LengthAwarePaginator($piggies, $count, $pageSize, $this->parameters->get('page'));
|
||||
$transformer = new PiggyBankTransformer();
|
||||
$transformer->setParameters($this->parameters); // give params to transformer
|
||||
|
||||
return response()
|
||||
->json($this->jsonApiList('piggy-banks', $paginator, $transformer))
|
||||
->header('Content-Type', self::CONTENT_TYPE);
|
||||
}
|
||||
}
|
45
app/Api/V2/Controllers/Model/Transaction/StoreController.php
Normal file
45
app/Api/V2/Controllers/Model/Transaction/StoreController.php
Normal file
@@ -0,0 +1,45 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
/*
|
||||
* StoreController.php
|
||||
* Copyright (c) 2023 james@firefly-iii.org
|
||||
*
|
||||
* This file is part of Firefly III (https://github.com/firefly-iii).
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
namespace FireflyIII\Api\V2\Controllers\Model\Transaction;
|
||||
|
||||
use FireflyIII\Api\V2\Controllers\Controller;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
|
||||
/**
|
||||
* Class StoreController
|
||||
*/
|
||||
class StoreController extends Controller
|
||||
{
|
||||
/**
|
||||
* @return JsonResponse
|
||||
*/
|
||||
public function post(): JsonResponse
|
||||
{
|
||||
|
||||
return response()->json([]);
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
@@ -26,7 +26,6 @@ namespace FireflyIII\Api\V2\Controllers;
|
||||
|
||||
use FireflyIII\Api\V2\Request\Generic\SingleDateRequest;
|
||||
use FireflyIII\Helpers\Report\NetWorthInterface;
|
||||
use FireflyIII\Support\Http\Api\ConvertsExchangeRates;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
|
||||
/**
|
||||
@@ -34,8 +33,6 @@ use Illuminate\Http\JsonResponse;
|
||||
*/
|
||||
class NetWorthController extends Controller
|
||||
{
|
||||
use ConvertsExchangeRates;
|
||||
|
||||
private NetWorthInterface $netWorth;
|
||||
|
||||
/**
|
||||
@@ -64,6 +61,7 @@ class NetWorthController extends Controller
|
||||
*/
|
||||
public function get(SingleDateRequest $request): JsonResponse
|
||||
{
|
||||
die('deprecated use of thing.');
|
||||
$date = $request->getDate();
|
||||
$result = $this->netWorth->sumNetWorthByCurrency($date);
|
||||
$converted = $this->cerSum($result);
|
||||
|
552
app/Api/V2/Controllers/Summary/BasicController.php
Normal file
552
app/Api/V2/Controllers/Summary/BasicController.php
Normal file
@@ -0,0 +1,552 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* SummaryController.php
|
||||
* Copyright (c) 2021 james@firefly-iii.org
|
||||
*
|
||||
* This file is part of Firefly III (https://github.com/firefly-iii).
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace FireflyIII\Api\V2\Controllers\Summary;
|
||||
|
||||
use Carbon\Carbon;
|
||||
use Exception;
|
||||
use FireflyIII\Api\V2\Controllers\Controller;
|
||||
use FireflyIII\Api\V2\Request\Generic\DateRequest;
|
||||
use FireflyIII\Exceptions\FireflyException;
|
||||
use FireflyIII\Helpers\Collector\GroupCollectorInterface;
|
||||
use FireflyIII\Helpers\Report\NetWorthInterface;
|
||||
use FireflyIII\Models\Account;
|
||||
use FireflyIII\Models\AccountType;
|
||||
use FireflyIII\Models\TransactionCurrency;
|
||||
use FireflyIII\Models\TransactionType;
|
||||
use FireflyIII\Models\UserGroup;
|
||||
use FireflyIII\Repositories\Administration\Account\AccountRepositoryInterface;
|
||||
use FireflyIII\Repositories\Administration\Bill\BillRepositoryInterface;
|
||||
use FireflyIII\Repositories\Administration\Budget\AvailableBudgetRepositoryInterface;
|
||||
use FireflyIII\Repositories\Administration\Budget\BudgetRepositoryInterface;
|
||||
use FireflyIII\Repositories\Administration\Budget\OperationsRepositoryInterface;
|
||||
use FireflyIII\Repositories\Currency\CurrencyRepositoryInterface;
|
||||
use FireflyIII\Support\Http\Api\ExchangeRateConverter;
|
||||
use FireflyIII\User;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
|
||||
/**
|
||||
* Class BasicController
|
||||
*/
|
||||
class BasicController extends Controller
|
||||
{
|
||||
private AvailableBudgetRepositoryInterface $abRepository;
|
||||
private AccountRepositoryInterface $accountRepository;
|
||||
private BillRepositoryInterface $billRepository;
|
||||
private BudgetRepositoryInterface $budgetRepository;
|
||||
private CurrencyRepositoryInterface $currencyRepos;
|
||||
private OperationsRepositoryInterface $opsRepository;
|
||||
|
||||
/**
|
||||
* BasicController constructor.
|
||||
*
|
||||
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
$this->middleware(
|
||||
function ($request, $next) {
|
||||
/** @var User $user */
|
||||
$user = auth()->user();
|
||||
$this->abRepository = app(AvailableBudgetRepositoryInterface::class);
|
||||
$this->accountRepository = app(AccountRepositoryInterface::class);
|
||||
$this->billRepository = app(BillRepositoryInterface::class);
|
||||
$this->budgetRepository = app(BudgetRepositoryInterface::class);
|
||||
$this->currencyRepos = app(CurrencyRepositoryInterface::class);
|
||||
$this->opsRepository = app(OperationsRepositoryInterface::class);
|
||||
|
||||
$this->abRepository->setAdministrationId($user->user_group_id);
|
||||
$this->accountRepository->setAdministrationId($user->user_group_id);
|
||||
$this->billRepository->setAdministrationId($user->user_group_id);
|
||||
$this->budgetRepository->setAdministrationId($user->user_group_id);
|
||||
$this->currencyRepos->setUser($user);
|
||||
$this->opsRepository->setAdministrationId($user->user_group_id);
|
||||
|
||||
return $next($request);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* This endpoint is documented at:
|
||||
* https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v2)#/summary/getBasicSummary
|
||||
*
|
||||
* @param DateRequest $request
|
||||
*
|
||||
* @return JsonResponse
|
||||
* @throws Exception
|
||||
*/
|
||||
public function basic(DateRequest $request): JsonResponse
|
||||
{
|
||||
// parameters for boxes:
|
||||
$start = $this->parameters->get('start');
|
||||
$end = $this->parameters->get('end');
|
||||
|
||||
// balance information:
|
||||
$balanceData = $this->getBalanceInformation($start, $end);
|
||||
$billData = $this->getBillInformation($start, $end);
|
||||
$spentData = $this->getLeftToSpendInfo($start, $end);
|
||||
$netWorthData = $this->getNetWorthInfo($start, $end);
|
||||
$total = array_merge($balanceData, $billData, $spentData, $netWorthData);
|
||||
return response()->json($total);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Carbon $start
|
||||
* @param Carbon $end
|
||||
*
|
||||
* @return array
|
||||
* @throws FireflyException
|
||||
*/
|
||||
private function getBalanceInformation(Carbon $start, Carbon $end): array
|
||||
{
|
||||
// prep some arrays:
|
||||
$incomes = [
|
||||
'native' => '0',
|
||||
];
|
||||
$expenses = [
|
||||
'native' => '0',
|
||||
];
|
||||
$sums = [
|
||||
'native' => '0',
|
||||
];
|
||||
$return = [];
|
||||
$currencies = [];
|
||||
$converter = new ExchangeRateConverter();
|
||||
$default = app('amount')->getDefaultCurrency();
|
||||
/** @var User $user */
|
||||
$user = auth()->user();
|
||||
|
||||
// collect income of user using the new group collector.
|
||||
/** @var GroupCollectorInterface $collector */
|
||||
$collector = app(GroupCollectorInterface::class);
|
||||
$collector
|
||||
->setRange($start, $end)
|
||||
->setUserGroup($user->userGroup)
|
||||
// set page to retrieve
|
||||
->setPage($this->parameters->get('page'))
|
||||
// set types of transactions to return.
|
||||
->setTypes([TransactionType::DEPOSIT])
|
||||
->setRange($start, $end);
|
||||
|
||||
$set = $collector->getExtractedJournals();
|
||||
/** @var array $transactionJournal */
|
||||
foreach ($set as $transactionJournal) {
|
||||
// transaction info:
|
||||
$currencyId = (int)$transactionJournal['currency_id'];
|
||||
$amount = bcmul($transactionJournal['amount'], '-1');
|
||||
$currency = $currencies[$currencyId] ?? TransactionCurrency::find($currencyId);
|
||||
$currencies[$currencyId] = $currency;
|
||||
$nativeAmount = $converter->convert($currency, $default, $transactionJournal['date'], $amount);
|
||||
if ((int)$transactionJournal['foreign_currency_id'] === (int)$default->id) {
|
||||
// use foreign amount instead
|
||||
$nativeAmount = $transactionJournal['foreign_amount'];
|
||||
}
|
||||
// prep the arrays
|
||||
$incomes[$currencyId] = $incomes[$currencyId] ?? '0';
|
||||
$incomes['native'] = $incomes['native'] ?? '0';
|
||||
$sums[$currencyId] = $sums[$currencyId] ?? '0';
|
||||
$sums['native'] = $sums['native'] ?? '0';
|
||||
|
||||
// add values:
|
||||
$incomes[$currencyId] = bcadd($incomes[$currencyId], $amount);
|
||||
$sums[$currencyId] = bcadd($sums[$currencyId], $amount);
|
||||
$incomes['native'] = bcadd($incomes['native'], $nativeAmount);
|
||||
$sums['native'] = bcadd($sums['native'], $nativeAmount);
|
||||
}
|
||||
|
||||
// collect expenses of user using the new group collector.
|
||||
/** @var GroupCollectorInterface $collector */
|
||||
$collector = app(GroupCollectorInterface::class);
|
||||
$collector
|
||||
->setRange($start, $end)
|
||||
->setUserGroup($user->userGroup)
|
||||
// set page to retrieve
|
||||
->setPage($this->parameters->get('page'))
|
||||
// set types of transactions to return.
|
||||
->setTypes([TransactionType::WITHDRAWAL])
|
||||
->setRange($start, $end);
|
||||
$set = $collector->getExtractedJournals();
|
||||
|
||||
/** @var array $transactionJournal */
|
||||
foreach ($set as $transactionJournal) {
|
||||
// transaction info
|
||||
$currencyId = (int)$transactionJournal['currency_id'];
|
||||
$amount = $transactionJournal['amount'];
|
||||
$currency = $currencies[$currencyId] ?? $this->currencyRepos->find($currencyId);
|
||||
$currencies[$currencyId] = $currency;
|
||||
$nativeAmount = $converter->convert($currency, $default, $transactionJournal['date'], $amount);
|
||||
if ((int)$transactionJournal['foreign_currency_id'] === (int)$default->id) {
|
||||
// use foreign amount instead
|
||||
$nativeAmount = $transactionJournal['foreign_amount'];
|
||||
}
|
||||
|
||||
// prep arrays
|
||||
$expenses[$currencyId] = $expenses[$currencyId] ?? '0';
|
||||
$expenses['native'] = $expenses['native'] ?? '0';
|
||||
$sums[$currencyId] = $sums[$currencyId] ?? '0';
|
||||
$sums['native'] = $sums['native'] ?? '0';
|
||||
|
||||
// add values
|
||||
$expenses[$currencyId] = bcadd($expenses[$currencyId], $amount);
|
||||
$sums[$currencyId] = bcadd($sums[$currencyId], $amount);
|
||||
$expenses['native'] = bcadd($expenses['native'], $nativeAmount);
|
||||
$sums['native'] = bcadd($sums['native'], $nativeAmount);
|
||||
}
|
||||
|
||||
// create special array for native currency:
|
||||
$return[] = [
|
||||
'key' => 'balance-in-native',
|
||||
'value' => $sums['native'],
|
||||
'currency_id' => (string)$default->id,
|
||||
'currency_code' => $default->code,
|
||||
'currency_symbol' => $default->symbol,
|
||||
'currency_decimal_places' => $default->decimal_places,
|
||||
];
|
||||
$return[] = [
|
||||
'key' => 'spent-in-native',
|
||||
'value' => $expenses['native'],
|
||||
'currency_id' => (string)$default->id,
|
||||
'currency_code' => $default->code,
|
||||
'currency_symbol' => $default->symbol,
|
||||
'currency_decimal_places' => $default->decimal_places,
|
||||
];
|
||||
$return[] = [
|
||||
'key' => 'earned-in-native',
|
||||
'value' => $incomes['native'],
|
||||
'currency_id' => (string)$default->id,
|
||||
'currency_code' => $default->code,
|
||||
'currency_symbol' => $default->symbol,
|
||||
'currency_decimal_places' => $default->decimal_places,
|
||||
];
|
||||
|
||||
// format amounts:
|
||||
$keys = array_keys($sums);
|
||||
foreach ($keys as $currencyId) {
|
||||
if ('native' === $currencyId) {
|
||||
// skip native entries.
|
||||
continue;
|
||||
}
|
||||
$currency = $currencies[$currencyId] ?? $this->currencyRepos->find($currencyId);
|
||||
$currencies[$currencyId] = $currency;
|
||||
// create objects for big array.
|
||||
$return[] = [
|
||||
'key' => sprintf('balance-in-%s', $currency->code),
|
||||
'value' => $sums[$currencyId] ?? '0',
|
||||
'currency_id' => (string)$currency->id,
|
||||
'currency_code' => $currency->code,
|
||||
'currency_symbol' => $currency->symbol,
|
||||
'currency_decimal_places' => $currency->decimal_places,
|
||||
];
|
||||
$return[] = [
|
||||
'key' => sprintf('spent-in-%s', $currency->code),
|
||||
'value' => $expenses[$currencyId] ?? '0',
|
||||
'currency_id' => (string)$currency->id,
|
||||
'currency_code' => $currency->code,
|
||||
'currency_symbol' => $currency->symbol,
|
||||
'currency_decimal_places' => $currency->decimal_places,
|
||||
];
|
||||
$return[] = [
|
||||
'key' => sprintf('earned-in-%s', $currency->code),
|
||||
'value' => $incomes[$currencyId] ?? '0',
|
||||
'currency_id' => (string)$currency->id,
|
||||
'currency_code' => $currency->code,
|
||||
'currency_symbol' => $currency->symbol,
|
||||
'currency_decimal_places' => $currency->decimal_places,
|
||||
];
|
||||
}
|
||||
return $return;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Carbon $start
|
||||
* @param Carbon $end
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
private function getBillInformation(Carbon $start, Carbon $end): array
|
||||
{
|
||||
/*
|
||||
* Since both this method and the chart use the exact same data, we can suffice
|
||||
* with calling the one method in the bill repository that will get this amount.
|
||||
*/
|
||||
$paidAmount = $this->billRepository->sumPaidInRange($start, $end);
|
||||
$unpaidAmount = $this->billRepository->sumUnpaidInRange($start, $end);
|
||||
|
||||
$return = [];
|
||||
/**
|
||||
* @var array $info
|
||||
*/
|
||||
foreach ($paidAmount as $info) {
|
||||
$amount = bcmul($info['sum'], '-1');
|
||||
$nativeAmount = bcmul($info['native_sum'], '-1');
|
||||
$return[] = [
|
||||
'key' => sprintf('bills-paid-in-%s', $info['currency_code']),
|
||||
'value' => $amount,
|
||||
'currency_id' => (string)$info['currency_id'],
|
||||
'currency_code' => $info['currency_code'],
|
||||
'currency_symbol' => $info['currency_symbol'],
|
||||
'currency_decimal_places' => $info['currency_decimal_places'],
|
||||
];
|
||||
$return[] = [
|
||||
'key' => 'bills-paid-in-native',
|
||||
'value' => $nativeAmount,
|
||||
'currency_id' => (string)$info['native_id'],
|
||||
'currency_code' => $info['native_code'],
|
||||
'currency_symbol' => $info['native_symbol'],
|
||||
'currency_decimal_places' => $info['native_decimal_places'],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @var array $info
|
||||
*/
|
||||
foreach ($unpaidAmount as $info) {
|
||||
$amount = bcmul($info['sum'], '-1');
|
||||
$nativeAmount = bcmul($info['native_sum'], '-1');
|
||||
$return[] = [
|
||||
'key' => sprintf('bills-unpaid-in-%s', $info['currency_code']),
|
||||
'value' => $amount,
|
||||
'currency_id' => (string)$info['currency_id'],
|
||||
'currency_code' => $info['currency_code'],
|
||||
'currency_symbol' => $info['currency_symbol'],
|
||||
'currency_decimal_places' => $info['currency_decimal_places'],
|
||||
];
|
||||
$return[] = [
|
||||
'key' => 'bills-unpaid-in-native',
|
||||
'value' => $nativeAmount,
|
||||
'currency_id' => (string)$info['native_id'],
|
||||
'currency_code' => $info['native_code'],
|
||||
'currency_symbol' => $info['native_symbol'],
|
||||
'currency_decimal_places' => $info['native_decimal_places'],
|
||||
];
|
||||
}
|
||||
|
||||
return $return;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Carbon $start
|
||||
* @param Carbon $end
|
||||
*
|
||||
* @return array
|
||||
* @throws Exception
|
||||
*/
|
||||
private function getLeftToSpendInfo(Carbon $start, Carbon $end): array
|
||||
{
|
||||
app('log')->debug('Now in getLeftToSpendInfo');
|
||||
$return = [];
|
||||
$today = today(config('app.timezone'));
|
||||
$available = $this->abRepository->getAvailableBudgetWithCurrency($start, $end);
|
||||
$budgets = $this->budgetRepository->getActiveBudgets();
|
||||
$spent = $this->opsRepository->listExpenses($start, $end, null, $budgets);
|
||||
$default = app('amount')->getDefaultCurrency();
|
||||
$currencies = [];
|
||||
$converter = new ExchangeRateConverter();
|
||||
|
||||
// native info:
|
||||
$nativeLeft = [
|
||||
'key' => 'left-to-spend-in-native',
|
||||
'value' => '0',
|
||||
'currency_id' => (string)$default->id,
|
||||
'currency_code' => $default->code,
|
||||
'currency_symbol' => $default->symbol,
|
||||
'currency_decimal_places' => (int)$default->decimal_places,
|
||||
];
|
||||
$nativePerDay = [
|
||||
'key' => 'left-per-day-to-spend-in-native',
|
||||
'value' => '0',
|
||||
'currency_id' => (string)$default->id,
|
||||
'currency_code' => $default->code,
|
||||
'currency_symbol' => $default->symbol,
|
||||
'currency_decimal_places' => (int)$default->decimal_places,
|
||||
];
|
||||
|
||||
/**
|
||||
* @var int $currencyId
|
||||
* @var array $row
|
||||
*/
|
||||
foreach ($spent as $currencyId => $row) {
|
||||
app('log')->debug(sprintf('Processing spent array in currency #%d', $currencyId));
|
||||
$currencyId = (int)$currencyId;
|
||||
$spent = '0';
|
||||
$spentNative = '0';
|
||||
// get the sum from the array of transactions (double loop but who cares)
|
||||
/** @var array $budget */
|
||||
foreach ($row['budgets'] as $budget) {
|
||||
app('log')->debug(sprintf('Processing expenses in budget "%s".', $budget['name']));
|
||||
/** @var array $journal */
|
||||
foreach ($budget['transaction_journals'] as $journal) {
|
||||
$journalCurrencyId = $journal['currency_id'];
|
||||
$currency = $currencies[$journalCurrencyId] ?? $this->currencyRepos->find($journalCurrencyId);
|
||||
$currencies[$currencyId] = $currency;
|
||||
$amount = app('steam')->negative($journal['amount']);
|
||||
$amountNative = $converter->convert($default, $currency, $start, $amount);
|
||||
if ((int)$journal['foreign_currency_id'] === (int)$default->id) {
|
||||
$amountNative = $journal['foreign_amount'];
|
||||
}
|
||||
$spent = bcadd($spent, $amount);
|
||||
$spentNative = bcadd($spentNative, $amountNative);
|
||||
}
|
||||
app('log')->debug(sprintf('Total spent in budget "%s" is %s', $budget['name'], $spent));
|
||||
}
|
||||
|
||||
// either an amount was budgeted or 0 is available.
|
||||
$currency = $currencies[$currencyId] ?? $this->currencyRepos->find($currencyId);
|
||||
$currencies[$currencyId] = $currency;
|
||||
$amount = $available[$currencyId]['amount'] ?? '0';
|
||||
$amountNative = $available[$currencyId]['native_amount'] ?? '0';
|
||||
$left = bcadd($amount, $spent);
|
||||
$leftNative = bcadd($amountNative, $spentNative);
|
||||
app('log')->debug(sprintf('Available amount is %s', $amount));
|
||||
app('log')->debug(sprintf('Amount left is %s', $left));
|
||||
|
||||
// how much left per day?
|
||||
$days = $today->diffInDays($end) + 1;
|
||||
$perDay = '0';
|
||||
$perDayNative = '0';
|
||||
if (0 !== $days && bccomp($left, '0') > -1) {
|
||||
$perDay = bcdiv($left, (string)$days);
|
||||
}
|
||||
if (0 !== $days && bccomp($leftNative, '0') > -1) {
|
||||
$perDayNative = bcdiv($leftNative, (string)$days);
|
||||
}
|
||||
|
||||
// left
|
||||
$return[] = [
|
||||
'key' => sprintf('left-to-spend-in-%s', $row['currency_code']),
|
||||
'value' => $left,
|
||||
'currency_id' => (string)$row['currency_id'],
|
||||
'currency_code' => $row['currency_code'],
|
||||
'currency_symbol' => $row['currency_symbol'],
|
||||
'currency_decimal_places' => (int)$row['currency_decimal_places'],
|
||||
];
|
||||
// left (native)
|
||||
$nativeLeft['value'] = $leftNative;
|
||||
|
||||
// left per day:
|
||||
$return[] = [
|
||||
'key' => sprintf('left-per-day-to-spend-in-%s', $row['currency_code']),
|
||||
'value' => $perDay,
|
||||
'currency_id' => (string)$row['currency_id'],
|
||||
'currency_code' => $row['currency_code'],
|
||||
'currency_symbol' => $row['currency_symbol'],
|
||||
'currency_decimal_places' => (int)$row['currency_decimal_places'],
|
||||
];
|
||||
|
||||
// left per day (native)
|
||||
$nativePerDay['value'] = $perDayNative;
|
||||
}
|
||||
$return[] = $nativeLeft;
|
||||
$return[] = $nativePerDay;
|
||||
|
||||
return $return;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Carbon $start
|
||||
* @param Carbon $end
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
private function getNetWorthInfo(Carbon $start, Carbon $end): array
|
||||
{
|
||||
/** @var UserGroup $userGroup */
|
||||
$userGroup = auth()->user()->userGroup;
|
||||
$date = today(config('app.timezone'))->startOfDay();
|
||||
// start and end in the future? use $end
|
||||
if ($this->notInDateRange($date, $start, $end)) {
|
||||
/** @var Carbon $date */
|
||||
$date = session('end', today(config('app.timezone'))->endOfMonth());
|
||||
}
|
||||
|
||||
/** @var NetWorthInterface $netWorthHelper */
|
||||
$netWorthHelper = app(NetWorthInterface::class);
|
||||
$netWorthHelper->setUserGroup($userGroup);
|
||||
$allAccounts = $this->accountRepository->getActiveAccountsByType(
|
||||
[AccountType::ASSET, AccountType::DEFAULT, AccountType::LOAN, AccountType::MORTGAGE, AccountType::DEBT]
|
||||
);
|
||||
|
||||
// filter list on preference of being included.
|
||||
$filtered = $allAccounts->filter(
|
||||
function (Account $account) {
|
||||
$includeNetWorth = $this->accountRepository->getMetaValue($account, 'include_net_worth');
|
||||
|
||||
return null === $includeNetWorth || '1' === $includeNetWorth;
|
||||
}
|
||||
);
|
||||
|
||||
$netWorthSet = $netWorthHelper->byAccounts($filtered, $date);
|
||||
$return = [];
|
||||
// in native amount
|
||||
$return[] = [
|
||||
'key' => 'net-worth-in-native',
|
||||
'value' => $netWorthSet['native']['balance'],
|
||||
'currency_id' => (string)$netWorthSet['native']['currency_id'],
|
||||
'currency_code' => $netWorthSet['native']['currency_code'],
|
||||
'currency_symbol' => $netWorthSet['native']['currency_symbol'],
|
||||
'currency_decimal_places' => $netWorthSet['native']['currency_decimal_places'],
|
||||
];
|
||||
foreach ($netWorthSet as $key => $data) {
|
||||
if ('native' === $key) {
|
||||
continue;
|
||||
}
|
||||
$return[] = [
|
||||
'key' => sprintf('net-worth-in-%s', $data['currency_code']),
|
||||
'value' => $data['balance'],
|
||||
'currency_id' => (string)$data['currency_id'],
|
||||
'currency_code' => $data['currency_code'],
|
||||
'currency_symbol' => $data['currency_symbol'],
|
||||
'currency_decimal_places' => $data['currency_decimal_places'],
|
||||
];
|
||||
}
|
||||
|
||||
return $return;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if date is outside session range.
|
||||
*
|
||||
* @param Carbon $date
|
||||
*
|
||||
* @param Carbon $start
|
||||
* @param Carbon $end
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
protected function notInDateRange(Carbon $date, Carbon $start, Carbon $end): bool // Validate a preference
|
||||
{
|
||||
$result = false;
|
||||
if ($start->greaterThanOrEqualTo($date) && $end->greaterThanOrEqualTo($date)) {
|
||||
$result = true;
|
||||
}
|
||||
// start and end in the past? use $end
|
||||
if ($start->lessThanOrEqualTo($date) && $end->lessThanOrEqualTo($date)) {
|
||||
$result = true;
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
}
|
@@ -24,6 +24,9 @@ declare(strict_types=1);
|
||||
|
||||
namespace FireflyIII\Api\V2\Controllers\System;
|
||||
|
||||
/**
|
||||
* Class ConfigurationController
|
||||
*/
|
||||
class ConfigurationController
|
||||
{
|
||||
}
|
||||
|
@@ -26,6 +26,9 @@ namespace FireflyIII\Api\V2\Controllers\System;
|
||||
|
||||
use FireflyIII\Api\V2\Controllers\Controller;
|
||||
|
||||
/**
|
||||
* Class DebugController
|
||||
*/
|
||||
class DebugController extends Controller
|
||||
{
|
||||
}
|
||||
|
@@ -49,19 +49,17 @@ class AccountController extends Controller
|
||||
*
|
||||
* @return JsonResponse
|
||||
*/
|
||||
public function listTransactions(ListRequest $request, Account $account): JsonResponse
|
||||
public function list(ListRequest $request, Account $account): JsonResponse
|
||||
{
|
||||
// collect transactions:
|
||||
$type = $request->get('type') ?? 'default';
|
||||
$limit = (int)$request->get('limit');
|
||||
$page = (int)$request->get('page');
|
||||
$limit = $request->getLimit();
|
||||
$page = $request->getPage();
|
||||
$page = max($page, 1);
|
||||
|
||||
if ($limit > 0 && $limit <= $this->pageSize) {
|
||||
$this->pageSize = $limit;
|
||||
}
|
||||
|
||||
$types = $this->mapTransactionTypes($type);
|
||||
|
||||
/** @var GroupCollectorInterface $collector */
|
||||
$collector = app(GroupCollectorInterface::class);
|
||||
@@ -69,15 +67,25 @@ class AccountController extends Controller
|
||||
->withAPIInformation()
|
||||
->setLimit($this->pageSize)
|
||||
->setPage($page)
|
||||
->setTypes($types);
|
||||
->setTypes($request->getTransactionTypes());
|
||||
|
||||
// TODO date filter
|
||||
//if (null !== $this->parameters->get('start') && null !== $this->parameters->get('end')) {
|
||||
// $collector->setRange($this->parameters->get('start'), $this->parameters->get('end'));
|
||||
//}
|
||||
$start = $request->getStartDate();
|
||||
$end = $request->getEndDate();
|
||||
if (null !== $start) {
|
||||
$collector->setStart($start);
|
||||
}
|
||||
if (null !== $end) {
|
||||
$collector->setEnd($start);
|
||||
}
|
||||
|
||||
$paginator = $collector->getPaginatedGroups();
|
||||
$paginator->setPath(route('api.v2.accounts.transactions', [$account->id])); // TODO . $this->buildParams()
|
||||
$paginator->setPath(
|
||||
sprintf(
|
||||
'%s?%s',
|
||||
route('api.v2.accounts.transactions', [$account->id]),
|
||||
$request->buildParams()
|
||||
)
|
||||
);
|
||||
|
||||
return response()
|
||||
->json($this->jsonApiList('transactions', $paginator, new TransactionGroupTransformer()))
|
||||
|
@@ -0,0 +1,89 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
/*
|
||||
* TransactionController.php
|
||||
* Copyright (c) 2023 james@firefly-iii.org
|
||||
*
|
||||
* This file is part of Firefly III (https://github.com/firefly-iii).
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
namespace FireflyIII\Api\V2\Controllers\Transaction\List;
|
||||
|
||||
use FireflyIII\Api\V2\Controllers\Controller;
|
||||
use FireflyIII\Api\V2\Request\Transaction\ListRequest;
|
||||
use FireflyIII\Helpers\Collector\GroupCollectorInterface;
|
||||
use FireflyIII\Transformers\V2\TransactionGroupTransformer;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
|
||||
/**
|
||||
* Class TransactionController
|
||||
*/
|
||||
class TransactionController extends Controller
|
||||
{
|
||||
/**
|
||||
* @param ListRequest $request
|
||||
*
|
||||
* @return JsonResponse
|
||||
*/
|
||||
public function list(ListRequest $request): JsonResponse
|
||||
{
|
||||
// collect transactions:
|
||||
$limit = $request->getLimit();
|
||||
$page = $request->getPage();
|
||||
$page = max($page, 1);
|
||||
|
||||
if ($limit > 0 && $limit <= $this->pageSize) {
|
||||
$this->pageSize = $limit;
|
||||
}
|
||||
|
||||
|
||||
/** @var GroupCollectorInterface $collector */
|
||||
$collector = app(GroupCollectorInterface::class);
|
||||
$collector->setUserGroup(auth()->user()->userGroup)
|
||||
->withAPIInformation()
|
||||
->setLimit($this->pageSize)
|
||||
->setPage($page)
|
||||
->setTypes($request->getTransactionTypes());
|
||||
|
||||
$start = $this->parameters->get('start');
|
||||
$end = $this->parameters->get('end');
|
||||
if (null !== $start) {
|
||||
$collector->setStart($start);
|
||||
}
|
||||
if (null !== $end) {
|
||||
$collector->setEnd($end);
|
||||
}
|
||||
|
||||
// $collector->dumpQuery();
|
||||
// exit;
|
||||
|
||||
$paginator = $collector->getPaginatedGroups();
|
||||
$paginator->setPath(
|
||||
sprintf(
|
||||
'%s?%s',
|
||||
route('api.v2.transactions.list'),
|
||||
$request->buildParams()
|
||||
)
|
||||
);
|
||||
|
||||
return response()
|
||||
->json($this->jsonApiList('transactions', $paginator, new TransactionGroupTransformer()))
|
||||
->header('Content-Type', self::CONTENT_TYPE);
|
||||
}
|
||||
|
||||
|
||||
}
|
85
app/Api/V2/Request/Chart/BalanceChartRequest.php
Normal file
85
app/Api/V2/Request/Chart/BalanceChartRequest.php
Normal file
@@ -0,0 +1,85 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
/*
|
||||
* BalanceChartRequest.php
|
||||
* Copyright (c) 2023 james@firefly-iii.org
|
||||
*
|
||||
* This file is part of Firefly III (https://github.com/firefly-iii).
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
namespace FireflyIII\Api\V2\Request\Chart;
|
||||
|
||||
use FireflyIII\Support\Request\ChecksLogin;
|
||||
use FireflyIII\Support\Request\ConvertsDataTypes;
|
||||
use Illuminate\Foundation\Http\FormRequest;
|
||||
use Illuminate\Validation\Validator;
|
||||
|
||||
class BalanceChartRequest extends FormRequest
|
||||
{
|
||||
use ConvertsDataTypes;
|
||||
use ChecksLogin;
|
||||
|
||||
/**
|
||||
* Get all data from the request.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getAll(): array
|
||||
{
|
||||
return [
|
||||
'accounts' => $this->getAccountList(),
|
||||
'period' => $this->convertString('period'),
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* The rules that the incoming request must be matched against.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function rules(): array
|
||||
{
|
||||
return [
|
||||
'start' => 'required|date|after:1900-01-01|before:2099-12-31',
|
||||
'end' => 'required|date|after_or_equal:start|before:2099-12-31|after:1900-01-01',
|
||||
'accounts.*' => 'required|exists:accounts,id',
|
||||
'period' => sprintf('required|in:%s', join(',', config('firefly.valid_view_ranges'))),
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Validator $validator
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function withValidator(Validator $validator): void
|
||||
{
|
||||
$validator->after(
|
||||
function (Validator $validator) {
|
||||
// validate transaction query data.
|
||||
$data = $validator->getData();
|
||||
if (!array_key_exists('accounts', $data)) {
|
||||
$validator->errors()->add('accounts', trans('validation.filled', ['attribute' => 'accounts']));
|
||||
return;
|
||||
}
|
||||
if (!is_array($data['accounts'])) {
|
||||
$validator->errors()->add('accounts', trans('validation.filled', ['attribute' => 'accounts']));
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
@@ -47,7 +47,7 @@ class DateRequest extends FormRequest
|
||||
{
|
||||
return [
|
||||
'start' => $this->getCarbonDate('start'),
|
||||
'end' => $this->getCarbonDate('end'),
|
||||
'end' => $this->getCarbonDate('end')->endOfDay(),
|
||||
];
|
||||
}
|
||||
|
||||
|
@@ -24,15 +24,84 @@ declare(strict_types=1);
|
||||
|
||||
namespace FireflyIII\Api\V2\Request\Transaction;
|
||||
|
||||
use Carbon\Carbon;
|
||||
use FireflyIII\Support\Http\Api\TransactionFilter;
|
||||
use FireflyIII\Support\Request\ChecksLogin;
|
||||
use FireflyIII\Support\Request\ConvertsDataTypes;
|
||||
use Illuminate\Foundation\Http\FormRequest;
|
||||
|
||||
/**
|
||||
* Class ListRequest
|
||||
* Used specifically to list transactions.
|
||||
*/
|
||||
class ListRequest extends FormRequest
|
||||
{
|
||||
use ChecksLogin;
|
||||
use ConvertsDataTypes;
|
||||
use TransactionFilter;
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function buildParams(): string
|
||||
{
|
||||
$array = [
|
||||
'page' => $this->getPage(),
|
||||
];
|
||||
|
||||
$start = $this->getStartDate();
|
||||
$end = $this->getEndDate();
|
||||
if (null !== $start && null !== $end) {
|
||||
$array['start'] = $start->format('Y-m-d');
|
||||
$array['end'] = $end->format('Y-m-d');
|
||||
}
|
||||
if (0 !== $this->getLimit()) {
|
||||
$array['limit'] = $this->getLimit();
|
||||
}
|
||||
return http_build_query($array);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int
|
||||
*/
|
||||
public function getPage(): int
|
||||
{
|
||||
$page = $this->convertInteger('page');
|
||||
return 0 === $page || $page > 65536 ? 1 : $page;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Carbon|null
|
||||
*/
|
||||
public function getStartDate(): ?Carbon
|
||||
{
|
||||
return $this->getCarbonDate('start');
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Carbon|null
|
||||
*/
|
||||
public function getEndDate(): ?Carbon
|
||||
{
|
||||
return $this->getCarbonDate('end');
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int
|
||||
*/
|
||||
public function getLimit(): int
|
||||
{
|
||||
return $this->convertInteger('limit');
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function getTransactionTypes(): array
|
||||
{
|
||||
$type = (string)$this->get('type', 'default');
|
||||
return $this->mapTransactionTypes($type);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
|
@@ -34,6 +34,7 @@ use FireflyIII\Models\PiggyBankRepetition;
|
||||
use FireflyIII\Models\RecurrenceTransaction;
|
||||
use FireflyIII\Models\RuleTrigger;
|
||||
use Illuminate\Console\Command;
|
||||
use ValueError;
|
||||
|
||||
/**
|
||||
* Class ReportSkeleton
|
||||
@@ -247,7 +248,16 @@ class CorrectAmounts extends Command
|
||||
/** @var RuleTrigger $item */
|
||||
foreach ($set as $item) {
|
||||
// basic check:
|
||||
if (-1 === bccomp((string)$item->trigger_value, '0')) {
|
||||
$check = 0;
|
||||
try {
|
||||
$check = bccomp((string)$item->trigger_value, '0');
|
||||
} catch (ValueError $e) {
|
||||
$this->friendlyError(sprintf('Rule #%d contained invalid %s-trigger "%s". The trigger has been removed, and the rule is disabled.', $item->rule_id, $item->trigger_type, $item->trigger_value));
|
||||
$item->rule->active = false;
|
||||
$item->rule->save();
|
||||
$item->forceDelete();
|
||||
}
|
||||
if (-1 === $check) {
|
||||
$fixed++;
|
||||
$item->trigger_value = app('steam')->positive((string)$item->trigger_value);
|
||||
$item->save();
|
||||
|
@@ -126,6 +126,7 @@ class CorrectOpeningBalanceCurrencies extends Command
|
||||
/**
|
||||
* @param Account $account
|
||||
* @param TransactionJournal $journal
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
private function setCorrectCurrency(Account $account, TransactionJournal $journal): int
|
||||
|
@@ -82,6 +82,7 @@ class DeleteEmptyJournals extends Command
|
||||
TransactionJournal::find((int)$row->transaction_journal_id)->delete();
|
||||
} catch (QueryException $e) {
|
||||
Log::info(sprintf('Could not delete journal: %s', $e->getMessage()));
|
||||
Log::error($e->getTraceAsString());
|
||||
}
|
||||
|
||||
|
||||
@@ -97,6 +98,9 @@ class DeleteEmptyJournals extends Command
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return void
|
||||
*/
|
||||
private function deleteEmptyJournals(): void
|
||||
{
|
||||
$count = 0;
|
||||
@@ -110,6 +114,7 @@ class DeleteEmptyJournals extends Command
|
||||
TransactionJournal::find($entry->id)->delete();
|
||||
} catch (QueryException $e) {
|
||||
Log::info(sprintf('Could not delete entry: %s', $e->getMessage()));
|
||||
Log::error($e->getTraceAsString());
|
||||
}
|
||||
|
||||
|
||||
|
@@ -65,6 +65,9 @@ class DeleteOrphanedTransactions extends Command
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return void
|
||||
*/
|
||||
private function deleteOrphanedJournals(): void
|
||||
{
|
||||
$set = TransactionJournal::leftJoin('transaction_groups', 'transaction_journals.transaction_group_id', 'transaction_groups.id')
|
||||
|
@@ -89,6 +89,7 @@ class FixAccountTypes extends Command
|
||||
* @param TransactionJournal $journal
|
||||
*
|
||||
* @throws FireflyException
|
||||
* @throws JsonException
|
||||
*/
|
||||
private function inspectJournal(TransactionJournal $journal): void
|
||||
{
|
||||
|
@@ -1,5 +1,26 @@
|
||||
<?php
|
||||
|
||||
|
||||
/*
|
||||
* TriggerCreditCalculation.php
|
||||
* Copyright (c) 2023 james@firefly-iii.org
|
||||
*
|
||||
* This file is part of Firefly III (https://github.com/firefly-iii).
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace FireflyIII\Console\Commands\Correction;
|
||||
@@ -29,6 +50,9 @@ class TriggerCreditCalculation extends Command
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return void
|
||||
*/
|
||||
private function processAccounts(): void
|
||||
{
|
||||
$accounts = Account::leftJoin('account_types', 'accounts.account_type_id', 'account_types.id')
|
||||
|
@@ -38,6 +38,8 @@ use Illuminate\Console\Command;
|
||||
use Illuminate\Support\Collection;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
use InvalidArgumentException;
|
||||
use Psr\Container\ContainerExceptionInterface;
|
||||
use Psr\Container\NotFoundExceptionInterface;
|
||||
|
||||
/**
|
||||
* Class ExportData
|
||||
@@ -83,6 +85,8 @@ class ExportData extends Command
|
||||
*
|
||||
* @return int
|
||||
* @throws FireflyException
|
||||
* @throws ContainerExceptionInterface
|
||||
* @throws NotFoundExceptionInterface
|
||||
*/
|
||||
public function handle(): int
|
||||
{
|
||||
|
@@ -32,6 +32,7 @@ use FireflyIII\Models\Bill;
|
||||
use FireflyIII\Models\Budget;
|
||||
use FireflyIII\Models\Category;
|
||||
use FireflyIII\Models\CurrencyExchangeRate;
|
||||
use FireflyIII\Models\ObjectGroup;
|
||||
use FireflyIII\Models\Recurrence;
|
||||
use FireflyIII\Models\Rule;
|
||||
use FireflyIII\Models\RuleGroup;
|
||||
@@ -73,6 +74,11 @@ class UpdateGroupInformation extends Command
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param User $user
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
private function updateGroupInfo(User $user): void
|
||||
{
|
||||
$group = $user->userGroup;
|
||||
@@ -88,6 +94,7 @@ class UpdateGroupInformation extends Command
|
||||
Bill::class,
|
||||
Budget::class,
|
||||
Category::class,
|
||||
ObjectGroup::class,
|
||||
CurrencyExchangeRate::class,
|
||||
Recurrence::class,
|
||||
RuleGroup::class,
|
||||
|
@@ -1,6 +1,6 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
/*
|
||||
* ShowsFriendlyMessages.php
|
||||
* Copyright (c) 2023 james@firefly-iii.org
|
||||
@@ -21,6 +21,8 @@ declare(strict_types=1);
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace FireflyIII\Console\Commands;
|
||||
|
||||
/**
|
||||
@@ -30,6 +32,7 @@ trait ShowsFriendlyMessages
|
||||
{
|
||||
/**
|
||||
* @param string $message
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function friendlyError(string $message): void
|
||||
@@ -39,6 +42,7 @@ trait ShowsFriendlyMessages
|
||||
|
||||
/**
|
||||
* @param string $message
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function friendlyInfo(string $message): void
|
||||
@@ -48,6 +52,7 @@ trait ShowsFriendlyMessages
|
||||
|
||||
/**
|
||||
* @param string $message
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function friendlyNeutral(string $message): void
|
||||
@@ -57,6 +62,7 @@ trait ShowsFriendlyMessages
|
||||
|
||||
/**
|
||||
* @param string $message
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function friendlyLine(string $message): void
|
||||
@@ -66,6 +72,7 @@ trait ShowsFriendlyMessages
|
||||
|
||||
/**
|
||||
* @param string $message
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function friendlyPositive(string $message): void
|
||||
@@ -75,6 +82,7 @@ trait ShowsFriendlyMessages
|
||||
|
||||
/**
|
||||
* @param string $message
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function friendlyWarning(string $message): void
|
||||
|
@@ -92,7 +92,6 @@ class ForceDecimalSize extends Command
|
||||
/**
|
||||
* Execute the console command.
|
||||
*
|
||||
* @throws FireflyException
|
||||
*/
|
||||
public function handle(): int
|
||||
{
|
||||
@@ -110,6 +109,9 @@ class ForceDecimalSize extends Command
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return void
|
||||
*/
|
||||
private function determineDatabaseType(): void
|
||||
{
|
||||
// switch stuff based on database connection:
|
||||
@@ -155,6 +157,7 @@ class ForceDecimalSize extends Command
|
||||
* This method loops all enabled currencies and then calls the method that will fix all objects in this currency.
|
||||
*
|
||||
* @return void
|
||||
* @throws FireflyException
|
||||
*/
|
||||
private function correctAmountsByCurrency(): void
|
||||
{
|
||||
|
@@ -32,6 +32,9 @@ use Illuminate\Support\Facades\DB;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
/**
|
||||
* Class ForceMigration
|
||||
*/
|
||||
class ForceMigration extends Command
|
||||
{
|
||||
use ShowsFriendlyMessages;
|
||||
@@ -79,6 +82,9 @@ class ForceMigration extends Command
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return void
|
||||
*/
|
||||
private function forceMigration(): void
|
||||
{
|
||||
DB::commit();
|
||||
|
52
app/Console/Commands/System/OutputVersion.php
Normal file
52
app/Console/Commands/System/OutputVersion.php
Normal file
@@ -0,0 +1,52 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
/*
|
||||
* OutputVersion.php
|
||||
* Copyright (c) 2023 james@firefly-iii.org
|
||||
*
|
||||
* This file is part of Firefly III (https://github.com/firefly-iii).
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
namespace FireflyIII\Console\Commands\System;
|
||||
|
||||
use Illuminate\Console\Command;
|
||||
|
||||
class OutputVersion extends Command
|
||||
{
|
||||
/**
|
||||
* The name and signature of the console command.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $signature = 'firefly-iii:output-version';
|
||||
|
||||
/**
|
||||
* The console command description.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $description = 'Outputs the Firefly III version';
|
||||
|
||||
/**
|
||||
* Execute the console command.
|
||||
*/
|
||||
public function handle(): int
|
||||
{
|
||||
echo config('firefly.version');
|
||||
return 0;
|
||||
}
|
||||
}
|
@@ -64,6 +64,8 @@ class Cron extends Command
|
||||
|
||||
/**
|
||||
* @return int
|
||||
* @throws ContainerExceptionInterface
|
||||
* @throws NotFoundExceptionInterface
|
||||
*/
|
||||
public function handle(): int
|
||||
{
|
||||
@@ -76,9 +78,9 @@ class Cron extends Command
|
||||
$force = (bool)$this->option('force');
|
||||
|
||||
/*
|
||||
* Fire recurring transaction cron job.
|
||||
* Fire exchange rates cron job.
|
||||
*/
|
||||
if (true === config('cer.enabled')) {
|
||||
if (true === config('cer.download_enabled')) {
|
||||
try {
|
||||
$this->exchangeRatesCronJob($force, $date);
|
||||
} catch (FireflyException $e) {
|
||||
|
@@ -35,6 +35,8 @@ use FireflyIII\Repositories\User\UserRepositoryInterface;
|
||||
use FireflyIII\User;
|
||||
use Illuminate\Console\Command;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
use Psr\Container\ContainerExceptionInterface;
|
||||
use Psr\Container\NotFoundExceptionInterface;
|
||||
|
||||
/**
|
||||
* Class AccountCurrencies
|
||||
@@ -94,6 +96,8 @@ class AccountCurrencies extends Command
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
* @throws ContainerExceptionInterface
|
||||
* @throws NotFoundExceptionInterface
|
||||
*/
|
||||
private function isExecuted(): bool
|
||||
{
|
||||
|
@@ -24,13 +24,15 @@ declare(strict_types=1);
|
||||
namespace FireflyIII\Console\Commands\Upgrade;
|
||||
|
||||
use FireflyIII\Console\Commands\ShowsFriendlyMessages;
|
||||
use FireflyIII\Exceptions\FireflyException;
|
||||
use FireflyIII\Models\BudgetLimit;
|
||||
use Illuminate\Console\Command;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
use Psr\Container\ContainerExceptionInterface;
|
||||
use Psr\Container\NotFoundExceptionInterface;
|
||||
|
||||
/**
|
||||
* Class AppendBudgetLimitPeriods
|
||||
*/
|
||||
class AppendBudgetLimitPeriods extends Command
|
||||
{
|
||||
use ShowsFriendlyMessages;
|
||||
@@ -54,7 +56,6 @@ class AppendBudgetLimitPeriods extends Command
|
||||
*
|
||||
* @return int
|
||||
* @throws ContainerExceptionInterface
|
||||
* @throws FireflyException
|
||||
* @throws NotFoundExceptionInterface
|
||||
*/
|
||||
public function handle(): int
|
||||
|
@@ -25,7 +25,6 @@ namespace FireflyIII\Console\Commands\Upgrade;
|
||||
|
||||
use DB;
|
||||
use FireflyIII\Console\Commands\ShowsFriendlyMessages;
|
||||
use FireflyIII\Exceptions\FireflyException;
|
||||
use FireflyIII\Models\Budget;
|
||||
use FireflyIII\Models\Category;
|
||||
use FireflyIII\Models\Transaction;
|
||||
@@ -61,7 +60,6 @@ class BackToJournals extends Command
|
||||
*
|
||||
* @return int
|
||||
* @throws ContainerExceptionInterface
|
||||
* @throws FireflyException
|
||||
* @throws NotFoundExceptionInterface
|
||||
*/
|
||||
public function handle(): int
|
||||
|
@@ -51,6 +51,8 @@ class DecryptDatabase extends Command
|
||||
* Execute the console command.
|
||||
*
|
||||
* @return int
|
||||
* @throws ContainerExceptionInterface
|
||||
* @throws NotFoundExceptionInterface
|
||||
*/
|
||||
public function handle(): int
|
||||
{
|
||||
|
@@ -24,7 +24,6 @@ declare(strict_types=1);
|
||||
namespace FireflyIII\Console\Commands\Upgrade;
|
||||
|
||||
use FireflyIII\Console\Commands\ShowsFriendlyMessages;
|
||||
use FireflyIII\Exceptions\FireflyException;
|
||||
use FireflyIII\Models\Note;
|
||||
use FireflyIII\Models\TransactionJournalMeta;
|
||||
use Illuminate\Console\Command;
|
||||
@@ -58,7 +57,6 @@ class MigrateJournalNotes extends Command
|
||||
*
|
||||
* @return int
|
||||
* @throws ContainerExceptionInterface
|
||||
* @throws FireflyException
|
||||
* @throws NotFoundExceptionInterface
|
||||
*/
|
||||
public function handle(): int
|
||||
|
@@ -25,7 +25,6 @@ declare(strict_types=1);
|
||||
namespace FireflyIII\Console\Commands\Upgrade;
|
||||
|
||||
use FireflyIII\Console\Commands\ShowsFriendlyMessages;
|
||||
use FireflyIII\Exceptions\FireflyException;
|
||||
use FireflyIII\Models\Recurrence;
|
||||
use FireflyIII\Models\RecurrenceMeta;
|
||||
use FireflyIII\Models\RecurrenceTransactionMeta;
|
||||
@@ -60,7 +59,6 @@ class MigrateRecurrenceMeta extends Command
|
||||
*
|
||||
* @return int
|
||||
* @throws ContainerExceptionInterface
|
||||
* @throws FireflyException
|
||||
* @throws JsonException
|
||||
* @throws NotFoundExceptionInterface
|
||||
*/
|
||||
|
@@ -25,7 +25,6 @@ declare(strict_types=1);
|
||||
namespace FireflyIII\Console\Commands\Upgrade;
|
||||
|
||||
use FireflyIII\Console\Commands\ShowsFriendlyMessages;
|
||||
use FireflyIII\Exceptions\FireflyException;
|
||||
use FireflyIII\Models\Recurrence;
|
||||
use FireflyIII\Models\RecurrenceTransaction;
|
||||
use FireflyIII\Models\TransactionType;
|
||||
@@ -59,7 +58,6 @@ class MigrateRecurrenceType extends Command
|
||||
*
|
||||
* @return int
|
||||
* @throws ContainerExceptionInterface
|
||||
* @throws FireflyException
|
||||
* @throws NotFoundExceptionInterface
|
||||
*/
|
||||
public function handle(): int
|
||||
@@ -104,6 +102,7 @@ class MigrateRecurrenceType extends Command
|
||||
|
||||
/**
|
||||
* @param Recurrence $recurrence
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
private function migrateRecurrence(Recurrence $recurrence): void
|
||||
|
@@ -25,7 +25,6 @@ declare(strict_types=1);
|
||||
namespace FireflyIII\Console\Commands\Upgrade;
|
||||
|
||||
use FireflyIII\Console\Commands\ShowsFriendlyMessages;
|
||||
use FireflyIII\Exceptions\FireflyException;
|
||||
use FireflyIII\Models\Location;
|
||||
use FireflyIII\Models\Tag;
|
||||
use Illuminate\Console\Command;
|
||||
@@ -58,7 +57,6 @@ class MigrateTagLocations extends Command
|
||||
*
|
||||
* @return int
|
||||
* @throws ContainerExceptionInterface
|
||||
* @throws FireflyException
|
||||
* @throws NotFoundExceptionInterface
|
||||
*/
|
||||
public function handle(): int
|
||||
@@ -89,6 +87,9 @@ class MigrateTagLocations extends Command
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return void
|
||||
*/
|
||||
private function migrateTagLocations(): void
|
||||
{
|
||||
$tags = Tag::get();
|
||||
|
@@ -64,6 +64,8 @@ class MigrateToGroups extends Command
|
||||
* Execute the console command.
|
||||
*
|
||||
* @return int
|
||||
* @throws ContainerExceptionInterface
|
||||
* @throws NotFoundExceptionInterface
|
||||
*/
|
||||
public function handle(): int
|
||||
{
|
||||
|
@@ -24,7 +24,6 @@ declare(strict_types=1);
|
||||
namespace FireflyIII\Console\Commands\Upgrade;
|
||||
|
||||
use FireflyIII\Console\Commands\ShowsFriendlyMessages;
|
||||
use FireflyIII\Exceptions\FireflyException;
|
||||
use FireflyIII\Models\Account;
|
||||
use FireflyIII\Models\AccountType;
|
||||
use FireflyIII\Models\Transaction;
|
||||
@@ -61,7 +60,6 @@ class OtherCurrenciesCorrections extends Command
|
||||
*
|
||||
* @return int
|
||||
* @throws ContainerExceptionInterface
|
||||
* @throws FireflyException
|
||||
* @throws NotFoundExceptionInterface
|
||||
*/
|
||||
public function handle(): int
|
||||
|
@@ -62,6 +62,8 @@ class TransferCurrenciesCorrections extends Command
|
||||
* Execute the console command.
|
||||
*
|
||||
* @return int
|
||||
* @throws ContainerExceptionInterface
|
||||
* @throws NotFoundExceptionInterface
|
||||
*/
|
||||
public function handle(): int
|
||||
{
|
||||
|
@@ -69,6 +69,9 @@ class UpgradeDatabase extends Command
|
||||
'firefly-iii:liabilities-600',
|
||||
'firefly-iii:budget-limit-periods',
|
||||
'firefly-iii:restore-oauth-keys',
|
||||
// also just in case, some integrity commands:
|
||||
'firefly-iii:create-group-memberships',
|
||||
'firefly-iii:upgrade-group-information',
|
||||
];
|
||||
$args = [];
|
||||
if ($this->option('force')) {
|
||||
|
@@ -25,7 +25,6 @@ declare(strict_types=1);
|
||||
namespace FireflyIII\Console\Commands\Upgrade;
|
||||
|
||||
use FireflyIII\Console\Commands\ShowsFriendlyMessages;
|
||||
use FireflyIII\Exceptions\FireflyException;
|
||||
use FireflyIII\Factory\AccountMetaFactory;
|
||||
use FireflyIII\Models\Account;
|
||||
use FireflyIII\Models\Transaction;
|
||||
@@ -53,7 +52,6 @@ class UpgradeLiabilities extends Command
|
||||
*
|
||||
* @return int
|
||||
* @throws ContainerExceptionInterface
|
||||
* @throws FireflyException
|
||||
* @throws NotFoundExceptionInterface
|
||||
*/
|
||||
public function handle(): int
|
||||
|
@@ -25,7 +25,6 @@ declare(strict_types=1);
|
||||
namespace FireflyIII\Console\Commands\Upgrade;
|
||||
|
||||
use FireflyIII\Console\Commands\ShowsFriendlyMessages;
|
||||
use FireflyIII\Exceptions\FireflyException;
|
||||
use FireflyIII\Models\Account;
|
||||
use FireflyIII\Models\AccountType;
|
||||
use FireflyIII\Models\Transaction;
|
||||
@@ -56,7 +55,6 @@ class UpgradeLiabilitiesEight extends Command
|
||||
*
|
||||
* @return int
|
||||
* @throws ContainerExceptionInterface
|
||||
* @throws FireflyException
|
||||
* @throws NotFoundExceptionInterface
|
||||
*/
|
||||
public function handle(): int
|
||||
|
@@ -24,6 +24,9 @@ declare(strict_types=1);
|
||||
|
||||
namespace FireflyIII\Enums;
|
||||
|
||||
/**
|
||||
* Class RecurrenceRepetitionWeekend
|
||||
*/
|
||||
enum RecurrenceRepetitionWeekend: int
|
||||
{
|
||||
case WEEKEND_DO_NOTHING = 1;
|
||||
|
@@ -24,6 +24,9 @@ declare(strict_types=1);
|
||||
|
||||
namespace FireflyIII\Enums;
|
||||
|
||||
/**
|
||||
* Class UserRoleEnum
|
||||
*/
|
||||
enum UserRoleEnum: string
|
||||
{
|
||||
case CHANGE_PIGGY_BANKS = 'change_piggies';
|
||||
|
@@ -24,6 +24,9 @@ declare(strict_types=1);
|
||||
|
||||
namespace FireflyIII\Enums;
|
||||
|
||||
/**
|
||||
* Class WebhookDelivery
|
||||
*/
|
||||
enum WebhookDelivery: int
|
||||
{
|
||||
//case XML = 200;
|
||||
|
@@ -24,6 +24,9 @@ declare(strict_types=1);
|
||||
|
||||
namespace FireflyIII\Enums;
|
||||
|
||||
/**
|
||||
* Class WebhookResponse
|
||||
*/
|
||||
enum WebhookResponse: int
|
||||
{
|
||||
case TRANSACTIONS = 200;
|
||||
|
@@ -1,6 +1,6 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
/*
|
||||
* Created.php
|
||||
* Copyright (c) 2023 james@firefly-iii.org
|
||||
@@ -21,6 +21,8 @@ declare(strict_types=1);
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace FireflyIII\Events\Model\BudgetLimit;
|
||||
|
||||
use FireflyIII\Events\Event;
|
||||
|
@@ -1,8 +1,8 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
/*
|
||||
* Created.php
|
||||
* Deleted.php
|
||||
* Copyright (c) 2023 james@firefly-iii.org
|
||||
*
|
||||
* This file is part of Firefly III (https://github.com/firefly-iii).
|
||||
@@ -21,6 +21,8 @@ declare(strict_types=1);
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace FireflyIII\Events\Model\BudgetLimit;
|
||||
|
||||
use FireflyIII\Events\Event;
|
||||
|
@@ -1,8 +1,8 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
/*
|
||||
* Created.php
|
||||
* Updated.php
|
||||
* Copyright (c) 2023 james@firefly-iii.org
|
||||
*
|
||||
* This file is part of Firefly III (https://github.com/firefly-iii).
|
||||
@@ -21,6 +21,8 @@ declare(strict_types=1);
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace FireflyIII\Events\Model\BudgetLimit;
|
||||
|
||||
use FireflyIII\Events\Event;
|
||||
|
52
app/Events/Model/Rule/RuleActionFailedOnArray.php
Normal file
52
app/Events/Model/Rule/RuleActionFailedOnArray.php
Normal file
@@ -0,0 +1,52 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
/*
|
||||
* RuleActionFailedOnArray.php
|
||||
* Copyright (c) 2023 james@firefly-iii.org
|
||||
*
|
||||
* This file is part of Firefly III (https://github.com/firefly-iii).
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
namespace FireflyIII\Events\Model\Rule;
|
||||
|
||||
use FireflyIII\Models\RuleAction;
|
||||
use Illuminate\Queue\SerializesModels;
|
||||
|
||||
/**
|
||||
* Class RuleActionFailedOnArray
|
||||
*/
|
||||
class RuleActionFailedOnArray
|
||||
{
|
||||
use SerializesModels;
|
||||
|
||||
public string $error;
|
||||
public array $journal;
|
||||
public RuleAction $ruleAction;
|
||||
|
||||
/**
|
||||
* @param RuleAction $ruleAction
|
||||
* @param array $journal
|
||||
* @param string $error
|
||||
*/
|
||||
public function __construct(RuleAction $ruleAction, array $journal, string $error)
|
||||
{
|
||||
app('log')->debug('Created new RuleActionFailedOnArray');
|
||||
$this->ruleAction = $ruleAction;
|
||||
$this->journal = $journal;
|
||||
$this->error = $error;
|
||||
}
|
||||
}
|
53
app/Events/Model/Rule/RuleActionFailedOnObject.php
Normal file
53
app/Events/Model/Rule/RuleActionFailedOnObject.php
Normal file
@@ -0,0 +1,53 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
/*
|
||||
* RuleActionFailedOnArray.php
|
||||
* Copyright (c) 2023 james@firefly-iii.org
|
||||
*
|
||||
* This file is part of Firefly III (https://github.com/firefly-iii).
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
namespace FireflyIII\Events\Model\Rule;
|
||||
|
||||
use FireflyIII\Models\RuleAction;
|
||||
use FireflyIII\Models\TransactionJournal;
|
||||
use Illuminate\Queue\SerializesModels;
|
||||
|
||||
/**
|
||||
* Class RuleActionFailedOnObject
|
||||
*/
|
||||
class RuleActionFailedOnObject
|
||||
{
|
||||
use SerializesModels;
|
||||
|
||||
public string $error;
|
||||
public TransactionJournal $journal;
|
||||
public RuleAction $ruleAction;
|
||||
|
||||
/**
|
||||
* @param RuleAction $ruleAction
|
||||
* @param TransactionJournal $journal
|
||||
* @param string $error
|
||||
*/
|
||||
public function __construct(RuleAction $ruleAction, TransactionJournal $journal, string $error)
|
||||
{
|
||||
app('log')->debug('Created new RuleActionFailedOnObject');
|
||||
$this->ruleAction = $ruleAction;
|
||||
$this->journal = $journal;
|
||||
$this->error = $error;
|
||||
}
|
||||
}
|
@@ -26,6 +26,9 @@ namespace FireflyIII\Events;
|
||||
|
||||
use Illuminate\Queue\SerializesModels;
|
||||
|
||||
/**
|
||||
* Class NewVersionAvailable
|
||||
*/
|
||||
class NewVersionAvailable extends Event
|
||||
{
|
||||
use SerializesModels;
|
||||
|
@@ -25,6 +25,9 @@ namespace FireflyIII\Events;
|
||||
|
||||
use Illuminate\Queue\SerializesModels;
|
||||
|
||||
/**
|
||||
* Class RequestedSendWebhookMessages
|
||||
*/
|
||||
class RequestedSendWebhookMessages extends Event
|
||||
{
|
||||
use SerializesModels;
|
||||
|
@@ -92,6 +92,7 @@ class AccountFactory
|
||||
$return = $this->create(
|
||||
[
|
||||
'user_id' => $this->user->id,
|
||||
'user_group_id' => $this->user->user_group_id,
|
||||
'name' => $accountName,
|
||||
'account_type_id' => $type->id,
|
||||
'account_type_name' => null,
|
||||
@@ -199,6 +200,7 @@ class AccountFactory
|
||||
$active = array_key_exists('active', $data) ? $data['active'] : true;
|
||||
$databaseData = [
|
||||
'user_id' => $this->user->id,
|
||||
'user_group_id' => $this->user->user_group_id,
|
||||
'account_type_id' => $type->id,
|
||||
'name' => $data['name'],
|
||||
'order' => 25000,
|
||||
@@ -216,6 +218,7 @@ class AccountFactory
|
||||
}
|
||||
// create account!
|
||||
$account = Account::create($databaseData);
|
||||
Log::channel('audit')->info(sprintf('Account #%d ("%s") has been created.', $account->id, $account->name));
|
||||
|
||||
// update meta data:
|
||||
$data = $this->cleanMetaDataArray($account, $data);
|
||||
@@ -226,6 +229,7 @@ class AccountFactory
|
||||
$this->storeOpeningBalance($account, $data);
|
||||
} catch (FireflyException $e) {
|
||||
Log::error($e->getMessage());
|
||||
Log::error($e->getTraceAsString());
|
||||
}
|
||||
|
||||
// create credit liability data (only liabilities)
|
||||
@@ -233,6 +237,7 @@ class AccountFactory
|
||||
$this->storeCreditLiability($account, $data);
|
||||
} catch (FireflyException $e) {
|
||||
Log::error($e->getMessage());
|
||||
Log::error($e->getTraceAsString());
|
||||
}
|
||||
|
||||
// create notes
|
||||
|
@@ -26,6 +26,7 @@ namespace FireflyIII\Factory;
|
||||
|
||||
use FireflyIII\Models\Account;
|
||||
use FireflyIII\Models\AccountMeta;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
|
||||
/**
|
||||
* Class AccountMetaFactory
|
||||
|
@@ -67,6 +67,7 @@ class BillFactory
|
||||
'match' => 'MIGRATED_TO_RULES',
|
||||
'amount_min' => $data['amount_min'],
|
||||
'user_id' => $this->user->id,
|
||||
'user_group_id' => $this->user->user_group_id,
|
||||
'transaction_currency_id' => $currency->id,
|
||||
'amount_max' => $data['amount_max'],
|
||||
'date' => $data['date'],
|
||||
|
@@ -70,12 +70,14 @@ class CategoryFactory
|
||||
try {
|
||||
return Category::create(
|
||||
[
|
||||
'user_id' => $this->user->id,
|
||||
'name' => $categoryName,
|
||||
'user_id' => $this->user->id,
|
||||
'user_group_id' => $this->user->user_group_id,
|
||||
'name' => $categoryName,
|
||||
]
|
||||
);
|
||||
} catch (QueryException $e) {
|
||||
Log::error($e->getMessage());
|
||||
Log::error($e->getTraceAsString());
|
||||
throw new FireflyException('400003: Could not store new category.', 0, $e);
|
||||
}
|
||||
}
|
||||
|
@@ -107,6 +107,7 @@ class RecurrenceFactory
|
||||
$recurrence = new Recurrence(
|
||||
[
|
||||
'user_id' => $this->user->id,
|
||||
'user_group_id' => $this->user->user_group_id,
|
||||
'transaction_type_id' => $type->id,
|
||||
'title' => $title,
|
||||
'description' => $description,
|
||||
@@ -129,6 +130,7 @@ class RecurrenceFactory
|
||||
$this->createTransactions($recurrence, $data['transactions'] ?? []);
|
||||
} catch (FireflyException $e) {
|
||||
Log::error($e->getMessage());
|
||||
Log::error($e->getTraceAsString());
|
||||
$recurrence->forceDelete();
|
||||
$message = sprintf('Could not create recurring transaction: %s', $e->getMessage());
|
||||
$this->errors->add('store', $message);
|
||||
|
@@ -83,14 +83,15 @@ class TagFactory
|
||||
$latitude = 0.0 === (float)$data['latitude'] ? null : (float)$data['latitude']; // intentional float
|
||||
$longitude = 0.0 === (float)$data['longitude'] ? null : (float)$data['longitude']; // intentional float
|
||||
$array = [
|
||||
'user_id' => $this->user->id,
|
||||
'tag' => trim($data['tag']),
|
||||
'tagMode' => 'nothing',
|
||||
'date' => $data['date'],
|
||||
'description' => $data['description'],
|
||||
'latitude' => null,
|
||||
'longitude' => null,
|
||||
'zoomLevel' => null,
|
||||
'user_id' => $this->user->id,
|
||||
'user_group_id' => $this->user->user_group_id,
|
||||
'tag' => trim($data['tag']),
|
||||
'tagMode' => 'nothing',
|
||||
'date' => $data['date'],
|
||||
'description' => $data['description'],
|
||||
'latitude' => null,
|
||||
'longitude' => null,
|
||||
'zoomLevel' => null,
|
||||
];
|
||||
$tag = Tag::create($array);
|
||||
if (null !== $tag && null !== $latitude && null !== $longitude) {
|
||||
|
@@ -69,6 +69,7 @@ class TransactionCurrencyFactory
|
||||
} catch (QueryException $e) {
|
||||
$result = null;
|
||||
Log::error(sprintf('Could not create new currency: %s', $e->getMessage()));
|
||||
Log::error($e->getTraceAsString());
|
||||
throw new FireflyException('400004: Could not store new currency.', 0, $e);
|
||||
}
|
||||
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user