mirror of
https://github.com/firefly-iii/firefly-iii.git
synced 2025-09-02 03:02:18 +00:00
Compare commits
183 Commits
develop-20
...
develop-20
Author | SHA1 | Date | |
---|---|---|---|
|
54bf56bbb0 | ||
|
3d8c6671f4 | ||
|
4e33de9c29 | ||
|
27d46eb3fa | ||
|
e1e7a2e497 | ||
|
a476b4259c | ||
|
0c03ec5ddd | ||
|
2d95b7f8ef | ||
|
34cc79ce4f | ||
|
6ff9943fe0 | ||
|
a0166b45e4 | ||
|
d27b035b20 | ||
|
f3b387fc22 | ||
|
03904ffcde | ||
|
a7973190c2 | ||
|
671ff95f22 | ||
|
01181ceea9 | ||
|
97643639d1 | ||
|
424783c47b | ||
|
ea0ced70b2 | ||
|
1a633e64ef | ||
|
30da3f4399 | ||
|
6bdff95d87 | ||
|
895ae279d5 | ||
|
8b57f45963 | ||
|
a2d2b7edd3 | ||
|
3d65f00c6e | ||
|
333004c4d9 | ||
|
7451659824 | ||
|
ec89c23ace | ||
|
92d07d346f | ||
|
a7ac894af2 | ||
|
20f89e3a7c | ||
|
5d2f11c3c7 | ||
|
1eea79e431 | ||
|
1aaaac67ca | ||
|
1eb86639c9 | ||
|
28b911c4ee | ||
|
c525c70ec0 | ||
|
1f7d6e218b | ||
|
a69b6d9ce2 | ||
|
28b2ddde18 | ||
|
a16cc73c77 | ||
|
46395e350a | ||
|
f62e49090c | ||
|
af3b40a314 | ||
|
c3cea0fa9e | ||
|
6cbdb2ce70 | ||
|
b78460100d | ||
|
bf6e1cb0e1 | ||
|
6a53f5031c | ||
|
ae15ec01e8 | ||
|
fe3c7c47c4 | ||
|
68b934010c | ||
|
22852bd238 | ||
|
5b3b1804f3 | ||
|
f2588eb343 | ||
|
64a643ceec | ||
|
1add505644 | ||
|
9663eb6a19 | ||
|
f30a24a02f | ||
|
68655d60a6 | ||
|
63b0efcd81 | ||
|
93284682c8 | ||
|
3bafcb6ad2 | ||
|
942d027556 | ||
|
a60882d5f5 | ||
|
680f554981 | ||
|
20e4dc07ce | ||
|
184d8eb027 | ||
|
59725b088a | ||
|
32fca4a9f5 | ||
|
7dccf6ec48 | ||
|
917665feac | ||
|
06c50b68c2 | ||
|
7035c399d8 | ||
|
7c0ac5805c | ||
|
3424741583 | ||
|
baf0297994 | ||
|
31d06752fa | ||
|
8a27154798 | ||
|
6d87e38ec0 | ||
|
ccdc30a6fb | ||
|
90005538d3 | ||
|
f4e0428ebc | ||
|
bd1326eca9 | ||
|
bdfa834251 | ||
|
4a9aeb4e44 | ||
|
3886c0fbde | ||
|
d998eff56e | ||
|
d73df9bf0a | ||
|
754f2f3a34 | ||
|
43fd7c928a | ||
|
05768c2e73 | ||
|
3feb2c9955 | ||
|
7d9f3ac473 | ||
|
8a5755c8f1 | ||
|
a75a760019 | ||
|
78d1a130d2 | ||
|
79fd43f32b | ||
|
7a7bd65a27 | ||
|
01a9ecccac | ||
|
c1b3c71090 | ||
|
323d04fe6c | ||
|
80c2f1ea3f | ||
|
784494871d | ||
|
8e93af5cc7 | ||
|
ebfdeeedaa | ||
|
1d02ed6a56 | ||
|
cca53cb0e8 | ||
|
ab33aee4b1 | ||
|
41d4fab071 | ||
|
f0a1913dc6 | ||
|
b956b463c2 | ||
|
43603c4990 | ||
|
196e738f60 | ||
|
59e2ea357a | ||
|
5e9d942069 | ||
|
53d5bedd85 | ||
|
49c68af07b | ||
|
c84c8e1aef | ||
|
a8d43d7174 | ||
|
1087278890 | ||
|
ae5912ab52 | ||
|
035bd96ae5 | ||
|
7283c616a0 | ||
|
5706666bb6 | ||
|
4607466fb6 | ||
|
34bcfcfe9b | ||
|
05986cb6a6 | ||
|
0c4ee9f043 | ||
|
ff222795cf | ||
|
e0c76695ee | ||
|
ae126e8322 | ||
|
8f9c35fbe8 | ||
|
84efd6e2ee | ||
|
b1fbe4e909 | ||
|
8576877072 | ||
|
c298aced01 | ||
|
ac61a78d8d | ||
|
fce90a94c4 | ||
|
023a4f178d | ||
|
ef254995ad | ||
|
faeb74634b | ||
|
b5baae373f | ||
|
63de711cda | ||
|
bd28d116cb | ||
|
7efc2861bc | ||
|
5c689a2ca2 | ||
|
d5d65df76f | ||
|
df7d4f700c | ||
|
efebe3cb41 | ||
|
2ba5b6ae49 | ||
|
31d93efab2 | ||
|
657b95485c | ||
|
3bfc12f93b | ||
|
ccfd2f2ac3 | ||
|
fb3fe0d87b | ||
|
c80c6d52fe | ||
|
0fb3c0c7bf | ||
|
43c625bee2 | ||
|
967a5dd256 | ||
|
3c9d1bcaa1 | ||
|
8cd2de14a9 | ||
|
7728a35e04 | ||
|
49000da123 | ||
|
32a8f89875 | ||
|
49e5a81bd3 | ||
|
a8efe86af0 | ||
|
4f07b089d2 | ||
|
e786bf47c2 | ||
|
be11778c53 | ||
|
3d7325424c | ||
|
f4ffed99ef | ||
|
52dfe9a738 | ||
|
a0bc8b2ba2 | ||
|
4ffca9e2ca | ||
|
a6afec9afa | ||
|
5d859222f8 | ||
|
adbf785aba | ||
|
1fae39a49d | ||
|
659240a98b | ||
|
e9644c9679 |
@@ -19,26 +19,25 @@
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
use PhpCsFixer\Runner\Parallel\ParallelConfigFactory;
|
||||
|
||||
$current = __DIR__;
|
||||
|
||||
$paths = [
|
||||
$current . '/../../app',
|
||||
$current . '/../../config',
|
||||
$current . '/../../database',
|
||||
$current . '/../../routes',
|
||||
$current . '/../../tests',
|
||||
$current . '/../../resources/lang/en_US',
|
||||
];
|
||||
|
||||
$finder = PhpCsFixer\Finder::create()
|
||||
->in($paths);
|
||||
|
||||
|
||||
$config = new PhpCsFixer\Config();
|
||||
$config->setParallelConfig(ParallelConfigFactory::detect());
|
||||
$config = (new PhpCsFixer\Config())
|
||||
// ->setUnsupportedPhpVersionAllowed(true) // use this when PHP 8.5 comes out.
|
||||
->setParallelConfig(PhpCsFixer\Runner\Parallel\ParallelConfigFactory::detect())
|
||||
;
|
||||
return $config->setRules(
|
||||
|
||||
[
|
||||
// rule sets
|
||||
'@PHP83Migration' => true,
|
||||
@@ -53,9 +52,6 @@ return $config->setRules(
|
||||
'statement_indentation' => true,
|
||||
'void_return' => true,
|
||||
|
||||
// about importing statements
|
||||
'global_namespace_import' => ['import_classes' => true, 'import_constants' => true, 'import_functions' => true],
|
||||
|
||||
// disabled rules
|
||||
'native_function_invocation' => false, // annoying
|
||||
'php_unit_data_provider_name' => false, // bloody annoying long test names
|
||||
@@ -64,9 +60,15 @@ return $config->setRules(
|
||||
'comment_to_phpdoc' => false, // breaks phpstan lines in combination with PHPStorm.
|
||||
'type_declaration_spaces' => false,
|
||||
'cast_spaces' => false,
|
||||
'phpdoc_to_comment' => false, // do not overrule single line comment style, breaks phpstan.
|
||||
|
||||
// enabled rules
|
||||
'global_namespace_import' => true, // matches with rector.
|
||||
|
||||
// complex rules
|
||||
'phpdoc_to_comment' => ['ignored_tags' => ['var']],
|
||||
'php_unit_test_case_static_method_calls' => [
|
||||
'call_type' => 'this',
|
||||
],
|
||||
'array_syntax' => ['syntax' => 'short'],
|
||||
'binary_operator_spaces' => [
|
||||
'default' => 'at_least_single_space',
|
||||
@@ -76,5 +78,7 @@ return $config->setRules(
|
||||
'??=' => 'align_single_space_minimal_by_scope',
|
||||
],
|
||||
],
|
||||
])
|
||||
]
|
||||
|
||||
)
|
||||
->setFinder($finder);
|
||||
|
141
.ci/php-cs-fixer/composer.lock
generated
141
.ci/php-cs-fixer/composer.lock
generated
@@ -406,58 +406,59 @@
|
||||
},
|
||||
{
|
||||
"name": "friendsofphp/php-cs-fixer",
|
||||
"version": "v3.75.0",
|
||||
"version": "v3.85.1",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer.git",
|
||||
"reference": "399a128ff2fdaf4281e4e79b755693286cdf325c"
|
||||
"reference": "2fb6d7f6c3398dca5786a1635b27405d73a417ba"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/PHP-CS-Fixer/PHP-CS-Fixer/zipball/399a128ff2fdaf4281e4e79b755693286cdf325c",
|
||||
"reference": "399a128ff2fdaf4281e4e79b755693286cdf325c",
|
||||
"url": "https://api.github.com/repos/PHP-CS-Fixer/PHP-CS-Fixer/zipball/2fb6d7f6c3398dca5786a1635b27405d73a417ba",
|
||||
"reference": "2fb6d7f6c3398dca5786a1635b27405d73a417ba",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"clue/ndjson-react": "^1.0",
|
||||
"clue/ndjson-react": "^1.3",
|
||||
"composer/semver": "^3.4",
|
||||
"composer/xdebug-handler": "^3.0.3",
|
||||
"composer/xdebug-handler": "^3.0.5",
|
||||
"ext-filter": "*",
|
||||
"ext-hash": "*",
|
||||
"ext-json": "*",
|
||||
"ext-tokenizer": "*",
|
||||
"fidry/cpu-core-counter": "^1.2",
|
||||
"php": "^7.4 || ^8.0",
|
||||
"react/child-process": "^0.6.5",
|
||||
"react/event-loop": "^1.0",
|
||||
"react/promise": "^2.0 || ^3.0",
|
||||
"react/socket": "^1.0",
|
||||
"react/stream": "^1.0",
|
||||
"sebastian/diff": "^4.0 || ^5.1 || ^6.0 || ^7.0",
|
||||
"symfony/console": "^5.4 || ^6.4 || ^7.0",
|
||||
"symfony/event-dispatcher": "^5.4 || ^6.4 || ^7.0",
|
||||
"symfony/filesystem": "^5.4 || ^6.4 || ^7.0",
|
||||
"symfony/finder": "^5.4 || ^6.4 || ^7.0",
|
||||
"symfony/options-resolver": "^5.4 || ^6.4 || ^7.0",
|
||||
"symfony/polyfill-mbstring": "^1.31",
|
||||
"symfony/polyfill-php80": "^1.31",
|
||||
"symfony/polyfill-php81": "^1.31",
|
||||
"symfony/process": "^5.4 || ^6.4 || ^7.2",
|
||||
"symfony/stopwatch": "^5.4 || ^6.4 || ^7.0"
|
||||
"react/child-process": "^0.6.6",
|
||||
"react/event-loop": "^1.5",
|
||||
"react/promise": "^3.2",
|
||||
"react/socket": "^1.16",
|
||||
"react/stream": "^1.4",
|
||||
"sebastian/diff": "^4.0.6 || ^5.1.1 || ^6.0.2 || ^7.0",
|
||||
"symfony/console": "^5.4.47 || ^6.4.13 || ^7.0",
|
||||
"symfony/event-dispatcher": "^5.4.45 || ^6.4.13 || ^7.0",
|
||||
"symfony/filesystem": "^5.4.45 || ^6.4.13 || ^7.0",
|
||||
"symfony/finder": "^5.4.45 || ^6.4.17 || ^7.0",
|
||||
"symfony/options-resolver": "^5.4.45 || ^6.4.16 || ^7.0",
|
||||
"symfony/polyfill-mbstring": "^1.32",
|
||||
"symfony/polyfill-php80": "^1.32",
|
||||
"symfony/polyfill-php81": "^1.32",
|
||||
"symfony/process": "^5.4.47 || ^6.4.20 || ^7.2",
|
||||
"symfony/stopwatch": "^5.4.45 || ^6.4.19 || ^7.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"facile-it/paraunit": "^1.3.1 || ^2.6",
|
||||
"infection/infection": "^0.29.14",
|
||||
"justinrainbow/json-schema": "^5.3 || ^6.2",
|
||||
"keradus/cli-executor": "^2.1",
|
||||
"justinrainbow/json-schema": "^5.3 || ^6.4",
|
||||
"keradus/cli-executor": "^2.2",
|
||||
"mikey179/vfsstream": "^1.6.12",
|
||||
"php-coveralls/php-coveralls": "^2.7",
|
||||
"php-coveralls/php-coveralls": "^2.8",
|
||||
"php-cs-fixer/accessible-object": "^1.1",
|
||||
"php-cs-fixer/phpunit-constraint-isidenticalstring": "^1.6",
|
||||
"php-cs-fixer/phpunit-constraint-xmlmatchesxsd": "^1.6",
|
||||
"phpunit/phpunit": "^9.6.22 || ^10.5.45 || ^11.5.12",
|
||||
"symfony/var-dumper": "^5.4.48 || ^6.4.18 || ^7.2.3",
|
||||
"symfony/yaml": "^5.4.45 || ^6.4.18 || ^7.2.3"
|
||||
"phpunit/phpunit": "^9.6.23 || ^10.5.47 || ^11.5.25",
|
||||
"symfony/polyfill-php84": "^1.32",
|
||||
"symfony/var-dumper": "^5.4.48 || ^6.4.23 || ^7.3.1",
|
||||
"symfony/yaml": "^5.4.45 || ^6.4.23 || ^7.3.1"
|
||||
},
|
||||
"suggest": {
|
||||
"ext-dom": "For handling output formats in XML",
|
||||
@@ -498,7 +499,7 @@
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/issues",
|
||||
"source": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/tree/v3.75.0"
|
||||
"source": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/tree/v3.85.1"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
@@ -506,7 +507,7 @@
|
||||
"type": "github"
|
||||
}
|
||||
],
|
||||
"time": "2025-03-31T18:40:42+00:00"
|
||||
"time": "2025-07-29T22:22:50+00:00"
|
||||
},
|
||||
{
|
||||
"name": "psr/container",
|
||||
@@ -1256,16 +1257,16 @@
|
||||
},
|
||||
{
|
||||
"name": "symfony/console",
|
||||
"version": "v7.3.0",
|
||||
"version": "v7.3.2",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/console.git",
|
||||
"reference": "66c1440edf6f339fd82ed6c7caa76cb006211b44"
|
||||
"reference": "5f360ebc65c55265a74d23d7fe27f957870158a1"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/console/zipball/66c1440edf6f339fd82ed6c7caa76cb006211b44",
|
||||
"reference": "66c1440edf6f339fd82ed6c7caa76cb006211b44",
|
||||
"url": "https://api.github.com/repos/symfony/console/zipball/5f360ebc65c55265a74d23d7fe27f957870158a1",
|
||||
"reference": "5f360ebc65c55265a74d23d7fe27f957870158a1",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -1330,7 +1331,7 @@
|
||||
"terminal"
|
||||
],
|
||||
"support": {
|
||||
"source": "https://github.com/symfony/console/tree/v7.3.0"
|
||||
"source": "https://github.com/symfony/console/tree/v7.3.2"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
@@ -1341,12 +1342,16 @@
|
||||
"url": "https://github.com/fabpot",
|
||||
"type": "github"
|
||||
},
|
||||
{
|
||||
"url": "https://github.com/nicolas-grekas",
|
||||
"type": "github"
|
||||
},
|
||||
{
|
||||
"url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
|
||||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2025-05-24T10:34:04+00:00"
|
||||
"time": "2025-07-30T17:13:41+00:00"
|
||||
},
|
||||
{
|
||||
"name": "symfony/deprecation-contracts",
|
||||
@@ -1573,16 +1578,16 @@
|
||||
},
|
||||
{
|
||||
"name": "symfony/filesystem",
|
||||
"version": "v7.3.0",
|
||||
"version": "v7.3.2",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/filesystem.git",
|
||||
"reference": "b8dce482de9d7c9fe2891155035a7248ab5c7fdb"
|
||||
"reference": "edcbb768a186b5c3f25d0643159a787d3e63b7fd"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/filesystem/zipball/b8dce482de9d7c9fe2891155035a7248ab5c7fdb",
|
||||
"reference": "b8dce482de9d7c9fe2891155035a7248ab5c7fdb",
|
||||
"url": "https://api.github.com/repos/symfony/filesystem/zipball/edcbb768a186b5c3f25d0643159a787d3e63b7fd",
|
||||
"reference": "edcbb768a186b5c3f25d0643159a787d3e63b7fd",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -1619,7 +1624,7 @@
|
||||
"description": "Provides basic utilities for the filesystem",
|
||||
"homepage": "https://symfony.com",
|
||||
"support": {
|
||||
"source": "https://github.com/symfony/filesystem/tree/v7.3.0"
|
||||
"source": "https://github.com/symfony/filesystem/tree/v7.3.2"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
@@ -1630,25 +1635,29 @@
|
||||
"url": "https://github.com/fabpot",
|
||||
"type": "github"
|
||||
},
|
||||
{
|
||||
"url": "https://github.com/nicolas-grekas",
|
||||
"type": "github"
|
||||
},
|
||||
{
|
||||
"url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
|
||||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2024-10-25T15:15:23+00:00"
|
||||
"time": "2025-07-07T08:17:47+00:00"
|
||||
},
|
||||
{
|
||||
"name": "symfony/finder",
|
||||
"version": "v7.3.0",
|
||||
"version": "v7.3.2",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/finder.git",
|
||||
"reference": "ec2344cf77a48253bbca6939aa3d2477773ea63d"
|
||||
"reference": "2a6614966ba1074fa93dae0bc804227422df4dfe"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/finder/zipball/ec2344cf77a48253bbca6939aa3d2477773ea63d",
|
||||
"reference": "ec2344cf77a48253bbca6939aa3d2477773ea63d",
|
||||
"url": "https://api.github.com/repos/symfony/finder/zipball/2a6614966ba1074fa93dae0bc804227422df4dfe",
|
||||
"reference": "2a6614966ba1074fa93dae0bc804227422df4dfe",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -1683,7 +1692,7 @@
|
||||
"description": "Finds files and directories via an intuitive fluent interface",
|
||||
"homepage": "https://symfony.com",
|
||||
"support": {
|
||||
"source": "https://github.com/symfony/finder/tree/v7.3.0"
|
||||
"source": "https://github.com/symfony/finder/tree/v7.3.2"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
@@ -1694,25 +1703,29 @@
|
||||
"url": "https://github.com/fabpot",
|
||||
"type": "github"
|
||||
},
|
||||
{
|
||||
"url": "https://github.com/nicolas-grekas",
|
||||
"type": "github"
|
||||
},
|
||||
{
|
||||
"url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
|
||||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2024-12-30T19:00:26+00:00"
|
||||
"time": "2025-07-15T13:41:35+00:00"
|
||||
},
|
||||
{
|
||||
"name": "symfony/options-resolver",
|
||||
"version": "v7.3.0",
|
||||
"version": "v7.3.2",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/options-resolver.git",
|
||||
"reference": "afb9a8038025e5dbc657378bfab9198d75f10fca"
|
||||
"reference": "119bcf13e67dbd188e5dbc74228b1686f66acd37"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/options-resolver/zipball/afb9a8038025e5dbc657378bfab9198d75f10fca",
|
||||
"reference": "afb9a8038025e5dbc657378bfab9198d75f10fca",
|
||||
"url": "https://api.github.com/repos/symfony/options-resolver/zipball/119bcf13e67dbd188e5dbc74228b1686f66acd37",
|
||||
"reference": "119bcf13e67dbd188e5dbc74228b1686f66acd37",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -1750,7 +1763,7 @@
|
||||
"options"
|
||||
],
|
||||
"support": {
|
||||
"source": "https://github.com/symfony/options-resolver/tree/v7.3.0"
|
||||
"source": "https://github.com/symfony/options-resolver/tree/v7.3.2"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
@@ -1761,12 +1774,16 @@
|
||||
"url": "https://github.com/fabpot",
|
||||
"type": "github"
|
||||
},
|
||||
{
|
||||
"url": "https://github.com/nicolas-grekas",
|
||||
"type": "github"
|
||||
},
|
||||
{
|
||||
"url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
|
||||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2025-04-04T13:12:05+00:00"
|
||||
"time": "2025-07-15T11:36:08+00:00"
|
||||
},
|
||||
{
|
||||
"name": "symfony/polyfill-ctype",
|
||||
@@ -2451,16 +2468,16 @@
|
||||
},
|
||||
{
|
||||
"name": "symfony/string",
|
||||
"version": "v7.3.0",
|
||||
"version": "v7.3.2",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/string.git",
|
||||
"reference": "f3570b8c61ca887a9e2938e85cb6458515d2b125"
|
||||
"reference": "42f505aff654e62ac7ac2ce21033818297ca89ca"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/string/zipball/f3570b8c61ca887a9e2938e85cb6458515d2b125",
|
||||
"reference": "f3570b8c61ca887a9e2938e85cb6458515d2b125",
|
||||
"url": "https://api.github.com/repos/symfony/string/zipball/42f505aff654e62ac7ac2ce21033818297ca89ca",
|
||||
"reference": "42f505aff654e62ac7ac2ce21033818297ca89ca",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -2518,7 +2535,7 @@
|
||||
"utf8"
|
||||
],
|
||||
"support": {
|
||||
"source": "https://github.com/symfony/string/tree/v7.3.0"
|
||||
"source": "https://github.com/symfony/string/tree/v7.3.2"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
@@ -2529,12 +2546,16 @@
|
||||
"url": "https://github.com/fabpot",
|
||||
"type": "github"
|
||||
},
|
||||
{
|
||||
"url": "https://github.com/nicolas-grekas",
|
||||
"type": "github"
|
||||
},
|
||||
{
|
||||
"url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
|
||||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2025-04-20T20:19:01+00:00"
|
||||
"time": "2025-07-10T08:47:49+00:00"
|
||||
}
|
||||
],
|
||||
"packages-dev": [],
|
||||
|
@@ -26,9 +26,10 @@ SCRIPT_DIR="$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )
|
||||
cd $SCRIPT_DIR/php-cs-fixer
|
||||
composer update --quiet
|
||||
rm -f .php-cs-fixer.cache
|
||||
PHP_CS_FIXER_IGNORE_ENV=true ./vendor/bin/php-cs-fixer fix \
|
||||
./vendor/bin/php-cs-fixer fix \
|
||||
--config $SCRIPT_DIR/php-cs-fixer/.php-cs-fixer.php \
|
||||
--format=txt -v \
|
||||
--format=txt \
|
||||
-v \
|
||||
--allow-risky=yes
|
||||
|
||||
EXIT_CODE=$?
|
||||
|
@@ -25,6 +25,7 @@ declare(strict_types=1);
|
||||
|
||||
use Rector\Config\RectorConfig;
|
||||
use Rector\EarlyReturn\Rector\If_\ChangeOrIfContinueToMultiContinueRector;
|
||||
use Rector\Php80\Rector\ClassMethod\AddParamBasedOnParentClassMethodRector;
|
||||
use Rector\Transform\Rector\String_\StringToClassConstantRector;
|
||||
use RectorLaravel\Set\LaravelLevelSetList;
|
||||
|
||||
@@ -32,6 +33,7 @@ use RectorLaravel\Set\LaravelLevelSetList;
|
||||
return RectorConfig::configure()
|
||||
->withSkip([
|
||||
ChangeOrIfContinueToMultiContinueRector::class,
|
||||
AddParamBasedOnParentClassMethodRector::class,
|
||||
StringToClassConstantRector::class => [
|
||||
__DIR__ . '/../app/Http/Controllers/Auth/LoginController.php',
|
||||
],
|
||||
|
@@ -329,7 +329,7 @@ FIREFLY_III_LAYOUT=v1
|
||||
# Which Query Parser implementation to use for the search engine and rules
|
||||
# 'new' is experimental, 'legacy' is the classic one
|
||||
#
|
||||
QUERY_PARSER_IMPLEMENTATION=legacy
|
||||
QUERY_PARSER_IMPLEMENTATION=new
|
||||
|
||||
#
|
||||
# Please make sure this URL matches the external URL of your Firefly III installation.
|
||||
|
13
.github/ISSUE_TEMPLATE/bug.yml
vendored
13
.github/ISSUE_TEMPLATE/bug.yml
vendored
@@ -1,4 +1,4 @@
|
||||
name: Bug Report
|
||||
name: Bug report
|
||||
description: Report a bug in Firefly III (or associated tools)
|
||||
body:
|
||||
- type: checkboxes
|
||||
@@ -12,7 +12,7 @@ body:
|
||||
- type: checkboxes
|
||||
attributes:
|
||||
label: I've found a bug and checked that ...
|
||||
description: Make sure that your request fulfills all of the following requirements. If one requirement cannot be satisfied, explain in detail why.
|
||||
description: Make sure that your request fulfills all of the following requirements. If one requirement cannot be satisfied, please explain why.
|
||||
options:
|
||||
- label: ... [the documentation](https://docs.firefly-iii.org/) does not mention anything about my problem
|
||||
- label: ... there are no open or closed issues that are related to my problem
|
||||
@@ -33,13 +33,6 @@ body:
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: Expected behaviour
|
||||
description: Please describe precisely what you'd expect to happen. Be specific.
|
||||
validations:
|
||||
required: false
|
||||
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: Steps to reproduce
|
||||
@@ -54,4 +47,4 @@ body:
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: Additional info
|
||||
description: Please provide any additional information that seem useful.
|
||||
description: Please provide any additional information that seems useful.
|
||||
|
3
.github/ISSUE_TEMPLATE/config.yml
vendored
3
.github/ISSUE_TEMPLATE/config.yml
vendored
@@ -3,3 +3,6 @@ contact_links:
|
||||
- name: Ask a question
|
||||
url: https://github.com/firefly-iii/firefly-iii/discussions
|
||||
about: Please ask and answer questions here.
|
||||
- name: I need support!
|
||||
url: https://github.com/firefly-iii/firefly-iii/discussions
|
||||
about: I think I broke something...
|
||||
|
7
.github/ISSUE_TEMPLATE/fr.yml
vendored
7
.github/ISSUE_TEMPLATE/fr.yml
vendored
@@ -1,4 +1,4 @@
|
||||
name: Feature Request
|
||||
name: Feature request
|
||||
description: Request a feature or enhancement in Firefly III (or associated tools)
|
||||
body:
|
||||
- type: checkboxes
|
||||
@@ -31,11 +31,6 @@ body:
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: What are alternatives?
|
||||
description: Please describe what alternatives currently exist.
|
||||
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: Additional context
|
||||
|
1
.github/workflows/cleanup.yml
vendored
1
.github/workflows/cleanup.yml
vendored
@@ -66,7 +66,6 @@ jobs:
|
||||
'label-actions.yml',
|
||||
'lock.yml',
|
||||
'release.yml',
|
||||
'sonarcloud.yml',
|
||||
'stale.yml'
|
||||
]
|
||||
|
||||
|
28
.github/workflows/release.yml
vendored
28
.github/workflows/release.yml
vendored
@@ -259,6 +259,12 @@ jobs:
|
||||
echo "* Or read the upgrade instructions for [Docker](https://docs.firefly-iii.org/how-to/firefly-iii/upgrade/docker/), [Kubernetes](https://docs.firefly-iii.org/how-to/firefly-iii/upgrade/kubernetes/) or [self-managed servers](https://docs.firefly-iii.org/how-to/firefly-iii/upgrade/self-managed/)" >> output.txt
|
||||
echo "" >> output.txt
|
||||
echo ":warning: Please be careful with this pre-release, as it may not work as expected." >> output.txt
|
||||
|
||||
# donations!
|
||||
echo '' >> output.txt
|
||||
echo '### Support Firefly III' >> output.txt
|
||||
echo 'Did you know you can support the development of Firefly III? You can donate in many ways, like GitHub Sponsors or Patreon. For more information, please [follow this link](https://bit.ly/donate-to-Firefly-III) for more information.' >> output.txt
|
||||
echo '' >> output.txt
|
||||
fi
|
||||
# describe a branch release
|
||||
if [[ "$version" == branch* ]]; then
|
||||
@@ -279,16 +285,31 @@ jobs:
|
||||
if [[ "develop" != "$version" ]] && [[ "$version" != branch* ]] && [[ "$version" != *alpha* ]] && [[ "$version" != *beta* ]]; then
|
||||
echo 'Describe the latest release'
|
||||
sudo chown -R runner:docker output.txt
|
||||
|
||||
# the changelog is in output.txt
|
||||
mv output.txt output2.txt
|
||||
|
||||
touch output.txt
|
||||
echo '' >> output.txt
|
||||
echo "Welcome to release $version of Firefly III. It contains the the latest fixes, translations and features. Docker users can find this release under the \`latest\` tag." >> output.txt
|
||||
echo '' >> output.txt
|
||||
|
||||
# add changelog to file.
|
||||
cat output2.txt >> output.txt
|
||||
echo '' >> output.txt
|
||||
rm -f output2.txt
|
||||
|
||||
echo '### Instructions' >> output.txt
|
||||
echo '' >> output.txt
|
||||
echo "* Installation instructions for [Docker](https://docs.firefly-iii.org/how-to/firefly-iii/installation/docker/), [Portainer](https://docs.firefly-iii.org/how-to/firefly-iii/installation/portainer/), [Kubernetes](https://docs.firefly-iii.org/how-to/firefly-iii/installation/kubernetes/) or [self-managed servers](https://docs.firefly-iii.org/how-to/firefly-iii/installation/self-managed/)" >> output.txt
|
||||
echo "* Or read the upgrade instructions for [Docker](https://docs.firefly-iii.org/how-to/firefly-iii/upgrade/docker/), [Kubernetes](https://docs.firefly-iii.org/how-to/firefly-iii/upgrade/kubernetes/) or [self-managed servers](https://docs.firefly-iii.org/how-to/firefly-iii/upgrade/self-managed/)" >> output.txt
|
||||
echo "* The releases are signed, and you can verify them using the [Firefly III releases PGP key](https://docs.firefly-iii.org/explanation/more-information/signatures/)." >> output.txt
|
||||
|
||||
# donations!
|
||||
echo '' >> output.txt
|
||||
echo '### Support Firefly III' >> output.txt
|
||||
echo 'Did you know you can support the development of Firefly III? You can donate in many ways, like GitHub Sponsors or Patreon. For more information, please [follow this link](https://bit.ly/donate-to-Firefly-III) for more information.' >> output.txt
|
||||
echo '' >> output.txt
|
||||
fi
|
||||
|
||||
# describe alpha release
|
||||
@@ -465,20 +486,27 @@ jobs:
|
||||
- name: Upload artifacts
|
||||
run: |
|
||||
# add zip file to release.
|
||||
echo "Upload $zipName to $releaseName"
|
||||
gh release upload $releaseName $zipName
|
||||
echo "Upload $tarName to $releaseName"
|
||||
gh release upload $releaseName $tarName
|
||||
|
||||
# add sha256 sum to release
|
||||
echo "Upload $zipName.sha256 to $releaseName"
|
||||
gh release upload $releaseName $zipName.sha256
|
||||
echo "Upload $tarName.sha256 to $releaseName"
|
||||
gh release upload $releaseName $tarName.sha256
|
||||
|
||||
# add signatures to release
|
||||
echo "Upload $zipName.asc to $releaseName"
|
||||
gh release upload $releaseName $zipName.asc
|
||||
echo "Upload $tarName.asc to $releaseName"
|
||||
gh release upload $releaseName $tarName.asc
|
||||
|
||||
# get current HEAD and add as file to the release
|
||||
HEAD=$(git rev-parse HEAD)
|
||||
echo $HEAD > HEAD.txt
|
||||
echo "Upload HEAD.txt to $releaseName"
|
||||
gh release upload $releaseName HEAD.txt
|
||||
|
||||
# remove all temporary files
|
||||
|
71
.github/workflows/sonarcloud.yml
vendored
71
.github/workflows/sonarcloud.yml
vendored
@@ -1,71 +0,0 @@
|
||||
name: 'Code - Run Sonarcloud'
|
||||
on:
|
||||
pull_request:
|
||||
workflow_dispatch:
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
env:
|
||||
DB_CONNECTION: sqlite
|
||||
APP_KEY: TestTestTestTestTestTestTestTest
|
||||
jobs:
|
||||
sonarcloud:
|
||||
name: SonarCloud
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
- name: Setup PHP with Xdebug
|
||||
uses: shivammathur/setup-php@v2
|
||||
with:
|
||||
php-version: '8.4'
|
||||
coverage: xdebug
|
||||
extensions: >-
|
||||
bcmath
|
||||
curl
|
||||
fileinfo
|
||||
iconv
|
||||
intl
|
||||
json
|
||||
sqlite3
|
||||
mbstring
|
||||
openssl
|
||||
pdo
|
||||
session
|
||||
simplexml
|
||||
sodium
|
||||
tokenizer
|
||||
xml
|
||||
xmlwriter
|
||||
|
||||
- name: Copy standard configuration
|
||||
run: cp .env.testing .env
|
||||
|
||||
- name: Install Composer dependencies
|
||||
run: composer install --prefer-dist --no-interaction --no-progress --no-scripts
|
||||
|
||||
- name: "Create database file"
|
||||
run: |
|
||||
touch storage/database/database.sqlite
|
||||
wget -q https://github.com/firefly-iii/test-fixtures/raw/refs/heads/main/test-database.sqlite -O storage/database/database.sqlite
|
||||
|
||||
- name: "Upgrades the database to the latest version"
|
||||
run: |
|
||||
php artisan firefly-iii:upgrade-database
|
||||
chmod 600 storage/oauth-public.key
|
||||
chmod 600 storage/oauth-private.key
|
||||
|
||||
- name: "Integrity Database Report"
|
||||
run: php artisan firefly-iii:report-integrity
|
||||
|
||||
- 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/sonarqube-scan-action@v5.2.0
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GH_ACTIONS_PERSONAL_ACCESS_TOKEN }}
|
||||
SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
|
@@ -24,6 +24,7 @@ declare(strict_types=1);
|
||||
|
||||
namespace FireflyIII\Api\V1\Controllers\Autocomplete;
|
||||
|
||||
use Deprecated;
|
||||
use FireflyIII\Api\V1\Controllers\Controller;
|
||||
use FireflyIII\Api\V1\Requests\Autocomplete\AutocompleteRequest;
|
||||
use FireflyIII\Models\TransactionCurrency;
|
||||
@@ -83,9 +84,8 @@ class CurrencyController extends Controller
|
||||
/**
|
||||
* Documentation for this endpoint is at:
|
||||
* https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/autocomplete/getCurrenciesCodeAC
|
||||
*
|
||||
* @deprecated
|
||||
*/
|
||||
#[Deprecated]
|
||||
public function currenciesWithCode(AutocompleteRequest $request): JsonResponse
|
||||
{
|
||||
$data = $request->getData();
|
||||
|
@@ -24,22 +24,25 @@ declare(strict_types=1);
|
||||
|
||||
namespace FireflyIII\Api\V1\Controllers\Chart;
|
||||
|
||||
use FireflyIII\Models\TransactionCurrency;
|
||||
use Carbon\Carbon;
|
||||
use FireflyIII\Api\V1\Controllers\Controller;
|
||||
use FireflyIII\Api\V1\Requests\Chart\ChartRequest;
|
||||
use FireflyIII\Api\V1\Requests\Data\DateRequest;
|
||||
use FireflyIII\Enums\AccountTypeEnum;
|
||||
use FireflyIII\Exceptions\FireflyException;
|
||||
use FireflyIII\Exceptions\ValidationException;
|
||||
use FireflyIII\Models\Account;
|
||||
use FireflyIII\Models\Preference;
|
||||
use FireflyIII\Models\TransactionCurrency;
|
||||
use FireflyIII\Repositories\Account\AccountRepositoryInterface;
|
||||
use FireflyIII\Support\Chart\ChartData;
|
||||
use FireflyIII\Support\Facades\Preferences;
|
||||
use FireflyIII\Support\Facades\Steam;
|
||||
use FireflyIII\Support\Http\Api\ApiSupport;
|
||||
use FireflyIII\Support\Http\Api\CollectsAccountsFromFilter;
|
||||
use FireflyIII\User;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
|
||||
/**
|
||||
* Class AccountController
|
||||
@@ -84,10 +87,12 @@ class AccountController extends Controller
|
||||
// move date to end of day
|
||||
$queryParameters['start']->startOfDay();
|
||||
$queryParameters['end']->endOfDay();
|
||||
Log::debug(sprintf('dashboard(), convert to native: %s', var_export($this->convertToNative, true)));
|
||||
|
||||
// loop each account, and collect info:
|
||||
/** @var Account $account */
|
||||
foreach ($accounts as $account) {
|
||||
Log::debug(sprintf('Account #%d ("%s")', $account->id, $account->name));
|
||||
$this->renderAccountData($queryParameters, $account);
|
||||
}
|
||||
|
||||
@@ -99,15 +104,22 @@ class AccountController extends Controller
|
||||
*/
|
||||
private function renderAccountData(array $params, Account $account): void
|
||||
{
|
||||
$currency = $this->repository->getAccountCurrency($account);
|
||||
Log::debug(sprintf('Now in %s(array, #%d)', __METHOD__, $account->id));
|
||||
$currency = $this->repository->getAccountCurrency($account);
|
||||
$currentStart = clone $params['start'];
|
||||
$range = Steam::finalAccountBalanceInRange($account, $params['start'], clone $params['end'], $this->convertToNative);
|
||||
|
||||
|
||||
$previous = array_values($range)[0]['balance'];
|
||||
$nativePrevious = null;
|
||||
if (!$currency instanceof TransactionCurrency) {
|
||||
$currency = $this->default;
|
||||
}
|
||||
$currentSet = [
|
||||
$currentSet = [
|
||||
'label' => $account->name,
|
||||
|
||||
// the currency that belongs to the account.
|
||||
'currency_id' => (string) $currency->id,
|
||||
'currency_id' => (string)$currency->id,
|
||||
'currency_code' => $currency->code,
|
||||
'currency_symbol' => $currency->symbol,
|
||||
'currency_decimal_places' => $currency->decimal_places,
|
||||
@@ -119,18 +131,33 @@ class AccountController extends Controller
|
||||
'period' => '1D',
|
||||
'entries' => [],
|
||||
];
|
||||
$currentStart = clone $params['start'];
|
||||
$range = Steam::finalAccountBalanceInRange($account, $params['start'], clone $params['end'], $this->convertToNative);
|
||||
if ($this->convertToNative) {
|
||||
$currentSet['native_entries'] = [];
|
||||
$currentSet['native_currency_id'] = (string)$this->nativeCurrency->id;
|
||||
$currentSet['native_currency_code'] = $this->nativeCurrency->code;
|
||||
$currentSet['native_currency_symbol'] = $this->nativeCurrency->symbol;
|
||||
$currentSet['native_currency_decimal_places'] = $this->nativeCurrency->decimal_places;
|
||||
$nativePrevious = array_values($range)[0]['native_balance'];
|
||||
}
|
||||
|
||||
|
||||
$previous = array_values($range)[0]['balance'];
|
||||
while ($currentStart <= $params['end']) {
|
||||
$format = $currentStart->format('Y-m-d');
|
||||
$label = $currentStart->toAtomString();
|
||||
$balance = array_key_exists($format, $range) ? $range[$format]['balance'] : $previous;
|
||||
$previous = $balance;
|
||||
$currentSet['entries'][$label] = $balance;
|
||||
|
||||
|
||||
// do the same for the native balance, if relevant:
|
||||
$nativeBalance = null;
|
||||
if ($this->convertToNative) {
|
||||
$nativeBalance = array_key_exists($format, $range) ? $range[$format]['native_balance'] : $nativePrevious;
|
||||
$nativePrevious = $nativeBalance;
|
||||
$currentSet['native_entries'][$label] = $nativeBalance;
|
||||
}
|
||||
|
||||
$currentStart->addDay();
|
||||
$currentSet['entries'][$label] = $balance;
|
||||
}
|
||||
$this->chartData->add($currentSet);
|
||||
}
|
||||
@@ -139,45 +166,39 @@ class AccountController extends Controller
|
||||
* This endpoint is documented at:
|
||||
* https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/charts/getChartAccountOverview
|
||||
*
|
||||
* @throws FireflyException
|
||||
* @throws ValidationException
|
||||
*/
|
||||
public function overview(DateRequest $request): JsonResponse
|
||||
{
|
||||
// parameters for chart:
|
||||
$dates = $request->getAll();
|
||||
$dates = $request->getAll();
|
||||
|
||||
|
||||
/** @var Carbon $start */
|
||||
$start = $dates['start'];
|
||||
$start = $dates['start'];
|
||||
|
||||
/** @var Carbon $end */
|
||||
$end = $dates['end'];
|
||||
$end = $dates['end'];
|
||||
|
||||
// set dates to end of day + start of day:
|
||||
$start->startOfDay();
|
||||
$end->endOfDay();
|
||||
|
||||
// user's preferences
|
||||
$defaultSet = $this->repository->getAccountsByType([AccountTypeEnum::ASSET->value])->pluck('id')->toArray();
|
||||
|
||||
/** @var Preference $frontpage */
|
||||
$frontpage = app('preferences')->get('frontpageAccounts', $defaultSet);
|
||||
|
||||
if (!(is_array($frontpage->data) && count($frontpage->data) > 0)) {
|
||||
$frontpage->data = $defaultSet;
|
||||
$frontpage->save();
|
||||
}
|
||||
|
||||
// get accounts:
|
||||
$accounts = $this->repository->getAccountsById($frontpage->data);
|
||||
$chartData = [];
|
||||
$frontPageIds = $this->getFrontPageAccountIds();
|
||||
$accounts = $this->repository->getAccountsById($frontPageIds);
|
||||
$chartData = [];
|
||||
|
||||
/** @var Account $account */
|
||||
foreach ($accounts as $account) {
|
||||
$currency = $this->repository->getAccountCurrency($account) ?? $this->nativeCurrency;
|
||||
$field = $this->convertToNative && $currency->id !== $this->nativeCurrency->id ? 'native_balance' : 'balance';
|
||||
$currentSet = [
|
||||
Log::debug(sprintf('Rendering chart data for account %s (%d)', $account->name, $account->id));
|
||||
$currency = $this->repository->getAccountCurrency($account) ?? $this->nativeCurrency;
|
||||
$currentStart = clone $start;
|
||||
$range = Steam::finalAccountBalanceInRange($account, $start, clone $end, $this->convertToNative);
|
||||
$previous = array_values($range)[0]['balance'];
|
||||
$nativePrevious = null;
|
||||
$currentSet = [
|
||||
'label' => $account->name,
|
||||
'currency_id' => (string) $currency->id,
|
||||
'currency_id' => (string)$currency->id,
|
||||
'currency_code' => $currency->code,
|
||||
'currency_symbol' => $currency->symbol,
|
||||
'currency_decimal_places' => $currency->decimal_places,
|
||||
@@ -187,21 +208,57 @@ class AccountController extends Controller
|
||||
'yAxisID' => 0, // 0, 1, 2
|
||||
'entries' => [],
|
||||
];
|
||||
// TODO this code is also present in the V2 chart account controller so this method is due to be deprecated.
|
||||
$currentStart = clone $start;
|
||||
$range = Steam::finalAccountBalanceInRange($account, $start, clone $end, $this->convertToNative);
|
||||
$previous = array_values($range)[0][$field];
|
||||
|
||||
// add "native_entries" if convertToNative is true:
|
||||
if ($this->convertToNative) {
|
||||
$currentSet['native_entries'] = [];
|
||||
$currentSet['native_currency_id'] = (string)$this->nativeCurrency->id;
|
||||
$currentSet['native_currency_code'] = $this->nativeCurrency->code;
|
||||
$currentSet['native_currency_symbol'] = $this->nativeCurrency->symbol;
|
||||
$currentSet['native_currency_decimal_places'] = $this->nativeCurrency->decimal_places;
|
||||
$nativePrevious = array_values($range)[0]['native_balance'];
|
||||
|
||||
}
|
||||
|
||||
// also get the native balance if convertToNative is true:
|
||||
while ($currentStart <= $end) {
|
||||
$format = $currentStart->format('Y-m-d');
|
||||
$label = $currentStart->toAtomString();
|
||||
$balance = array_key_exists($format, $range) ? $range[$format][$field] : $previous;
|
||||
|
||||
// balance is based on "balance" from the $range variable.
|
||||
$balance = array_key_exists($format, $range) ? $range[$format]['balance'] : $previous;
|
||||
$previous = $balance;
|
||||
$currentStart->addDay();
|
||||
$currentSet['entries'][$label] = $balance;
|
||||
|
||||
// do the same for the native balance, if relevant:
|
||||
$nativeBalance = null;
|
||||
if ($this->convertToNative) {
|
||||
$nativeBalance = array_key_exists($format, $range) ? $range[$format]['native_balance'] : $nativePrevious;
|
||||
$nativePrevious = $nativeBalance;
|
||||
$currentSet['native_entries'][$label] = $nativeBalance;
|
||||
}
|
||||
|
||||
$currentStart->addDay();
|
||||
|
||||
}
|
||||
$chartData[] = $currentSet;
|
||||
$chartData[] = $currentSet;
|
||||
}
|
||||
|
||||
return response()->json($chartData);
|
||||
}
|
||||
|
||||
private function getFrontPageAccountIds(): array
|
||||
{
|
||||
$defaultSet = $this->repository->getAccountsByType([AccountTypeEnum::ASSET->value])->pluck('id')->toArray();
|
||||
|
||||
/** @var Preference $frontpage */
|
||||
$frontpage = Preferences::get('frontpageAccounts', $defaultSet);
|
||||
|
||||
if (!(is_array($frontpage->data) && count($frontpage->data) > 0)) {
|
||||
$frontpage->data = $defaultSet;
|
||||
$frontpage->save();
|
||||
}
|
||||
|
||||
return $frontpage->data ?? $defaultSet;
|
||||
}
|
||||
}
|
||||
|
@@ -36,6 +36,7 @@ use FireflyIII\Repositories\Budget\BudgetLimitRepositoryInterface;
|
||||
use FireflyIII\Repositories\Budget\BudgetRepositoryInterface;
|
||||
use FireflyIII\Repositories\Budget\OperationsRepositoryInterface;
|
||||
use FireflyIII\Support\Http\Api\CleansChartData;
|
||||
use FireflyIII\Support\Http\Api\ExchangeRateConverter;
|
||||
use FireflyIII\Support\Http\Api\ValidatesUserGroupTrait;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Support\Collection;
|
||||
@@ -77,6 +78,8 @@ class BudgetController extends Controller
|
||||
|
||||
/**
|
||||
* TODO see autocomplete/accountcontroller
|
||||
*
|
||||
* @throws FireflyException
|
||||
*/
|
||||
public function dashboard(DateRequest $request): JsonResponse
|
||||
{
|
||||
@@ -107,23 +110,41 @@ class BudgetController extends Controller
|
||||
private function processBudget(Budget $budget, Carbon $start, Carbon $end): array
|
||||
{
|
||||
// get all limits:
|
||||
$limits = $this->blRepository->getBudgetLimits($budget, $start, $end);
|
||||
$rows = [];
|
||||
$limits = $this->blRepository->getBudgetLimits($budget, $start, $end);
|
||||
$rows = [];
|
||||
$spent = $this->opsRepository->listExpenses($start, $end, null, new Collection([$budget]));
|
||||
$expenses = $this->processExpenses($budget->id, $spent, $start, $end);
|
||||
|
||||
/**
|
||||
* @var int $currencyId
|
||||
* @var array $row
|
||||
*/
|
||||
foreach ($expenses as $currencyId => $row) {
|
||||
// budgeted, left and overspent are now 0.
|
||||
$limit = $this->filterLimit($currencyId, $limits);
|
||||
if (null !== $limit) {
|
||||
$row['budgeted'] = $limit->amount;
|
||||
$row['left'] = bcsub($row['budgeted'], bcmul($row['spent'], '-1'));
|
||||
$row['overspent'] = bcmul($row['left'], '-1');
|
||||
$row['left'] = 1 === bccomp($row['left'], '0') ? $row['left'] : '0';
|
||||
$row['overspent'] = 1 === bccomp($row['overspent'], '0') ? $row['overspent'] : '0';
|
||||
}
|
||||
$rows[] = $row;
|
||||
}
|
||||
|
||||
|
||||
// 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);
|
||||
}
|
||||
// if (0 === $limits->count()) {
|
||||
// return as a single item in an array
|
||||
// $rows = $this->noBudgetLimits($budget, $start, $end);
|
||||
// }
|
||||
|
||||
// is always an array
|
||||
$return = [];
|
||||
$return = [];
|
||||
foreach ($rows as $row) {
|
||||
$current = [
|
||||
'label' => $budget->name,
|
||||
'currency_id' => (string) $row['currency_id'],
|
||||
'currency_id' => (string)$row['currency_id'],
|
||||
'currency_code' => $row['currency_code'],
|
||||
'currency_name' => $row['currency_name'],
|
||||
'currency_decimal_places' => $row['currency_decimal_places'],
|
||||
@@ -131,6 +152,7 @@ class BudgetController extends Controller
|
||||
'start' => $row['start'],
|
||||
'end' => $row['end'],
|
||||
'entries' => [
|
||||
'budgeted' => $row['budgeted'],
|
||||
'spent' => $row['spent'],
|
||||
'left' => $row['left'],
|
||||
'overspent' => $row['overspent'],
|
||||
@@ -159,11 +181,9 @@ class BudgetController extends Controller
|
||||
* Shared between the "noBudgetLimits" function and "processLimit". Will take a single set of expenses and return
|
||||
* its info.
|
||||
*
|
||||
* @param array<int, array<int, string>> $array
|
||||
*
|
||||
* @throws FireflyException
|
||||
*/
|
||||
private function processExpenses(int $budgetId, array $array, Carbon $start, Carbon $end): array
|
||||
private function processExpenses(int $budgetId, array $spent, Carbon $start, Carbon $end): array
|
||||
{
|
||||
$return = [];
|
||||
|
||||
@@ -174,16 +194,17 @@ class BudgetController extends Controller
|
||||
* @var int $currencyId
|
||||
* @var array $block
|
||||
*/
|
||||
foreach ($array as $currencyId => $block) {
|
||||
foreach ($spent as $currencyId => $block) {
|
||||
$this->currencies[$currencyId] ??= TransactionCurrency::find($currencyId);
|
||||
$return[$currencyId] ??= [
|
||||
'currency_id' => (string) $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'],
|
||||
'currency_decimal_places' => (int)$block['currency_decimal_places'],
|
||||
'start' => $start->toAtomString(),
|
||||
'end' => $end->toAtomString(),
|
||||
'budgeted' => '0',
|
||||
'spent' => '0',
|
||||
'left' => '0',
|
||||
'overspent' => '0',
|
||||
@@ -193,7 +214,7 @@ class BudgetController extends Controller
|
||||
// var_dump($return);
|
||||
/** @var array $journal */
|
||||
foreach ($currentBudgetArray['transaction_journals'] as $journal) {
|
||||
$return[$currencyId]['spent'] = bcadd($return[$currencyId]['spent'], (string) $journal['amount']);
|
||||
$return[$currencyId]['spent'] = bcadd($return[$currencyId]['spent'], (string)$journal['amount']);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -233,28 +254,59 @@ class BudgetController extends Controller
|
||||
$end->endOfDay();
|
||||
$spent = $this->opsRepository->listExpenses($limit->start_date, $end, null, new Collection([$budget]));
|
||||
$limitCurrencyId = $limit->transaction_currency_id;
|
||||
$filtered = [];
|
||||
|
||||
/** @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;
|
||||
}
|
||||
}
|
||||
// only spent the entry where the entry's currency matches the budget limit's currency
|
||||
// so $filtered will only have 1 or 0 entries
|
||||
$filtered = array_filter($spent, fn ($entry) => $entry['currency_id'] === $limitCurrencyId);
|
||||
$result = $this->processExpenses($budget->id, $filtered, $limit->start_date, $end);
|
||||
if (1 === count($result)) {
|
||||
$compare = bccomp($limit->amount, (string) app('steam')->positive($result[$limitCurrencyId]['spent']));
|
||||
$compare = bccomp($limit->amount, (string)app('steam')->positive($result[$limitCurrencyId]['spent']));
|
||||
$result[$limitCurrencyId]['budgeted'] = $limit->amount;
|
||||
if (1 === $compare) {
|
||||
// convert this amount into the native currency:
|
||||
$result[$limitCurrencyId]['left'] = bcadd($limit->amount, (string) $result[$limitCurrencyId]['spent']);
|
||||
$result[$limitCurrencyId]['left'] = bcadd($limit->amount, (string)$result[$limitCurrencyId]['spent']);
|
||||
}
|
||||
if ($compare <= 0) {
|
||||
$result[$limitCurrencyId]['overspent'] = app('steam')->positive(bcadd($limit->amount, (string) $result[$limitCurrencyId]['spent']));
|
||||
$result[$limitCurrencyId]['overspent'] = app('steam')->positive(bcadd($limit->amount, (string)$result[$limitCurrencyId]['spent']));
|
||||
}
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
private function filterLimit(int $currencyId, Collection $limits): ?BudgetLimit
|
||||
{
|
||||
$amount = '0';
|
||||
$limit = null;
|
||||
$converter = new ExchangeRateConverter();
|
||||
|
||||
/** @var BudgetLimit $current */
|
||||
foreach ($limits as $current) {
|
||||
if (true === $this->convertToNative) {
|
||||
if ($current->transaction_currency_id === $this->nativeCurrency->id) {
|
||||
// simply add it.
|
||||
$amount = bcadd($amount, (string)$current->amount);
|
||||
Log::debug(sprintf('Set amount in limit to %s', $amount));
|
||||
}
|
||||
if ($current->transaction_currency_id !== $this->nativeCurrency->id) {
|
||||
// convert and then add it.
|
||||
$converted = $converter->convert($current->transactionCurrency, $this->nativeCurrency, $limit->start_date, $limit->amount);
|
||||
$amount = bcadd($amount, $converted);
|
||||
Log::debug(sprintf('Budgeted in limit #%d: %s %s, converted to %s %s', $current->id, $current->transactionCurrency->code, $current->amount, $this->nativeCurrency->code, $converted));
|
||||
Log::debug(sprintf('Set amount in limit to %s', $amount));
|
||||
}
|
||||
}
|
||||
if ($current->transaction_currency_id === $currencyId) {
|
||||
$limit = $current;
|
||||
}
|
||||
}
|
||||
if (null !== $limit && true === $this->convertToNative) {
|
||||
// convert and add all amounts.
|
||||
$limit->amount = app('steam')->positive($amount);
|
||||
Log::debug(sprintf('Final amount in limit with converted amount %s', $limit->amount));
|
||||
}
|
||||
|
||||
return $limit;
|
||||
}
|
||||
}
|
||||
|
@@ -25,17 +25,20 @@ declare(strict_types=1);
|
||||
namespace FireflyIII\Api\V1\Controllers\Chart;
|
||||
|
||||
use Carbon\Carbon;
|
||||
use FireflyIII\Api\V2\Controllers\Controller;
|
||||
use FireflyIII\Api\V1\Controllers\Controller;
|
||||
use FireflyIII\Api\V2\Request\Generic\DateRequest;
|
||||
use FireflyIII\Enums\AccountTypeEnum;
|
||||
use FireflyIII\Enums\TransactionTypeEnum;
|
||||
use FireflyIII\Enums\UserRoleEnum;
|
||||
use FireflyIII\Exceptions\FireflyException;
|
||||
use FireflyIII\Helpers\Collector\GroupCollectorInterface;
|
||||
use FireflyIII\Repositories\Account\AccountRepositoryInterface;
|
||||
use FireflyIII\Repositories\Currency\CurrencyRepositoryInterface;
|
||||
use FireflyIII\Support\Http\Api\CleansChartData;
|
||||
use FireflyIII\Support\Http\Api\ExchangeRateConverter;
|
||||
use FireflyIII\Support\Http\Api\ValidatesUserGroupTrait;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
|
||||
/**
|
||||
* Class BudgetController
|
||||
@@ -45,6 +48,8 @@ class CategoryController extends Controller
|
||||
use CleansChartData;
|
||||
use ValidatesUserGroupTrait;
|
||||
|
||||
protected array $acceptedRoles = [UserRoleEnum::READ_ONLY];
|
||||
|
||||
private AccountRepositoryInterface $accountRepos;
|
||||
private CurrencyRepositoryInterface $currencyRepos;
|
||||
|
||||
@@ -79,9 +84,10 @@ class CategoryController extends Controller
|
||||
|
||||
/** @var Carbon $end */
|
||||
$end = $this->parameters->get('end');
|
||||
$accounts = $this->accountRepos->getAccountsByType([AccountTypeEnum::DEBT->value, AccountTypeEnum::LOAN->value, AccountTypeEnum::MORTGAGE->value, AccountTypeEnum::ASSET->value, AccountTypeEnum::DEFAULT->value]);
|
||||
$accounts = $this->accountRepos->getAccountsByType([AccountTypeEnum::DEBT->value, AccountTypeEnum::LOAN->value, AccountTypeEnum::MORTGAGE->value, AccountTypeEnum::ASSET->value]);
|
||||
$currencies = [];
|
||||
$return = [];
|
||||
$converter = new ExchangeRateConverter();
|
||||
|
||||
// get journals for entire period:
|
||||
/** @var GroupCollectorInterface $collector */
|
||||
@@ -93,20 +99,40 @@ class CategoryController extends Controller
|
||||
|
||||
/** @var array $journal */
|
||||
foreach ($journals as $journal) {
|
||||
$currencyId = (int) $journal['currency_id'];
|
||||
$currency = $currencies[$currencyId] ?? $this->currencyRepos->find($currencyId);
|
||||
$currencies[$currencyId] = $currency;
|
||||
$categoryName = $journal['category_name'] ?? (string) trans('firefly.no_category');
|
||||
$amount = app('steam')->positive($journal['amount']);
|
||||
$key = sprintf('%s-%s', $categoryName, $currency->code);
|
||||
// find journal:
|
||||
$journalCurrencyId = (int)$journal['currency_id'];
|
||||
$currency = $currencies[$journalCurrencyId] ?? $this->currencyRepos->find($journalCurrencyId);
|
||||
$currencies[$journalCurrencyId] = $currency;
|
||||
$currencyId = (int)$currency->id;
|
||||
$currencyName = (string)$currency->name;
|
||||
$currencyCode = (string)$currency->code;
|
||||
$currencySymbol = (string)$currency->symbol;
|
||||
$currencyDecimalPlaces = (int)$currency->decimal_places;
|
||||
$amount = app('steam')->positive($journal['amount']);
|
||||
|
||||
// overrule if necessary:
|
||||
if ($this->convertToNative && $journalCurrencyId !== $this->nativeCurrency->id) {
|
||||
$currencyId = (int)$this->nativeCurrency->id;
|
||||
$currencyName = (string)$this->nativeCurrency->name;
|
||||
$currencyCode = (string)$this->nativeCurrency->code;
|
||||
$currencySymbol = (string)$this->nativeCurrency->symbol;
|
||||
$currencyDecimalPlaces = (int)$this->nativeCurrency->decimal_places;
|
||||
$convertedAmount = $converter->convert($currency, $this->nativeCurrency, $journal['date'], $amount);
|
||||
Log::debug(sprintf('Converted %s %s to %s %s', $journal['currency_code'], $amount, $this->nativeCurrency->code, $convertedAmount));
|
||||
$amount = $convertedAmount;
|
||||
}
|
||||
|
||||
|
||||
$categoryName = $journal['category_name'] ?? (string)trans('firefly.no_category');
|
||||
$key = sprintf('%s-%s', $categoryName, $currencyCode);
|
||||
// create arrays
|
||||
$return[$key] ??= [
|
||||
'label' => $categoryName,
|
||||
'currency_id' => (string) $currency->id,
|
||||
'currency_code' => $currency->code,
|
||||
'currency_name' => $currency->name,
|
||||
'currency_symbol' => $currency->symbol,
|
||||
'currency_decimal_places' => $currency->decimal_places,
|
||||
'currency_id' => (string)$currencyId,
|
||||
'currency_code' => $currencyCode,
|
||||
'currency_name' => $currencyName,
|
||||
'currency_symbol' => $currencySymbol,
|
||||
'currency_decimal_places' => $currencyDecimalPlaces,
|
||||
'period' => null,
|
||||
'start' => $start->toAtomString(),
|
||||
'end' => $end->toAtomString(),
|
||||
@@ -114,12 +140,12 @@ class CategoryController extends Controller
|
||||
];
|
||||
|
||||
// add monies
|
||||
$return[$key]['amount'] = bcadd($return[$key]['amount'], (string) $amount);
|
||||
$return[$key]['amount'] = bcadd($return[$key]['amount'], (string)$amount);
|
||||
}
|
||||
$return = array_values($return);
|
||||
|
||||
// order by amount
|
||||
usort($return, static fn (array $a, array $b) => (float) $a['amount'] < (float) $b['amount'] ? 1 : -1);
|
||||
usort($return, static fn (array $a, array $b) => (float)$a['amount'] < (float)$b['amount'] ? 1 : -1);
|
||||
|
||||
return response()->json($this->clean($return));
|
||||
}
|
||||
|
@@ -127,7 +127,6 @@ abstract class Controller extends BaseController
|
||||
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;
|
||||
if (null !== $date) {
|
||||
|
@@ -64,7 +64,7 @@ class DestroyController extends Controller
|
||||
public function destroy(DestroyRequest $request): JsonResponse
|
||||
{
|
||||
$objects = $request->getObjects();
|
||||
$this->unused = $request->boolean('unused', false);
|
||||
$this->unused = $request->boolean('unused');
|
||||
|
||||
$allExceptAssets = [AccountTypeEnum::BENEFICIARY->value, AccountTypeEnum::CASH->value, AccountTypeEnum::CREDITCARD->value, AccountTypeEnum::DEFAULT->value, AccountTypeEnum::EXPENSE->value, AccountTypeEnum::IMPORT->value, AccountTypeEnum::INITIAL_BALANCE->value, AccountTypeEnum::LIABILITY_CREDIT->value, AccountTypeEnum::RECONCILIATION->value, AccountTypeEnum::REVENUE->value];
|
||||
$all = [AccountTypeEnum::ASSET->value, AccountTypeEnum::BENEFICIARY->value, AccountTypeEnum::CASH->value, AccountTypeEnum::CREDITCARD->value, AccountTypeEnum::DEBT->value, AccountTypeEnum::DEFAULT->value, AccountTypeEnum::EXPENSE->value, AccountTypeEnum::IMPORT->value, AccountTypeEnum::INITIAL_BALANCE->value, AccountTypeEnum::LIABILITY_CREDIT->value, AccountTypeEnum::LOAN->value, AccountTypeEnum::MORTGAGE->value, AccountTypeEnum::RECONCILIATION->value];
|
||||
|
@@ -29,6 +29,7 @@ use FireflyIII\Api\V1\Requests\Data\Export\ExportRequest;
|
||||
use FireflyIII\Exceptions\FireflyException;
|
||||
use FireflyIII\Support\Export\ExportDataGenerator;
|
||||
use Illuminate\Http\Response as LaravelResponse;
|
||||
use Safe\Exceptions\DatetimeException;
|
||||
|
||||
use function Safe\date;
|
||||
|
||||
@@ -72,6 +73,7 @@ class ExportController extends Controller
|
||||
|
||||
/**
|
||||
* @throws FireflyException
|
||||
* @throws DatetimeException
|
||||
*/
|
||||
private function returnExport(string $key): LaravelResponse
|
||||
{
|
||||
|
@@ -28,7 +28,9 @@ use FireflyIII\Api\V1\Controllers\Controller;
|
||||
use FireflyIII\Exceptions\FireflyException;
|
||||
use FireflyIII\Models\Bill;
|
||||
use FireflyIII\Repositories\Bill\BillRepositoryInterface;
|
||||
use FireflyIII\Support\JsonApi\Enrichments\SubscriptionEnrichment;
|
||||
use FireflyIII\Transformers\BillTransformer;
|
||||
use FireflyIII\User;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Pagination\LengthAwarePaginator;
|
||||
use League\Fractal\Pagination\IlluminatePaginatorAdapter;
|
||||
@@ -76,6 +78,17 @@ class ShowController extends Controller
|
||||
$bills = $bills->slice(($this->parameters->get('page') - 1) * $pageSize, $pageSize);
|
||||
$paginator = new LengthAwarePaginator($bills, $count, $pageSize, $this->parameters->get('page'));
|
||||
|
||||
// enrich
|
||||
/** @var User $admin */
|
||||
$admin = auth()->user();
|
||||
$enrichment = new SubscriptionEnrichment();
|
||||
$enrichment->setUser($admin);
|
||||
$enrichment->setConvertToNative($this->convertToNative);
|
||||
$enrichment->setNative($this->nativeCurrency);
|
||||
$enrichment->setStart($this->parameters->get('start'));
|
||||
$enrichment->setEnd($this->parameters->get('end'));
|
||||
$bills = $enrichment->enrich($bills);
|
||||
|
||||
/** @var BillTransformer $transformer */
|
||||
$transformer = app(BillTransformer::class);
|
||||
$transformer->setParameters($this->parameters);
|
||||
@@ -96,6 +109,17 @@ class ShowController extends Controller
|
||||
{
|
||||
$manager = $this->getManager();
|
||||
|
||||
// enrich
|
||||
/** @var User $admin */
|
||||
$admin = auth()->user();
|
||||
$enrichment = new SubscriptionEnrichment();
|
||||
$enrichment->setUser($admin);
|
||||
$enrichment->setConvertToNative($this->convertToNative);
|
||||
$enrichment->setNative($this->nativeCurrency);
|
||||
$enrichment->setStart($this->parameters->get('start'));
|
||||
$enrichment->setEnd($this->parameters->get('end'));
|
||||
$bill = $enrichment->enrichSingle($bill);
|
||||
|
||||
/** @var BillTransformer $transformer */
|
||||
$transformer = app(BillTransformer::class);
|
||||
$transformer->setParameters($this->parameters);
|
||||
|
@@ -29,7 +29,9 @@ use FireflyIII\Api\V1\Requests\Models\Bill\StoreRequest;
|
||||
use FireflyIII\Exceptions\FireflyException;
|
||||
use FireflyIII\Repositories\Bill\BillRepositoryInterface;
|
||||
use FireflyIII\Support\Http\Api\TransactionFilter;
|
||||
use FireflyIII\Support\JsonApi\Enrichments\SubscriptionEnrichment;
|
||||
use FireflyIII\Transformers\BillTransformer;
|
||||
use FireflyIII\User;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use League\Fractal\Resource\Item;
|
||||
|
||||
@@ -72,6 +74,17 @@ class StoreController extends Controller
|
||||
$bill = $this->repository->store($data);
|
||||
$manager = $this->getManager();
|
||||
|
||||
// enrich
|
||||
/** @var User $admin */
|
||||
$admin = auth()->user();
|
||||
$enrichment = new SubscriptionEnrichment();
|
||||
$enrichment->setUser($admin);
|
||||
$enrichment->setConvertToNative($this->convertToNative);
|
||||
$enrichment->setNative($this->nativeCurrency);
|
||||
$enrichment->setStart($this->parameters->get('start'));
|
||||
$enrichment->setEnd($this->parameters->get('end'));
|
||||
$bill = $enrichment->enrichSingle($bill);
|
||||
|
||||
/** @var BillTransformer $transformer */
|
||||
$transformer = app(BillTransformer::class);
|
||||
$transformer->setParameters($this->parameters);
|
||||
|
@@ -28,7 +28,9 @@ use FireflyIII\Api\V1\Controllers\Controller;
|
||||
use FireflyIII\Api\V1\Requests\Models\Bill\UpdateRequest;
|
||||
use FireflyIII\Models\Bill;
|
||||
use FireflyIII\Repositories\Bill\BillRepositoryInterface;
|
||||
use FireflyIII\Support\JsonApi\Enrichments\SubscriptionEnrichment;
|
||||
use FireflyIII\Transformers\BillTransformer;
|
||||
use FireflyIII\User;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use League\Fractal\Resource\Item;
|
||||
|
||||
@@ -67,6 +69,17 @@ class UpdateController extends Controller
|
||||
$bill = $this->repository->update($bill, $data);
|
||||
$manager = $this->getManager();
|
||||
|
||||
// enrich
|
||||
/** @var User $admin */
|
||||
$admin = auth()->user();
|
||||
$enrichment = new SubscriptionEnrichment();
|
||||
$enrichment->setUser($admin);
|
||||
$enrichment->setConvertToNative($this->convertToNative);
|
||||
$enrichment->setNative($this->nativeCurrency);
|
||||
$enrichment->setStart($this->parameters->get('start'));
|
||||
$enrichment->setEnd($this->parameters->get('end'));
|
||||
$bill = $enrichment->enrichSingle($bill);
|
||||
|
||||
/** @var BillTransformer $transformer */
|
||||
$transformer = app(BillTransformer::class);
|
||||
$transformer->setParameters($this->parameters);
|
||||
|
@@ -69,7 +69,6 @@ class StoreController extends Controller
|
||||
$data = $request->getAll();
|
||||
$data['start_date'] = $data['start'];
|
||||
$data['end_date'] = $data['end'];
|
||||
$data['notes'] = $data['notes'];
|
||||
$data['budget_id'] = $budget->id;
|
||||
|
||||
$budgetLimit = $this->blRepository->store($data);
|
||||
|
@@ -28,6 +28,7 @@ use FireflyIII\Api\V1\Controllers\Controller;
|
||||
use FireflyIII\Exceptions\FireflyException;
|
||||
use FireflyIII\Models\ObjectGroup;
|
||||
use FireflyIII\Repositories\ObjectGroup\ObjectGroupRepositoryInterface;
|
||||
use FireflyIII\Support\JsonApi\Enrichments\SubscriptionEnrichment;
|
||||
use FireflyIII\Transformers\BillTransformer;
|
||||
use FireflyIII\Transformers\PiggyBankTransformer;
|
||||
use FireflyIII\User;
|
||||
@@ -79,6 +80,17 @@ class ListController extends Controller
|
||||
$count = $collection->count();
|
||||
$bills = $collection->slice(($this->parameters->get('page') - 1) * $pageSize, $pageSize);
|
||||
|
||||
// enrich
|
||||
/** @var User $admin */
|
||||
$admin = auth()->user();
|
||||
$enrichment = new SubscriptionEnrichment();
|
||||
$enrichment->setUser($admin);
|
||||
$enrichment->setConvertToNative($this->convertToNative);
|
||||
$enrichment->setNative($this->nativeCurrency);
|
||||
$enrichment->setStart($this->parameters->get('start'));
|
||||
$enrichment->setEnd($this->parameters->get('end'));
|
||||
$bills = $enrichment->enrich($bills);
|
||||
|
||||
// make paginator:
|
||||
$paginator = new LengthAwarePaginator($bills, $count, $pageSize, $this->parameters->get('page'));
|
||||
$paginator->setPath(route('api.v1.currencies.bills', [$objectGroup->id]).$this->buildParams());
|
||||
|
@@ -147,6 +147,7 @@ class ShowController extends Controller
|
||||
$enrichment->setUser($admin);
|
||||
$selectedGroup = $enrichment->enrichSingle($selectedGroup);
|
||||
|
||||
|
||||
/** @var TransactionGroupTransformer $transformer */
|
||||
$transformer = app(TransactionGroupTransformer::class);
|
||||
$transformer->setParameters($this->parameters);
|
||||
|
@@ -32,6 +32,7 @@ use FireflyIII\Repositories\Currency\CurrencyRepositoryInterface;
|
||||
use FireflyIII\Repositories\User\UserRepositoryInterface;
|
||||
use FireflyIII\User;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Validation\ValidationException;
|
||||
|
||||
/**
|
||||
* Class DestroyController
|
||||
@@ -65,6 +66,7 @@ class DestroyController extends Controller
|
||||
* Remove the specified resource from storage.
|
||||
*
|
||||
* @throws FireflyException
|
||||
* @throws ValidationException
|
||||
*/
|
||||
public function destroy(TransactionCurrency $currency): JsonResponse
|
||||
{
|
||||
|
@@ -43,6 +43,7 @@ use FireflyIII\Repositories\Rule\RuleRepositoryInterface;
|
||||
use FireflyIII\Support\Http\Api\AccountFilter;
|
||||
use FireflyIII\Support\Http\Api\TransactionFilter;
|
||||
use FireflyIII\Support\JsonApi\Enrichments\AccountEnrichment;
|
||||
use FireflyIII\Support\JsonApi\Enrichments\SubscriptionEnrichment;
|
||||
use FireflyIII\Support\JsonApi\Enrichments\TransactionGroupEnrichment;
|
||||
use FireflyIII\Transformers\AccountTransformer;
|
||||
use FireflyIII\Transformers\AvailableBudgetTransformer;
|
||||
@@ -182,6 +183,17 @@ class ListController extends Controller
|
||||
$count = $collection->count();
|
||||
$bills = $collection->slice(($this->parameters->get('page') - 1) * $pageSize, $pageSize);
|
||||
|
||||
// enrich
|
||||
/** @var User $admin */
|
||||
$admin = auth()->user();
|
||||
$enrichment = new SubscriptionEnrichment();
|
||||
$enrichment->setUser($admin);
|
||||
$enrichment->setConvertToNative($this->convertToNative);
|
||||
$enrichment->setNative($this->nativeCurrency);
|
||||
$enrichment->setStart($this->parameters->get('start'));
|
||||
$enrichment->setEnd($this->parameters->get('end'));
|
||||
$bills = $enrichment->enrichSingle($bills);
|
||||
|
||||
// make paginator:
|
||||
$paginator = new LengthAwarePaginator($bills, $count, $pageSize, $this->parameters->get('page'));
|
||||
$paginator->setPath(route('api.v1.currencies.bills', [$currency->code]).$this->buildParams());
|
||||
@@ -250,10 +262,8 @@ class ListController extends Controller
|
||||
$collection = $unfiltered->filter(
|
||||
static function (Recurrence $recurrence) use ($currency) { // @phpstan-ignore-line
|
||||
/** @var RecurrenceTransaction $transaction */
|
||||
foreach ($recurrence->recurrenceTransactions as $transaction) {
|
||||
if ($transaction->transaction_currency_id === $currency->id || $transaction->foreign_currency_id === $currency->id) {
|
||||
return $recurrence;
|
||||
}
|
||||
if (array_any($recurrence->recurrenceTransactions, fn ($transaction) => $transaction->transaction_currency_id === $currency->id || $transaction->foreign_currency_id === $currency->id)) {
|
||||
return $recurrence;
|
||||
}
|
||||
|
||||
return null;
|
||||
@@ -297,10 +307,8 @@ class ListController extends Controller
|
||||
$collection = $unfiltered->filter(
|
||||
static function (Rule $rule) use ($currency) { // @phpstan-ignore-line
|
||||
/** @var RuleTrigger $trigger */
|
||||
foreach ($rule->ruleTriggers as $trigger) {
|
||||
if ('currency_is' === $trigger->trigger_type && $currency->name === $trigger->trigger_value) {
|
||||
return $rule;
|
||||
}
|
||||
if (array_any($rule->ruleTriggers, fn ($trigger) => 'currency_is' === $trigger->trigger_type && $currency->name === $trigger->trigger_value)) {
|
||||
return $rule;
|
||||
}
|
||||
|
||||
return null;
|
||||
|
@@ -27,13 +27,13 @@ namespace FireflyIII\Api\V1\Controllers\Models\TransactionLinkType;
|
||||
use Illuminate\Support\Facades\Validator;
|
||||
use FireflyIII\Api\V1\Controllers\Controller;
|
||||
use FireflyIII\Api\V1\Requests\Models\TransactionLinkType\StoreRequest;
|
||||
use FireflyIII\Exceptions\FireflyException;
|
||||
use FireflyIII\Repositories\LinkType\LinkTypeRepositoryInterface;
|
||||
use FireflyIII\Repositories\User\UserRepositoryInterface;
|
||||
use FireflyIII\Support\Http\Api\TransactionFilter;
|
||||
use FireflyIII\Transformers\LinkTypeTransformer;
|
||||
use FireflyIII\User;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Validation\ValidationException;
|
||||
use League\Fractal\Resource\Item;
|
||||
|
||||
/**
|
||||
@@ -71,7 +71,7 @@ class StoreController extends Controller
|
||||
*
|
||||
* Store new object.
|
||||
*
|
||||
* @throws FireflyException
|
||||
* @throws ValidationException
|
||||
*/
|
||||
public function store(StoreRequest $request): JsonResponse
|
||||
{
|
||||
|
@@ -35,6 +35,7 @@ use FireflyIII\Support\Http\Api\TransactionFilter;
|
||||
use FireflyIII\Transformers\LinkTypeTransformer;
|
||||
use FireflyIII\User;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Validation\ValidationException;
|
||||
use League\Fractal\Resource\Item;
|
||||
|
||||
/**
|
||||
@@ -73,6 +74,7 @@ class UpdateController extends Controller
|
||||
* Update object.
|
||||
*
|
||||
* @throws FireflyException
|
||||
* @throws ValidationException
|
||||
*/
|
||||
public function update(UpdateRequest $request, LinkType $linkType): JsonResponse
|
||||
{
|
||||
|
@@ -130,8 +130,6 @@ class BasicController extends Controller
|
||||
$convertToNative = Amount::convertToNative();
|
||||
$default = Amount::getNativeCurrency();
|
||||
// prep some arrays:
|
||||
$incomes = [];
|
||||
$expenses = [];
|
||||
$sums = [];
|
||||
$return = [];
|
||||
$currencies = [
|
||||
|
@@ -24,6 +24,7 @@ declare(strict_types=1);
|
||||
|
||||
namespace FireflyIII\Api\V1\Controllers\System;
|
||||
|
||||
use FireflyIII\Support\Facades\FireflyConfig;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
use Illuminate\Support\Facades\Validator;
|
||||
use FireflyIII\Api\V1\Controllers\Controller;
|
||||
@@ -32,6 +33,7 @@ use FireflyIII\Exceptions\FireflyException;
|
||||
use FireflyIII\Repositories\User\UserRepositoryInterface;
|
||||
use FireflyIII\Support\Binder\EitherConfigKey;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Validation\ValidationException;
|
||||
|
||||
/**
|
||||
* Class ConfigurationController
|
||||
@@ -93,13 +95,15 @@ class ConfigurationController extends Controller
|
||||
|
||||
/**
|
||||
* Get all config values.
|
||||
*
|
||||
* @throws FireflyException
|
||||
*/
|
||||
private function getDynamicConfiguration(): array
|
||||
{
|
||||
$isDemoSite = app('fireflyconfig')->get('is_demo_site');
|
||||
$updateCheck = app('fireflyconfig')->get('permission_update_check');
|
||||
$lastCheck = app('fireflyconfig')->get('last_update_check');
|
||||
$singleUser = app('fireflyconfig')->get('single_user_mode');
|
||||
$isDemoSite = FireflyConfig::get('is_demo_site');
|
||||
$updateCheck = FireflyConfig::get('permission_update_check');
|
||||
$lastCheck = FireflyConfig::get('last_update_check');
|
||||
$singleUser = FireflyConfig::get('single_user_mode');
|
||||
|
||||
return [
|
||||
'is_demo_site' => $isDemoSite?->data,
|
||||
@@ -154,6 +158,7 @@ class ConfigurationController extends Controller
|
||||
* Update the configuration.
|
||||
*
|
||||
* @throws FireflyException
|
||||
* @throws ValidationException
|
||||
*/
|
||||
public function update(UpdateRequest $request, string $name): JsonResponse
|
||||
{
|
||||
@@ -165,7 +170,7 @@ class ConfigurationController extends Controller
|
||||
$data = $request->getAll();
|
||||
$shortName = str_replace('configuration.', '', $name);
|
||||
|
||||
app('fireflyconfig')->set($shortName, $data['value']);
|
||||
FireflyConfig::set($shortName, $data['value']);
|
||||
|
||||
// get updated config:
|
||||
$newConfig = $this->getDynamicConfiguration();
|
||||
|
@@ -76,6 +76,6 @@ class SubmitController extends Controller
|
||||
SendWebhookMessage::dispatch($message)->afterResponse();
|
||||
}
|
||||
|
||||
return response()->json([]);
|
||||
return response()->json();
|
||||
}
|
||||
}
|
||||
|
@@ -58,7 +58,7 @@ class AutocompleteRequest extends FormRequest
|
||||
public function rules(): array
|
||||
{
|
||||
return [
|
||||
'date' => 'date|after:1900-01-01|before:2099-12-31',
|
||||
'date' => 'date|after:1970-01-02|before:2038-01-17',
|
||||
];
|
||||
}
|
||||
}
|
||||
|
@@ -60,8 +60,8 @@ class ChartRequest extends FormRequest
|
||||
public function rules(): array
|
||||
{
|
||||
return [
|
||||
'start' => 'required|date|after:1900-01-01|before:2099-12-31|before_or_equal:end',
|
||||
'end' => 'required|date|after:1900-01-01|before:2099-12-31|after_or_equal:start',
|
||||
'start' => 'required|date|after:1970-01-02|before:2038-01-17|before_or_equal:end',
|
||||
'end' => 'required|date|after:1970-01-02|before:2038-01-17|after_or_equal:start',
|
||||
'preselected' => sprintf('nullable|in:%s', implode(',', config('firefly.preselected_accounts'))),
|
||||
'period' => sprintf('nullable|in:%s', implode(',', config('firefly.valid_view_ranges'))),
|
||||
'accounts.*' => 'exists:accounts,id',
|
||||
|
@@ -54,7 +54,7 @@ class TransactionRequest extends FormRequest
|
||||
'query' => json_decode($this->get('query'), true, 8, JSON_THROW_ON_ERROR),
|
||||
];
|
||||
} catch (JsonException $e) {
|
||||
// dont really care. the validation should catch invalid json.
|
||||
// don't really care. the validation should catch invalid json.
|
||||
Log::error($e->getMessage());
|
||||
}
|
||||
|
||||
|
@@ -65,9 +65,9 @@ class DateRequest extends FormRequest
|
||||
public function rules(): array
|
||||
{
|
||||
return [
|
||||
'date' => 'date|after:1900-01-01|before:2099-12-31',
|
||||
'start' => 'date|after:1900-01-01|before:2099-12-31|before:end|required_with:end',
|
||||
'end' => 'date|after:1900-01-01|before:2099-12-31|after:start|required_with:start',
|
||||
'date' => 'date|after:1970-01-02|before:2038-01-17',
|
||||
'start' => 'date|after:1970-01-02|before:2038-01-17|before:end|required_with:end',
|
||||
'end' => 'date|after:1970-01-02|before:2038-01-17|after:start|required_with:start',
|
||||
];
|
||||
}
|
||||
}
|
||||
|
@@ -55,8 +55,8 @@ class DateRequest extends FormRequest
|
||||
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',
|
||||
'start' => 'required|date|after:1970-01-02|before:2038-01-17',
|
||||
'end' => 'required|date|after_or_equal:start|before:2038-01-17|after:1970-01-02',
|
||||
];
|
||||
}
|
||||
}
|
||||
|
@@ -53,7 +53,7 @@ class SingleDateRequest extends FormRequest
|
||||
public function rules(): array
|
||||
{
|
||||
return [
|
||||
'date' => 'required|date|after:1900-01-01|before:2099-12-31',
|
||||
'date' => 'required|date|after:1970-01-02|before:2038-01-17',
|
||||
];
|
||||
}
|
||||
}
|
||||
|
@@ -66,8 +66,8 @@ class Request extends FormRequest
|
||||
'currency_id' => 'numeric|exists:transaction_currencies,id',
|
||||
'currency_code' => 'min:3|max:51|exists:transaction_currencies,code',
|
||||
'amount' => ['nullable', new IsValidPositiveAmount()],
|
||||
'start' => 'date|after:1900-01-01|before:2099-12-31',
|
||||
'end' => 'date|after:1900-01-01|before:2099-12-31',
|
||||
'start' => 'date|after:1970-01-02|before:2038-01-17',
|
||||
'end' => 'date|after:1970-01-02|before:2038-01-17',
|
||||
];
|
||||
}
|
||||
|
||||
|
@@ -80,9 +80,9 @@ class StoreRequest extends FormRequest
|
||||
'amount_max' => ['required', new IsValidPositiveAmount()],
|
||||
'currency_id' => 'numeric|exists:transaction_currencies,id',
|
||||
'currency_code' => 'min:3|max:51|exists:transaction_currencies,code',
|
||||
'date' => 'date|required|after:1900-01-01|before:2099-12-31',
|
||||
'end_date' => 'nullable|date|after:date|after:1900-01-01|before:2099-12-31',
|
||||
'extension_date' => 'nullable|date|after:date|after:1900-01-01|before:2099-12-31',
|
||||
'date' => 'date|required|after:1970-01-02|before:2038-01-17',
|
||||
'end_date' => 'nullable|date|after:date|after:1970-01-02|before:2038-01-17',
|
||||
'extension_date' => 'nullable|date|after:date|after:1970-01-02|before:2038-01-17',
|
||||
'repeat_freq' => 'in:weekly,monthly,quarterly,half-year,yearly|required',
|
||||
'skip' => 'min:0|max:31|numeric',
|
||||
'active' => [new IsBoolean()],
|
||||
@@ -128,7 +128,6 @@ class StoreRequest extends FormRequest
|
||||
$failed = $validator->fails();
|
||||
} catch (TypeError $e) {
|
||||
Log::error($e->getMessage());
|
||||
$failed = false;
|
||||
}
|
||||
if ($failed) {
|
||||
Log::channel('audit')->error(sprintf('Validation errors in %s', self::class), $validator->errors()->toArray());
|
||||
|
@@ -81,9 +81,9 @@ class UpdateRequest extends FormRequest
|
||||
'amount_max' => ['nullable', new IsValidPositiveAmount()],
|
||||
'currency_id' => 'numeric|exists:transaction_currencies,id',
|
||||
'currency_code' => 'min:3|max:51|exists:transaction_currencies,code',
|
||||
'date' => 'date|after:1900-01-01|before:2099-12-31',
|
||||
'end_date' => 'date|after:date|after:1900-01-01|before:2099-12-31',
|
||||
'extension_date' => 'date|after:date|after:1900-01-01|before:2099-12-31',
|
||||
'date' => 'date|after:1970-01-02|before:2038-01-17',
|
||||
'end_date' => 'date|after:date|after:1970-01-02|before:2038-01-17',
|
||||
'extension_date' => 'date|after:date|after:1970-01-02|before:2038-01-17',
|
||||
'repeat_freq' => 'in:weekly,monthly,quarterly,half-year,yearly',
|
||||
'skip' => 'min:0|max:31|numeric',
|
||||
'active' => [new IsBoolean()],
|
||||
|
@@ -67,8 +67,8 @@ class UpdateRequest extends FormRequest
|
||||
public function rules(): array
|
||||
{
|
||||
return [
|
||||
'start' => 'date|after:1900-01-01|before:2099-12-31',
|
||||
'end' => 'date|after:1900-01-01|before:2099-12-31',
|
||||
'start' => 'date|after:1970-01-02|before:2038-01-17',
|
||||
'end' => 'date|after:1970-01-02|before:2038-01-17',
|
||||
'amount' => ['nullable', new IsValidPositiveAmount()],
|
||||
'currency_id' => 'numeric|exists:transaction_currencies,id',
|
||||
'currency_code' => 'min:3|max:51|exists:transaction_currencies,code',
|
||||
|
@@ -45,7 +45,7 @@ class DestroyRequest extends FormRequest
|
||||
public function rules(): array
|
||||
{
|
||||
return [
|
||||
'date' => 'required|date|after:1900-01-01|before:2099-12-31',
|
||||
'date' => 'required|date|after:1970-01-02|before:2038-01-17',
|
||||
];
|
||||
}
|
||||
}
|
||||
|
@@ -61,7 +61,7 @@ class StoreRequest extends FormRequest
|
||||
public function rules(): array
|
||||
{
|
||||
return [
|
||||
'date' => 'required|date|after:1900-01-01|before:2099-12-31',
|
||||
'date' => 'required|date|after:1970-01-02|before:2038-01-17',
|
||||
'rate' => 'required|numeric|gt:0',
|
||||
'from' => 'required|exists:transaction_currencies,code',
|
||||
'to' => 'required|exists:transaction_currencies,code',
|
||||
|
@@ -50,7 +50,7 @@ class UpdateRequest extends FormRequest
|
||||
public function rules(): array
|
||||
{
|
||||
return [
|
||||
'date' => 'date|after:1900-01-01|before:2099-12-31',
|
||||
'date' => 'date|after:1970-01-02|before:2038-01-17',
|
||||
'rate' => 'required|numeric|gt:0',
|
||||
];
|
||||
}
|
||||
|
@@ -76,7 +76,7 @@ class StoreRequest extends FormRequest
|
||||
|
||||
/**
|
||||
* Returns the transaction data as it is found in the submitted data. It's a complex method according to code
|
||||
* standards but it just has a lot of ??-statements because of the fields that may or may not exist.
|
||||
* standards, but it just has a lot of ??-statements because of the fields that may or may not exist.
|
||||
*/
|
||||
private function getTransactionData(): array
|
||||
{
|
||||
|
@@ -122,7 +122,7 @@ class UpdateRequest extends FormRequest
|
||||
|
||||
/**
|
||||
* Returns the transaction data as it is found in the submitted data. It's a complex method according to code
|
||||
* standards but it just has a lot of ??-statements because of the fields that may or may not exist.
|
||||
* standards, but it just has a lot of ??-statements because of the fields that may or may not exist.
|
||||
*/
|
||||
private function getTransactionData(): array
|
||||
{
|
||||
@@ -154,7 +154,7 @@ class UpdateRequest extends FormRequest
|
||||
return [
|
||||
'title' => sprintf('min:1|max:255|uniqueObjectForUser:recurrences,title,%d', $recurrence->id),
|
||||
'description' => 'min:1|max:32768',
|
||||
'first_date' => 'date|after:1900-01-01|before:2099-12-31',
|
||||
'first_date' => 'date|after:1970-01-02|before:2038-01-17',
|
||||
'apply_rules' => [new IsBoolean()],
|
||||
'active' => [new IsBoolean()],
|
||||
'repeat_until' => 'nullable|date',
|
||||
|
@@ -71,8 +71,8 @@ class TestRequest extends FormRequest
|
||||
public function rules(): array
|
||||
{
|
||||
return [
|
||||
'start' => 'date|after:1900-01-01|before:2099-12-31',
|
||||
'end' => 'date|after_or_equal:start|after:1900-01-01|before:2099-12-31',
|
||||
'start' => 'date|after:1970-01-02|before:2038-01-17',
|
||||
'end' => 'date|after_or_equal:start|after:1970-01-02|before:2038-01-17',
|
||||
'accounts' => '',
|
||||
'accounts.*' => 'required|exists:accounts,id|belongsToUser:accounts',
|
||||
];
|
||||
|
@@ -65,8 +65,8 @@ class TriggerRequest extends FormRequest
|
||||
public function rules(): array
|
||||
{
|
||||
return [
|
||||
'start' => 'date|after:1900-01-01|before:2099-12-31',
|
||||
'end' => 'date|after_or_equal:start|after:1900-01-01|before:2099-12-31',
|
||||
'start' => 'date|after:1970-01-02|before:2038-01-17',
|
||||
'end' => 'date|after_or_equal:start|after:1970-01-02|before:2038-01-17',
|
||||
'accounts' => '',
|
||||
'accounts.*' => 'exists:accounts,id|belongsToUser:accounts',
|
||||
];
|
||||
|
@@ -65,8 +65,8 @@ class TestRequest extends FormRequest
|
||||
public function rules(): array
|
||||
{
|
||||
return [
|
||||
'start' => 'date|after:1900-01-01|before:2099-12-31',
|
||||
'end' => 'date|after_or_equal:start|after:1900-01-01|before:2099-12-31',
|
||||
'start' => 'date|after:1970-01-02|before:2038-01-17',
|
||||
'end' => 'date|after_or_equal:start|after:1970-01-02|before:2038-01-17',
|
||||
'accounts' => '',
|
||||
'accounts.*' => 'exists:accounts,id|belongsToUser:accounts',
|
||||
];
|
||||
|
@@ -69,8 +69,8 @@ class TriggerRequest extends FormRequest
|
||||
public function rules(): array
|
||||
{
|
||||
return [
|
||||
'start' => 'date|after:1900-01-01|before:2099-12-31',
|
||||
'end' => 'date|after_or_equal:start|after:1900-01-01|before:2099-12-31',
|
||||
'start' => 'date|after:1970-01-02|before:2038-01-17',
|
||||
'end' => 'date|after_or_equal:start|after:1970-01-02|before:2038-01-17',
|
||||
];
|
||||
}
|
||||
}
|
||||
|
@@ -62,7 +62,7 @@ class StoreRequest extends FormRequest
|
||||
$rules = [
|
||||
'tag' => 'required|min:1|uniqueObjectForUser:tags,tag|max:1024',
|
||||
'description' => 'min:1|nullable|max:32768',
|
||||
'date' => 'date|nullable|after:1900-01-01|before:2099-12-31',
|
||||
'date' => 'date|nullable|after:1970-01-02|before:2038-01-17',
|
||||
];
|
||||
|
||||
return Location::requestRules($rules);
|
||||
|
@@ -66,7 +66,7 @@ class UpdateRequest extends FormRequest
|
||||
$rules = [
|
||||
'tag' => 'min:1|max:1024|uniqueObjectForUser:tags,tag,'.$tag->id,
|
||||
'description' => 'min:1|nullable|max:32768',
|
||||
'date' => 'date|nullable|after:1900-01-01|before:2099-12-31',
|
||||
'date' => 'date|nullable|after:1970-01-02|before:2038-01-17',
|
||||
];
|
||||
|
||||
return Location::requestRules($rules);
|
||||
|
@@ -183,7 +183,7 @@ class UpdateRequest extends FormRequest
|
||||
foreach ($this->dateFields as $fieldName) {
|
||||
app('log')->debug(sprintf('Now at date field %s', $fieldName));
|
||||
if (array_key_exists($fieldName, $transaction)) {
|
||||
app('log')->debug(sprintf('New value: "%s"', (string) $transaction[$fieldName]));
|
||||
Log::debug(sprintf('New value: "%s"', $transaction[$fieldName]));
|
||||
$current[$fieldName] = $this->dateFromValue((string) $transaction[$fieldName]);
|
||||
}
|
||||
}
|
||||
|
@@ -24,7 +24,6 @@ declare(strict_types=1);
|
||||
|
||||
namespace FireflyIII\Api\V1\Requests\Models\UserGroup;
|
||||
|
||||
use FireflyIII\Models\UserGroup;
|
||||
use FireflyIII\Support\Request\ChecksLogin;
|
||||
use FireflyIII\Support\Request\ConvertsDataTypes;
|
||||
use Illuminate\Foundation\Http\FormRequest;
|
||||
@@ -53,9 +52,6 @@ class UpdateRequest extends FormRequest
|
||||
*/
|
||||
public function rules(): array
|
||||
{
|
||||
/** @var UserGroup $userGroup */
|
||||
$userGroup = $this->route()->parameter('userGroup');
|
||||
|
||||
return [
|
||||
'title' => ['required', 'min:1', 'max:255'],
|
||||
'native_currency_id' => 'exists:transaction_currencies,id',
|
||||
|
@@ -73,7 +73,7 @@ class CronRequest extends FormRequest
|
||||
{
|
||||
return [
|
||||
'force' => 'in:true,false',
|
||||
'date' => 'nullable|date|after:1900-01-01|before:2099-12-31',
|
||||
'date' => 'nullable|date|after:1970-01-02|before:2038-01-17',
|
||||
];
|
||||
}
|
||||
}
|
||||
|
@@ -39,7 +39,6 @@ use League\Fractal\Resource\Collection as FractalCollection;
|
||||
use League\Fractal\Resource\Item;
|
||||
use League\Fractal\Serializer\JsonApiSerializer;
|
||||
use Psr\Container\ContainerExceptionInterface;
|
||||
use Psr\Container\NotFoundExceptionInterface;
|
||||
use Symfony\Component\HttpFoundation\Exception\BadRequestException;
|
||||
use Symfony\Component\HttpFoundation\ParameterBag;
|
||||
|
||||
@@ -82,7 +81,7 @@ class Controller extends BaseController
|
||||
|
||||
try {
|
||||
$page = (int) request()->get('page');
|
||||
} catch (ContainerExceptionInterface|NotFoundExceptionInterface $e) {
|
||||
} catch (ContainerExceptionInterface) {
|
||||
$page = 1;
|
||||
}
|
||||
|
||||
@@ -117,7 +116,7 @@ class Controller extends BaseController
|
||||
app('log')->warning(sprintf('Ignored invalid date "%s" in API v2 controller parameter check: %s', substr((string) $date, 0, 20), $e->getMessage()));
|
||||
}
|
||||
// out of range? set to null.
|
||||
if ($obj instanceof Carbon && ($obj->year <= 1900 || $obj->year > 2099)) {
|
||||
if ($obj instanceof Carbon && ($obj->year <= 1970 || $obj->year > 2038)) {
|
||||
app('log')->warning(sprintf('Refuse to use date "%s" in API v2 controller parameter check: %s', $field, $obj->toAtomString()));
|
||||
$obj = null;
|
||||
}
|
||||
|
@@ -53,7 +53,7 @@ class ListController extends Controller
|
||||
*/
|
||||
public function index(): JsonResponse
|
||||
{
|
||||
return response()->json([]);
|
||||
return response()->json();
|
||||
// throw new FireflyException('Needs refactoring, move to IndexController.');
|
||||
// $pageSize = $this->parameters->get('limit');
|
||||
// $dates = $request->getAll();
|
||||
|
@@ -65,29 +65,28 @@ class UpdateController extends Controller
|
||||
public function update(UpdateRequest $request, TransactionGroup $transactionGroup): JsonResponse
|
||||
{
|
||||
app('log')->debug('Now in update routine for transaction group [v2]!');
|
||||
$data = $request->getAll();
|
||||
$transactionGroup = $this->groupRepository->update($transactionGroup, $data);
|
||||
$applyRules = $data['apply_rules'] ?? true;
|
||||
$fireWebhooks = $data['fire_webhooks'] ?? true;
|
||||
$runRecalculations = true;
|
||||
$data = $request->getAll();
|
||||
$transactionGroup = $this->groupRepository->update($transactionGroup, $data);
|
||||
$applyRules = $data['apply_rules'] ?? true;
|
||||
$fireWebhooks = $data['fire_webhooks'] ?? true;
|
||||
|
||||
event(new UpdatedTransactionGroup($transactionGroup, $applyRules, $fireWebhooks, $runRecalculations));
|
||||
event(new UpdatedTransactionGroup($transactionGroup, $applyRules, $fireWebhooks, true));
|
||||
app('preferences')->mark();
|
||||
|
||||
/** @var User $admin */
|
||||
$admin = auth()->user();
|
||||
$admin = auth()->user();
|
||||
|
||||
// use new group collector:
|
||||
/** @var GroupCollectorInterface $collector */
|
||||
$collector = app(GroupCollectorInterface::class);
|
||||
$collector = app(GroupCollectorInterface::class);
|
||||
$collector->setUser($admin)->setTransactionGroup($transactionGroup);
|
||||
|
||||
$selectedGroup = $collector->getGroups()->first();
|
||||
$selectedGroup = $collector->getGroups()->first();
|
||||
if (null === $selectedGroup) {
|
||||
throw new FireflyException('200032: Cannot find transaction. Possibly, a rule deleted this transaction after its creation.');
|
||||
}
|
||||
|
||||
$transformer = new TransactionGroupTransformer();
|
||||
$transformer = new TransactionGroupTransformer();
|
||||
$transformer->setParameters($this->parameters);
|
||||
|
||||
return response()->api($this->jsonApiObject('transactions', $selectedGroup, $transformer))->header('Content-Type', self::CONTENT_TYPE);
|
||||
|
@@ -31,6 +31,7 @@ use FireflyIII\Repositories\Currency\CurrencyRepositoryInterface;
|
||||
use FireflyIII\Transformers\CurrencyTransformer;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Pagination\LengthAwarePaginator;
|
||||
use Illuminate\Support\Collection;
|
||||
|
||||
class IndexController extends Controller
|
||||
{
|
||||
@@ -56,6 +57,7 @@ class IndexController extends Controller
|
||||
public function index(IndexRequest $request): JsonResponse
|
||||
{
|
||||
$settings = $request->getAll();
|
||||
$currencies = new Collection();
|
||||
if (true === $settings['enabled']) {
|
||||
$currencies = $this->repository->get();
|
||||
}
|
||||
|
@@ -86,7 +86,7 @@ class AutocompleteRequest extends FormRequest
|
||||
$valid = array_keys($this->types);
|
||||
|
||||
return [
|
||||
'date' => 'nullable|date|after:1900-01-01|before:2100-01-01',
|
||||
'date' => 'nullable|date|after:1970-01-02|before:2038-01-17',
|
||||
'query' => 'nullable|string',
|
||||
'size' => 'nullable|integer|min:1|max:100',
|
||||
'page' => 'nullable|integer|min:1',
|
||||
|
@@ -60,8 +60,8 @@ class BalanceChartRequest extends FormRequest
|
||||
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',
|
||||
'start' => 'required|date|after:1970-01-02|before:2038-01-17',
|
||||
'end' => 'required|date|after_or_equal:start|before:2038-01-17|after:1970-01-02',
|
||||
'accounts.*' => 'required|exists:accounts,id',
|
||||
'period' => sprintf('required|in:%s', implode(',', config('firefly.valid_view_ranges'))),
|
||||
];
|
||||
|
@@ -61,8 +61,8 @@ class ChartRequest extends FormRequest
|
||||
public function rules(): array
|
||||
{
|
||||
return [
|
||||
'start' => 'required|date|after:1900-01-01|before:2099-12-31|before_or_equal:end',
|
||||
'end' => 'required|date|after:1900-01-01|before:2099-12-31|after_or_equal:start',
|
||||
'start' => 'required|date|after:1970-01-02|before:2038-01-17|before_or_equal:end',
|
||||
'end' => 'required|date|after:1970-01-02|before:2038-01-17|after_or_equal:start',
|
||||
'preselected' => sprintf('nullable|in:%s', implode(',', config('firefly.preselected_accounts'))),
|
||||
'period' => sprintf('nullable|in:%s', implode(',', config('firefly.valid_view_ranges'))),
|
||||
'accounts.*' => 'exists:accounts,id',
|
||||
|
@@ -60,8 +60,8 @@ class DashboardChartRequest extends FormRequest
|
||||
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',
|
||||
'start' => 'required|date|after:1970-01-02|before:2038-01-17',
|
||||
'end' => 'required|date|after_or_equal:start|before:2038-01-17|after:1970-01-02',
|
||||
'preselected' => sprintf('in:%s', implode(',', config('firefly.preselected_accounts'))),
|
||||
'accounts.*' => 'exists:accounts,id',
|
||||
];
|
||||
|
@@ -55,8 +55,8 @@ class DateRequest extends FormRequest
|
||||
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',
|
||||
'start' => 'required|date|after:1970-01-02|before:2038-01-17',
|
||||
'end' => 'required|date|after_or_equal:start|before:2038-01-17|after:1970-01-02',
|
||||
];
|
||||
}
|
||||
}
|
||||
|
@@ -53,7 +53,7 @@ class SingleDateRequest extends FormRequest
|
||||
public function rules(): array
|
||||
{
|
||||
return [
|
||||
'date' => 'required|date|after:1900-01-01|before:2099-12-31',
|
||||
'date' => 'required|date|after:1970-01-02|before:2038-01-17',
|
||||
];
|
||||
}
|
||||
}
|
||||
|
@@ -63,9 +63,9 @@ class IndexRequest extends FormRequest
|
||||
public function rules(): array
|
||||
{
|
||||
return [
|
||||
'date' => 'date|after:1900-01-01|before:2099-12-31',
|
||||
'start' => 'date|after:1900-01-01|before:2099-12-31|before:end|required_with:end',
|
||||
'end' => 'date|after:1900-01-01|before:2099-12-31|after:start|required_with:start',
|
||||
'date' => 'date|after:1970-01-02|before:2038-01-17',
|
||||
'start' => 'date|after:1970-01-02|before:2038-01-17|before:end|required_with:end',
|
||||
'end' => 'date|after:1970-01-02|before:2038-01-17|after:start|required_with:start',
|
||||
];
|
||||
}
|
||||
}
|
||||
|
@@ -109,8 +109,8 @@ class InfiniteListRequest extends FormRequest
|
||||
public function rules(): array
|
||||
{
|
||||
return [
|
||||
'start' => 'date|after:1900-01-01|before:2099-12-31',
|
||||
'end' => 'date|after:start|after:1900-01-01|before:2099-12-31',
|
||||
'start' => 'date|after:1970-01-02|before:2038-01-17',
|
||||
'end' => 'date|after:start|after:1970-01-02|before:2038-01-17',
|
||||
'start_row' => 'integer|min:0|max:4294967296',
|
||||
'end_row' => 'integer|min:0|max:4294967296|gt:start_row',
|
||||
];
|
||||
|
@@ -84,8 +84,8 @@ class ListRequest extends FormRequest
|
||||
public function rules(): array
|
||||
{
|
||||
return [
|
||||
'start' => 'date|after:1900-01-01|before:2099-12-31',
|
||||
'end' => 'date|after:start|after:1900-01-01|before:2099-12-31',
|
||||
'start' => 'date|after:1970-01-02|before:2038-01-17',
|
||||
'end' => 'date|after:start|after:1970-01-02|before:2038-01-17',
|
||||
];
|
||||
}
|
||||
}
|
||||
|
@@ -68,7 +68,7 @@ class UpdateRequest extends Request
|
||||
#[Override]
|
||||
public function getAll(): array
|
||||
{
|
||||
app('log')->debug(sprintf('Now in %s', __METHOD__));
|
||||
Log::debug(sprintf('Now in %s', __METHOD__));
|
||||
$this->integerFields = ['order', 'currency_id', 'foreign_currency_id', 'transaction_journal_id', 'source_id', 'destination_id', 'budget_id', 'category_id', 'bill_id', 'recurrence_id'];
|
||||
$this->dateFields = ['date', 'interest_date', 'book_date', 'process_date', 'due_date', 'payment_date', 'invoice_date'];
|
||||
$this->textareaFields = ['notes'];
|
||||
@@ -101,7 +101,7 @@ class UpdateRequest extends Request
|
||||
*/
|
||||
private function getTransactionData(): array
|
||||
{
|
||||
app('log')->debug(sprintf('Now in %s', __METHOD__));
|
||||
Log::debug(sprintf('Now in %s', __METHOD__));
|
||||
$return = [];
|
||||
|
||||
/** @var null|array $transactions */
|
||||
@@ -185,9 +185,9 @@ class UpdateRequest extends Request
|
||||
private function getDateData(array $current, array $transaction): array
|
||||
{
|
||||
foreach ($this->dateFields as $fieldName) {
|
||||
app('log')->debug(sprintf('Now at date field %s', $fieldName));
|
||||
Log::debug(sprintf('Now at date field %s', $fieldName));
|
||||
if (array_key_exists($fieldName, $transaction)) {
|
||||
app('log')->debug(sprintf('New value: "%s"', (string) $transaction[$fieldName]));
|
||||
Log::debug(sprintf('New value: "%s"', $transaction[$fieldName]));
|
||||
$current[$fieldName] = $this->dateFromValue((string) $transaction[$fieldName]);
|
||||
}
|
||||
}
|
||||
@@ -252,7 +252,7 @@ class UpdateRequest extends Request
|
||||
#[Override]
|
||||
public function rules(): array
|
||||
{
|
||||
app('log')->debug(sprintf('Now in %s', __METHOD__));
|
||||
Log::debug(sprintf('Now in %s', __METHOD__));
|
||||
$validProtocols = config('firefly.valid_url_protocols');
|
||||
|
||||
return [
|
||||
@@ -336,7 +336,7 @@ class UpdateRequest extends Request
|
||||
#[Override]
|
||||
public function withValidator(Validator $validator): void
|
||||
{
|
||||
app('log')->debug('Now in withValidator');
|
||||
Log::debug('Now in withValidator');
|
||||
|
||||
/** @var TransactionGroup $transactionGroup */
|
||||
$transactionGroup = $this->route()->parameter('userGroupTransaction');
|
||||
|
@@ -58,11 +58,13 @@ use function Safe\parse_url;
|
||||
*/
|
||||
class Handler extends ExceptionHandler
|
||||
{
|
||||
public static ?Throwable $lastError = null;
|
||||
|
||||
/**
|
||||
* @var array<int, class-string<Throwable>>
|
||||
*/
|
||||
protected $dontReport
|
||||
= [
|
||||
= [
|
||||
AuthenticationException::class,
|
||||
LaravelValidationException::class,
|
||||
NotFoundHttpException::class,
|
||||
@@ -123,7 +125,7 @@ class Handler extends ExceptionHandler
|
||||
// somehow Laravel handler does not catch this:
|
||||
app('log')->debug('Return JSON unauthenticated error.');
|
||||
|
||||
return response()->json(['message' => 'Unauthenticated', 'exception' => 'AuthenticationException'], 401);
|
||||
return response()->json(['message' => $e->getMessage(), 'exception' => 'AuthenticationException'], 401);
|
||||
}
|
||||
|
||||
if ($e instanceof OAuthServerException && $expectsJson) {
|
||||
@@ -215,13 +217,14 @@ class Handler extends ExceptionHandler
|
||||
#[Override]
|
||||
public function report(Throwable $e): void
|
||||
{
|
||||
$doMailError = (bool) config('firefly.send_error_message');
|
||||
self::$lastError = $e;
|
||||
$doMailError = (bool) config('firefly.send_error_message');
|
||||
if ($this->shouldntReportLocal($e) || !$doMailError) {
|
||||
parent::report($e);
|
||||
|
||||
return;
|
||||
}
|
||||
$userData = [
|
||||
$userData = [
|
||||
'id' => 0,
|
||||
'email' => 'unknown@example.com',
|
||||
];
|
||||
@@ -230,9 +233,9 @@ class Handler extends ExceptionHandler
|
||||
$userData['email'] = auth()->user()->email;
|
||||
}
|
||||
|
||||
$headers = request()->headers->all();
|
||||
$headers = request()->headers->all();
|
||||
|
||||
$data = [
|
||||
$data = [
|
||||
'class' => $e::class,
|
||||
'errorMessage' => $e->getMessage(),
|
||||
'time' => Carbon::now()->format('r'),
|
||||
@@ -250,8 +253,8 @@ class Handler extends ExceptionHandler
|
||||
];
|
||||
|
||||
// create job that will mail.
|
||||
$ipAddress = request()->ip() ?? '0.0.0.0';
|
||||
$job = new MailError($userData, (string) config('firefly.site_owner'), $ipAddress, $data);
|
||||
$ipAddress = request()->ip() ?? '0.0.0.0';
|
||||
$job = new MailError($userData, (string) config('firefly.site_owner'), $ipAddress, $data);
|
||||
dispatch($job);
|
||||
|
||||
parent::report($e);
|
||||
|
@@ -75,15 +75,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,
|
||||
'user_group_id' => $this->userGroup->id,
|
||||
'tag' => trim((string) $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->userGroup->id,
|
||||
'tag' => trim((string) $data['tag']),
|
||||
'tag_mode' => 'nothing',
|
||||
'date' => $data['date'],
|
||||
'description' => $data['description'],
|
||||
'latitude' => null,
|
||||
'longitude' => null,
|
||||
'zoomLevel' => null,
|
||||
];
|
||||
|
||||
/** @var null|Tag $tag */
|
||||
|
@@ -32,11 +32,14 @@ use FireflyIII\Models\TransactionGroup;
|
||||
use FireflyIII\Models\TransactionJournal;
|
||||
use FireflyIII\Models\Webhook;
|
||||
use FireflyIII\Models\WebhookMessage;
|
||||
use FireflyIII\Support\Facades\Amount;
|
||||
use FireflyIII\Support\JsonApi\Enrichments\AccountEnrichment;
|
||||
use FireflyIII\Transformers\AccountTransformer;
|
||||
use FireflyIII\Transformers\TransactionGroupTransformer;
|
||||
use FireflyIII\User;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Support\Collection;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
use Ramsey\Uuid\Uuid;
|
||||
use Symfony\Component\HttpFoundation\ParameterBag;
|
||||
|
||||
@@ -59,14 +62,14 @@ class StandardMessageGenerator implements MessageGeneratorInterface
|
||||
|
||||
public function generateMessages(): void
|
||||
{
|
||||
app('log')->debug(__METHOD__);
|
||||
Log::debug(__METHOD__);
|
||||
// get the webhooks:
|
||||
if (0 === $this->webhooks->count()) {
|
||||
$this->webhooks = $this->getWebhooks();
|
||||
}
|
||||
|
||||
// do some debugging
|
||||
app('log')->debug(
|
||||
Log::debug(
|
||||
sprintf('StandardMessageGenerator will generate messages for %d object(s) and %d webhook(s).', $this->objects->count(), $this->webhooks->count())
|
||||
);
|
||||
$this->run();
|
||||
@@ -79,13 +82,13 @@ class StandardMessageGenerator implements MessageGeneratorInterface
|
||||
|
||||
private function run(): void
|
||||
{
|
||||
app('log')->debug('Now in StandardMessageGenerator::run');
|
||||
Log::debug('Now in StandardMessageGenerator::run');
|
||||
|
||||
/** @var Webhook $webhook */
|
||||
foreach ($this->webhooks as $webhook) {
|
||||
$this->runWebhook($webhook);
|
||||
}
|
||||
app('log')->debug('Done with StandardMessageGenerator::run');
|
||||
Log::debug('Done with StandardMessageGenerator::run');
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -93,7 +96,7 @@ class StandardMessageGenerator implements MessageGeneratorInterface
|
||||
*/
|
||||
private function runWebhook(Webhook $webhook): void
|
||||
{
|
||||
app('log')->debug(sprintf('Now in runWebhook(#%d)', $webhook->id));
|
||||
Log::debug(sprintf('Now in runWebhook(#%d)', $webhook->id));
|
||||
|
||||
/** @var Model $object */
|
||||
foreach ($this->objects as $object) {
|
||||
@@ -108,7 +111,7 @@ class StandardMessageGenerator implements MessageGeneratorInterface
|
||||
{
|
||||
$class = $model::class;
|
||||
// Line is ignored because all of Firefly III's Models have an id property.
|
||||
app('log')->debug(sprintf('Now in generateMessage(#%d, %s#%d)', $webhook->id, $class, $model->id));
|
||||
Log::debug(sprintf('Now in generateMessage(#%d, %s#%d)', $webhook->id, $class, $model->id));
|
||||
|
||||
$uuid = Uuid::uuid4();
|
||||
$basicMessage = [
|
||||
@@ -125,7 +128,7 @@ class StandardMessageGenerator implements MessageGeneratorInterface
|
||||
switch ($class) {
|
||||
default:
|
||||
// Line is ignored because all of Firefly III's Models have an id property.
|
||||
app('log')->error(
|
||||
Log::error(
|
||||
sprintf('Webhook #%d was given %s#%d to deal with but can\'t extract user ID from it.', $webhook->id, $class, $model->id)
|
||||
);
|
||||
|
||||
@@ -141,7 +144,7 @@ class StandardMessageGenerator implements MessageGeneratorInterface
|
||||
// then depends on the response what to put in the message:
|
||||
switch ($webhook->response) {
|
||||
default:
|
||||
app('log')->error(
|
||||
Log::error(
|
||||
sprintf('The response code for webhook #%d is "%d" and the message generator cant handle it. Soft fail.', $webhook->id, $webhook->response)
|
||||
);
|
||||
|
||||
@@ -159,10 +162,10 @@ class StandardMessageGenerator implements MessageGeneratorInterface
|
||||
try {
|
||||
$basicMessage['content'] = $transformer->transformObject($model);
|
||||
} catch (FireflyException $e) {
|
||||
app('log')->error(
|
||||
Log::error(
|
||||
sprintf('The transformer could not include the requested transaction group for webhook #%d: %s', $webhook->id, $e->getMessage())
|
||||
);
|
||||
app('log')->error($e->getTraceAsString());
|
||||
Log::error($e->getTraceAsString());
|
||||
|
||||
return;
|
||||
}
|
||||
@@ -172,6 +175,10 @@ class StandardMessageGenerator implements MessageGeneratorInterface
|
||||
case WebhookResponse::ACCOUNTS->value:
|
||||
/** @var TransactionGroup $model */
|
||||
$accounts = $this->collectAccounts($model);
|
||||
$enrichment = new AccountEnrichment();
|
||||
$enrichment->setUser($model->user);
|
||||
$enrichment->setNative(Amount::getNativeCurrencyByUserGroup($model->userGroup));
|
||||
$accounts = $enrichment->enrich($accounts);
|
||||
foreach ($accounts as $account) {
|
||||
$transformer = new AccountTransformer();
|
||||
$transformer->setParameters(new ParameterBag());
|
||||
@@ -210,7 +217,7 @@ class StandardMessageGenerator implements MessageGeneratorInterface
|
||||
$webhookMessage->uuid = $message['uuid'];
|
||||
$webhookMessage->message = $message;
|
||||
$webhookMessage->save();
|
||||
app('log')->debug(sprintf('Stored new webhook message #%d', $webhookMessage->id));
|
||||
Log::debug(sprintf('Stored new webhook message #%d', $webhookMessage->id));
|
||||
}
|
||||
|
||||
public function setObjects(Collection $objects): void
|
||||
|
@@ -23,6 +23,7 @@ declare(strict_types=1);
|
||||
|
||||
namespace FireflyIII\Handlers\Events;
|
||||
|
||||
use Deprecated;
|
||||
use Carbon\Carbon;
|
||||
use FireflyIII\Events\RequestedVersionCheckStatus;
|
||||
use FireflyIII\Exceptions\FireflyException;
|
||||
@@ -42,9 +43,8 @@ class VersionCheckEventHandler
|
||||
* Checks with GitHub to see if there is a new version.
|
||||
*
|
||||
* @throws FireflyException
|
||||
*
|
||||
* @deprecated ?
|
||||
*/
|
||||
#[Deprecated(message: '?')]
|
||||
public function checkForUpdates(RequestedVersionCheckStatus $event): void
|
||||
{
|
||||
Log::debug('Now in checkForUpdates()');
|
||||
|
@@ -26,6 +26,7 @@ namespace FireflyIII\Handlers\Events;
|
||||
|
||||
use FireflyIII\Jobs\SendWebhookMessage;
|
||||
use FireflyIII\Models\WebhookMessage;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
|
||||
/**
|
||||
* Class WebhookEventHandler
|
||||
@@ -37,7 +38,13 @@ class WebhookEventHandler
|
||||
*/
|
||||
public function sendWebhookMessages(): void
|
||||
{
|
||||
app('log')->debug(sprintf('Now in %s', __METHOD__));
|
||||
Log::debug(sprintf('Now in %s', __METHOD__));
|
||||
if (false === config('firefly.feature_flags.webhooks') || false === config('firefly.allow_webhooks')) {
|
||||
Log::info('Webhook event handler is disabled, do not run sendWebhookMessages().');
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// kick off the job!
|
||||
$messages = WebhookMessage::where('webhook_messages.sent', false)
|
||||
->get(['webhook_messages.*'])
|
||||
@@ -45,14 +52,14 @@ class WebhookEventHandler
|
||||
static fn (WebhookMessage $message) => $message->webhookAttempts()->count() <= 2
|
||||
)->splice(0, 5)
|
||||
;
|
||||
app('log')->debug(sprintf('Found %d webhook message(s) ready to be send.', $messages->count()));
|
||||
Log::debug(sprintf('Found %d webhook message(s) ready to be send.', $messages->count()));
|
||||
foreach ($messages as $message) {
|
||||
if (false === $message->sent) {
|
||||
app('log')->debug(sprintf('Send message #%d', $message->id));
|
||||
Log::debug(sprintf('Send message #%d', $message->id));
|
||||
SendWebhookMessage::dispatch($message)->afterResponse();
|
||||
}
|
||||
if (false !== $message->sent) {
|
||||
app('log')->debug(sprintf('Skip message #%d', $message->id));
|
||||
Log::debug(sprintf('Skip message #%d', $message->id));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -434,6 +434,7 @@ class GroupCollector implements GroupCollectorInterface
|
||||
|
||||
public function findNothing(): GroupCollectorInterface
|
||||
{
|
||||
Log::warning('The search engine was instructed to FIND NOTHING. This may be a bug.');
|
||||
$this->query->where('transaction_groups.id', -1);
|
||||
|
||||
return $this;
|
||||
@@ -557,7 +558,6 @@ class GroupCollector implements GroupCollectorInterface
|
||||
$groups[$groupId]['transactions'][$journalId] = $this->parseAugmentedJournal($augumentedJournal);
|
||||
}
|
||||
}
|
||||
|
||||
$groups = $this->parseSums($groups);
|
||||
|
||||
return new Collection($groups);
|
||||
@@ -1094,6 +1094,10 @@ class GroupCollector implements GroupCollectorInterface
|
||||
->whereNull('transaction_groups.deleted_at')
|
||||
->whereNull('transaction_journals.deleted_at')
|
||||
->whereNull('source.deleted_at')
|
||||
|
||||
// #10507 ignore opening balance.
|
||||
->where('transaction_types.type', '!=', TransactionTypeEnum::OPENING_BALANCE->value)
|
||||
|
||||
->whereNotNull('transaction_groups.id')
|
||||
->whereNull('destination.deleted_at')
|
||||
->orderBy('transaction_journals.date', 'DESC')
|
||||
|
@@ -24,6 +24,7 @@ declare(strict_types=1);
|
||||
|
||||
namespace FireflyIII\Helpers\Report;
|
||||
|
||||
use Deprecated;
|
||||
use Carbon\Carbon;
|
||||
use FireflyIII\Enums\AccountTypeEnum;
|
||||
use FireflyIII\Exceptions\FireflyException;
|
||||
@@ -81,7 +82,7 @@ class NetWorth implements NetWorthInterface
|
||||
|
||||
/** @var Account $account */
|
||||
foreach ($accounts as $account) {
|
||||
Log::debug(sprintf('Now at account #%d ("%s")', $account->id, $account->name));
|
||||
// Log::debug(sprintf('Now at account #%d ("%s")', $account->id, $account->name));
|
||||
$currency = $this->accountRepository->getAccountCurrency($account) ?? $default;
|
||||
$useNative = $convertToNative && $default->id !== $currency->id;
|
||||
$currency = $useNative ? $default : $currency;
|
||||
@@ -92,12 +93,12 @@ class NetWorth implements NetWorthInterface
|
||||
$balance = $balances[$account->id]['balance'] ?? '0';
|
||||
$nativeBalance = $balances[$account->id]['native_balance'] ?? '0';
|
||||
}
|
||||
Log::debug(sprintf('Balance is %s, native balance is %s', $balance, $nativeBalance));
|
||||
// Log::debug(sprintf('Balance is %s, native balance is %s', $balance, $nativeBalance));
|
||||
// always subtract virtual balance again.
|
||||
$balance = '' !== (string) $account->virtual_balance ? bcsub($balance, (string) $account->virtual_balance) : $balance;
|
||||
$nativeBalance = '' !== (string) $account->native_virtual_balance ? bcsub($nativeBalance, (string) $account->native_virtual_balance) : $nativeBalance;
|
||||
$amountToUse = $useNative ? $nativeBalance : $balance;
|
||||
Log::debug(sprintf('Will use %s %s', $currencyCode, $amountToUse));
|
||||
// Log::debug(sprintf('Will use %s %s', $currencyCode, $amountToUse));
|
||||
|
||||
$netWorth[$currencyCode] ??= [
|
||||
'balance' => '0',
|
||||
@@ -134,9 +135,7 @@ class NetWorth implements NetWorthInterface
|
||||
$this->currencyRepos->setUserGroup($this->userGroup);
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated
|
||||
*/
|
||||
#[Deprecated]
|
||||
public function sumNetWorthByCurrency(Carbon $date): array
|
||||
{
|
||||
/**
|
||||
|
@@ -24,6 +24,7 @@ declare(strict_types=1);
|
||||
|
||||
namespace FireflyIII\Helpers\Report;
|
||||
|
||||
use Deprecated;
|
||||
use Carbon\Carbon;
|
||||
use FireflyIII\Models\UserGroup;
|
||||
use FireflyIII\User;
|
||||
@@ -53,8 +54,7 @@ interface NetWorthInterface
|
||||
* TODO move to repository
|
||||
*
|
||||
* Same as above but cleaner function with less dependencies.
|
||||
*
|
||||
* @deprecated
|
||||
*/
|
||||
#[Deprecated]
|
||||
public function sumNetWorthByCurrency(Carbon $date): array;
|
||||
}
|
||||
|
@@ -88,7 +88,9 @@ class IndexController extends Controller
|
||||
|
||||
/** @var Carbon $end */
|
||||
$end = clone session('end', today(config('app.timezone'))->endOfMonth());
|
||||
$start->subDay();
|
||||
|
||||
// #10618 go to the end of the previous day.
|
||||
$start->subSecond();
|
||||
|
||||
$ids = $accounts->pluck('id')->toArray();
|
||||
Log::debug(sprintf('inactive start: finalAccountsBalance("%s")', $start->format('Y-m-d H:i:s')));
|
||||
@@ -164,8 +166,8 @@ class IndexController extends Controller
|
||||
/** @var Carbon $end */
|
||||
$end = clone session('end', today(config('app.timezone'))->endOfMonth());
|
||||
|
||||
// 2025-05-11 removed this so start is exactly the start of the month.
|
||||
// $start->subDay();
|
||||
// #10618 go to the end of the previous day.
|
||||
$start->subSecond();
|
||||
|
||||
$ids = $accounts->pluck('id')->toArray();
|
||||
Log::debug(sprintf('index start: finalAccountsBalance("%s")', $start->format('Y-m-d H:i:s')));
|
||||
|
@@ -64,7 +64,7 @@ class ForgotPasswordController extends Controller
|
||||
public function sendResetLinkEmail(Request $request, UserRepositoryInterface $repository)
|
||||
{
|
||||
Log::info('Start of sendResetLinkEmail()');
|
||||
if ('web' !== config('firefly.authentication_guard')) {
|
||||
if ('web' !== config('firefly.authentication_guard')) {
|
||||
$message = sprintf('Cannot reset password when authenticating over "%s".', config('firefly.authentication_guard'));
|
||||
Log::error($message);
|
||||
|
||||
|
@@ -29,7 +29,9 @@ use FireflyIII\Http\Controllers\Controller;
|
||||
use FireflyIII\Models\Bill;
|
||||
use FireflyIII\Repositories\Bill\BillRepositoryInterface;
|
||||
use FireflyIII\Repositories\ObjectGroup\OrganisesObjectGroups;
|
||||
use FireflyIII\Support\JsonApi\Enrichments\SubscriptionEnrichment;
|
||||
use FireflyIII\Transformers\BillTransformer;
|
||||
use FireflyIII\User;
|
||||
use Illuminate\Contracts\View\Factory;
|
||||
use Illuminate\Contracts\View\View;
|
||||
use Illuminate\Foundation\Application;
|
||||
@@ -76,11 +78,26 @@ class IndexController extends Controller
|
||||
$collection = $this->repository->getBills();
|
||||
$total = $collection->count();
|
||||
|
||||
|
||||
|
||||
$parameters = new ParameterBag();
|
||||
// sub one day from temp start so the last paid date is one day before it should be.
|
||||
$tempStart = clone $start;
|
||||
// 2023-06-23 do not sub one day from temp start, fix is in BillTransformer::payDates instead
|
||||
// $tempStart->subDay();
|
||||
|
||||
// enrich
|
||||
/** @var User $admin */
|
||||
$admin = auth()->user();
|
||||
$enrichment = new SubscriptionEnrichment();
|
||||
$enrichment->setUser($admin);
|
||||
$enrichment->setConvertToNative($this->convertToNative);
|
||||
$enrichment->setNative($this->defaultCurrency);
|
||||
$enrichment->setStart($tempStart);
|
||||
$enrichment->setEnd($end);
|
||||
$collection = $enrichment->enrich($collection);
|
||||
|
||||
|
||||
$parameters->set('start', $tempStart);
|
||||
$parameters->set('end', $end);
|
||||
$parameters->set('convertToNative', $this->convertToNative);
|
||||
|
@@ -30,9 +30,11 @@ use FireflyIII\Http\Controllers\Controller;
|
||||
use FireflyIII\Models\Attachment;
|
||||
use FireflyIII\Models\Bill;
|
||||
use FireflyIII\Repositories\Bill\BillRepositoryInterface;
|
||||
use FireflyIII\Support\JsonApi\Enrichments\SubscriptionEnrichment;
|
||||
use FireflyIII\TransactionRules\Engine\RuleEngineInterface;
|
||||
use FireflyIII\Transformers\AttachmentTransformer;
|
||||
use FireflyIII\Transformers\BillTransformer;
|
||||
use FireflyIII\User;
|
||||
use Illuminate\Contracts\View\Factory;
|
||||
use Illuminate\Http\RedirectResponse;
|
||||
use Illuminate\Http\Request;
|
||||
@@ -142,6 +144,17 @@ class ShowController extends Controller
|
||||
$parameters->set('start', $start);
|
||||
$parameters->set('end', $end);
|
||||
|
||||
// enrich
|
||||
/** @var User $admin */
|
||||
$admin = auth()->user();
|
||||
$enrichment = new SubscriptionEnrichment();
|
||||
$enrichment->setUser($admin);
|
||||
$enrichment->setConvertToNative($this->convertToNative);
|
||||
$enrichment->setNative($this->defaultCurrency);
|
||||
$enrichment->setStart($start);
|
||||
$enrichment->setEnd($end);
|
||||
$bill = $enrichment->enrichSingle($bill);
|
||||
|
||||
/** @var BillTransformer $transformer */
|
||||
$transformer = app(BillTransformer::class);
|
||||
$transformer->setParameters($parameters);
|
||||
|
@@ -91,7 +91,7 @@ class IndexController extends Controller
|
||||
public function index(?Carbon $start = null, ?Carbon $end = null)
|
||||
{
|
||||
$this->abRepository->cleanup();
|
||||
app('log')->debug(sprintf('Start of IndexController::index("%s", "%s")', $start?->format('Y-m-d'), $end?->format('Y-m-d')));
|
||||
Log::debug(sprintf('Start of IndexController::index("%s", "%s")', $start?->format('Y-m-d'), $end?->format('Y-m-d')));
|
||||
|
||||
// collect some basic vars:
|
||||
$range = app('navigation')->getViewRange(true);
|
||||
@@ -199,12 +199,12 @@ class IndexController extends Controller
|
||||
// get all budgets, and paginate them into $budgets.
|
||||
$collection = $this->repository->getActiveBudgets();
|
||||
$budgets = [];
|
||||
app('log')->debug(sprintf('7) Start is "%s", end is "%s"', $start->format('Y-m-d H:i:s'), $end->format('Y-m-d H:i:s')));
|
||||
Log::debug(sprintf('(getAllBudgets) Start is "%s", end is "%s"', $start->format('Y-m-d H:i:s'), $end->format('Y-m-d H:i:s')));
|
||||
|
||||
// complement budget with budget limits in range, and expenses in currency X in range.
|
||||
/** @var Budget $current */
|
||||
foreach ($collection as $current) {
|
||||
app('log')->debug(sprintf('Working on budget #%d ("%s")', $current->id, $current->name));
|
||||
Log::debug(sprintf('Working on budget #%d ("%s")', $current->id, $current->name));
|
||||
$array = $current->toArray();
|
||||
$array['spent'] = [];
|
||||
$array['spent_total'] = [];
|
||||
@@ -215,7 +215,7 @@ class IndexController extends Controller
|
||||
|
||||
/** @var BudgetLimit $limit */
|
||||
foreach ($budgetLimits as $limit) {
|
||||
app('log')->debug(sprintf('Working on budget limit #%d', $limit->id));
|
||||
Log::debug(sprintf('Working on budget limit #%d', $limit->id));
|
||||
$currency = $limit->transactionCurrency ?? $defaultCurrency;
|
||||
$amount = app('steam')->bcround($limit->amount, $currency->decimal_places);
|
||||
$array['budgeted'][] = [
|
||||
@@ -225,14 +225,17 @@ class IndexController extends Controller
|
||||
'start_date' => $limit->start_date->isoFormat($this->monthAndDayFormat),
|
||||
'end_date' => $limit->end_date->isoFormat($this->monthAndDayFormat),
|
||||
'in_range' => $limit->start_date->isSameDay($start) && $limit->end_date->isSameDay($end),
|
||||
'total_days' => $limit->start_date->diffInDays($limit->end_date) + 1,
|
||||
'currency_id' => $currency->id,
|
||||
'currency_symbol' => $currency->symbol,
|
||||
'currency_name' => $currency->name,
|
||||
'currency_decimal_places' => $currency->decimal_places,
|
||||
];
|
||||
app('log')->debug(sprintf('The amount budgeted for budget limit #%d is %s %s', $limit->id, $currency->code, $amount));
|
||||
Log::debug(sprintf('The amount budgeted for budget limit #%d is %s %s', $limit->id, $currency->code, $amount));
|
||||
}
|
||||
|
||||
// #10463
|
||||
|
||||
/** @var TransactionCurrency $currency */
|
||||
foreach ($currencies as $currency) {
|
||||
$spentArr = $this->opsRepository->sumExpenses($start, $end, null, new Collection([$current]), $currency, false);
|
||||
@@ -259,6 +262,8 @@ class IndexController extends Controller
|
||||
|
||||
/** @var array $budget */
|
||||
foreach ($budgets as $budget) {
|
||||
Log::debug(sprintf('Now working on budget #%d ("%s")', $budget['id'], $budget['name']));
|
||||
|
||||
/** @var array $spent */
|
||||
foreach ($budget['spent'] as $spent) {
|
||||
$currencyId = $spent['currency_id'];
|
||||
|
@@ -23,8 +23,6 @@ declare(strict_types=1);
|
||||
|
||||
namespace FireflyIII\Http\Controllers;
|
||||
|
||||
use function Safe\realpath;
|
||||
use function Safe\ini_get;
|
||||
use FireflyIII\Models\TransactionCurrency;
|
||||
use FireflyIII\Support\Facades\Amount;
|
||||
use FireflyIII\Support\Facades\Steam;
|
||||
@@ -38,6 +36,9 @@ use Illuminate\Support\Facades\Config;
|
||||
use Illuminate\Support\Facades\View;
|
||||
use Illuminate\Support\Facades\Route;
|
||||
|
||||
use function Safe\realpath;
|
||||
use function Safe\ini_get;
|
||||
|
||||
/**
|
||||
* Class Controller.
|
||||
*
|
||||
@@ -78,12 +79,12 @@ abstract class Controller extends BaseController
|
||||
View::share('featuringWebhooks', true === config('firefly.feature_flags.webhooks') && true === config('firefly.allow_webhooks'));
|
||||
|
||||
// share custom auth guard info.
|
||||
$authGuard = config('firefly.authentication_guard');
|
||||
$logoutUrl = config('firefly.custom_logout_url');
|
||||
$authGuard = config('firefly.authentication_guard');
|
||||
$logoutUrl = config('firefly.custom_logout_url');
|
||||
|
||||
// overrule v2 layout back to v1.
|
||||
if ('true' === request()->get('force_default_layout') && 'v2' === config('view.layout')) {
|
||||
//config('view.layout','v1');
|
||||
// config('view.layout','v1');
|
||||
Config::set('view.layout', 'v1');
|
||||
View::getFinder()->setPaths([realpath(base_path('resources/views'))]); // @phpstan-ignore-line
|
||||
}
|
||||
@@ -92,15 +93,15 @@ abstract class Controller extends BaseController
|
||||
View::share('logoutUrl', $logoutUrl);
|
||||
|
||||
// upload size
|
||||
$maxFileSize = Steam::phpBytes((string) ini_get('upload_max_filesize'));
|
||||
$maxPostSize = Steam::phpBytes((string) ini_get('post_max_size'));
|
||||
$uploadSize = min($maxFileSize, $maxPostSize);
|
||||
$maxFileSize = Steam::phpBytes((string) ini_get('upload_max_filesize'));
|
||||
$maxPostSize = Steam::phpBytes((string) ini_get('post_max_size'));
|
||||
$uploadSize = min($maxFileSize, $maxPostSize);
|
||||
View::share('uploadSize', $uploadSize);
|
||||
|
||||
// share is alpha, is beta
|
||||
$isAlpha = false;
|
||||
$isBeta = false;
|
||||
$isDevelop = false;
|
||||
$isAlpha = false;
|
||||
$isBeta = false;
|
||||
$isDevelop = false;
|
||||
if (str_contains((string) config('firefly.version'), 'alpha')) {
|
||||
$isAlpha = true;
|
||||
}
|
||||
@@ -118,7 +119,7 @@ abstract class Controller extends BaseController
|
||||
|
||||
$this->middleware(
|
||||
function ($request, $next): mixed {
|
||||
$locale = Steam::getLocale();
|
||||
$locale = Steam::getLocale();
|
||||
// translations for specific strings:
|
||||
$this->monthFormat = (string) trans('config.month_js', [], $locale);
|
||||
$this->monthAndDayFormat = (string) trans('config.month_and_day_js', [], $locale);
|
||||
|
@@ -23,6 +23,7 @@ declare(strict_types=1);
|
||||
|
||||
namespace FireflyIII\Http\Controllers\Json;
|
||||
|
||||
use Deprecated;
|
||||
use Carbon\Carbon;
|
||||
use FireflyIII\Enums\AccountTypeEnum;
|
||||
use FireflyIII\Enums\TransactionTypeEnum;
|
||||
@@ -46,9 +47,8 @@ class BoxController extends Controller
|
||||
|
||||
/**
|
||||
* Deprecated method, no longer in use.
|
||||
*
|
||||
* @deprecated
|
||||
*/
|
||||
#[Deprecated]
|
||||
public function available(): JsonResponse
|
||||
{
|
||||
return response()->json([]);
|
||||
|
@@ -107,7 +107,7 @@ class RecurrenceController extends Controller
|
||||
$repetitionMoment = str_ireplace('ndom,', '', $request->get('type'));
|
||||
}
|
||||
if ('yearly' === $repetitionType) {
|
||||
$repetitionMoment = explode(',', (string) $request->get('type'))[1] ?? '2018-01-01';
|
||||
$repetitionMoment = explode(',', (string) $request->get('type'))[1] ?? '2025-01-01';
|
||||
}
|
||||
$actualStart->startOfDay();
|
||||
$repetition = new RecurrenceRepetition();
|
||||
|
@@ -154,12 +154,18 @@ class TagController extends Controller
|
||||
*/
|
||||
public function index(TagRepositoryInterface $repository)
|
||||
{
|
||||
// start with oldest tag
|
||||
// start with the oldest tag
|
||||
$first = session('first', today()) ?? today();
|
||||
$oldestTagDate = $repository->oldestTag() instanceof Tag ? $repository->oldestTag()->date : clone $first;
|
||||
$newestTagDate = $repository->newestTag() instanceof Tag ? $repository->newestTag()->date : today();
|
||||
$oldestTagDate->startOfYear();
|
||||
$newestTagDate->endOfYear();
|
||||
|
||||
if ($oldestTagDate->year < 1970) {
|
||||
$oldestTagDate = Carbon::create(1970, 1, 1, 0, 0, 0, config('app.timezone'));
|
||||
request()->session()->flash('error', trans('firefly.bad_date_transaction'));
|
||||
}
|
||||
|
||||
$tags = [];
|
||||
$tags['no-date'] = $repository->getTagsInYear(null);
|
||||
|
||||
|
@@ -26,10 +26,12 @@ namespace FireflyIII\Http\Middleware;
|
||||
|
||||
use Closure;
|
||||
use FireflyIII\Exceptions\FireflyException;
|
||||
use FireflyIII\Exceptions\Handler;
|
||||
use FireflyIII\User;
|
||||
use Illuminate\Auth\AuthenticationException;
|
||||
use Illuminate\Contracts\Auth\Factory as Auth;
|
||||
use Illuminate\Http\Request;
|
||||
use League\OAuth2\Server\Exception\OAuthServerException;
|
||||
|
||||
/**
|
||||
* Class Authenticate
|
||||
@@ -84,6 +86,7 @@ class Authenticate
|
||||
if ($this->auth->check()) {
|
||||
// do an extra check on user object.
|
||||
/** @noinspection PhpUndefinedMethodInspection */
|
||||
|
||||
/** @var User $user */
|
||||
$user = $this->auth->authenticate();
|
||||
$this->validateBlockedUser($user, $guards);
|
||||
@@ -107,7 +110,14 @@ class Authenticate
|
||||
}
|
||||
}
|
||||
|
||||
throw new AuthenticationException('Unauthenticated.', $guards);
|
||||
// this is a massive hack, but if the handler has the oauth exception
|
||||
// at this point we can report its error instead of a generic one.
|
||||
$message = 'Unauthenticated.';
|
||||
if (Handler::$lastError instanceof OAuthServerException) {
|
||||
$message = Handler::$lastError->getHint();
|
||||
}
|
||||
|
||||
throw new AuthenticationException($message, $guards);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@@ -41,8 +41,8 @@ class SelectTransactionsRequest extends FormRequest
|
||||
public function rules(): array
|
||||
{
|
||||
return [
|
||||
'start' => 'required|date|after:1900-01-01|before:2099-12-31|before:end|required_with:end',
|
||||
'end' => 'required|date|after:1900-01-01|before:2099-12-31|after:start|required_with:start',
|
||||
'start' => 'required|date|after:1970-01-02|before:2038-01-17|before:end|required_with:end',
|
||||
'end' => 'required|date|after:1970-01-02|before:2038-01-17|after:start|required_with:start',
|
||||
'accounts' => 'required',
|
||||
'accounts.*' => 'required|exists:accounts,id|belongsToUser:accounts',
|
||||
];
|
||||
|
@@ -74,7 +74,7 @@ class TagFormRequest extends FormRequest
|
||||
'tag' => $tagRule,
|
||||
'id' => $idRule,
|
||||
'description' => 'max:32768|min:1|nullable',
|
||||
'date' => 'date|nullable|after:1984-09-17',
|
||||
'date' => 'date|nullable|after:1970-01-02|before:2038-01-17',
|
||||
];
|
||||
|
||||
return Location::requestRules($rules);
|
||||
|
@@ -40,7 +40,7 @@ class Tag extends Model
|
||||
use ReturnsIntegerUserIdTrait;
|
||||
use SoftDeletes;
|
||||
|
||||
protected $fillable = ['user_id', 'user_group_id', 'tag', 'date', 'date_tz', 'description', 'tagMode'];
|
||||
protected $fillable = ['user_id', 'user_group_id', 'tag', 'date', 'date_tz', 'description', 'tag_mode'];
|
||||
|
||||
protected $hidden = ['zoomLevel', 'latitude', 'longitude'];
|
||||
|
||||
|
@@ -312,11 +312,23 @@ class BillRepository implements BillRepositoryInterface, UserGroupInterface
|
||||
Log::debug(sprintf('Search for linked journals between %s and %s', $start->toW3cString(), $end->toW3cString()));
|
||||
|
||||
return $bill->transactionJournals()
|
||||
->leftJoin('transactions', 'transactions.transaction_journal_id', '=', 'transaction_journals.id')
|
||||
->leftJoin('transaction_currencies AS currency', 'currency.id', '=', 'transactions.transaction_currency_id')
|
||||
->leftJoin('transaction_currencies AS foreign_currency', 'foreign_currency.id', '=', 'transactions.foreign_currency_id')
|
||||
->where('transactions.amount', '>', 0)
|
||||
->before($end)->after($start)->get(
|
||||
[
|
||||
'transaction_journals.id',
|
||||
'transaction_journals.date',
|
||||
'transaction_journals.transaction_group_id',
|
||||
'transactions.transaction_currency_id',
|
||||
'currency.code AS transaction_currency_code',
|
||||
'currency.decimal_places AS transaction_currency_decimal_places',
|
||||
'transactions.foreign_currency_id',
|
||||
'foreign_currency.code AS foreign_currency_code',
|
||||
'foreign_currency.decimal_places AS foreign_currency_decimal_places',
|
||||
'transactions.amount',
|
||||
'transactions.foreign_amount',
|
||||
]
|
||||
)
|
||||
;
|
||||
|
@@ -24,6 +24,7 @@ declare(strict_types=1);
|
||||
|
||||
namespace FireflyIII\Repositories\Budget;
|
||||
|
||||
use Deprecated;
|
||||
use Carbon\Carbon;
|
||||
use FireflyIII\Models\AvailableBudget;
|
||||
use FireflyIII\Models\TransactionCurrency;
|
||||
@@ -205,9 +206,7 @@ class AvailableBudgetRepository implements AvailableBudgetRepositoryInterface, U
|
||||
;
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated
|
||||
*/
|
||||
#[Deprecated]
|
||||
public function setAvailableBudget(TransactionCurrency $currency, Carbon $start, Carbon $end, string $amount): AvailableBudget
|
||||
{
|
||||
/** @var null|AvailableBudget */
|
||||
|
@@ -24,6 +24,7 @@ declare(strict_types=1);
|
||||
|
||||
namespace FireflyIII\Repositories\Budget;
|
||||
|
||||
use Deprecated;
|
||||
use Carbon\Carbon;
|
||||
use FireflyIII\Enums\UserRoleEnum;
|
||||
use FireflyIII\Models\AvailableBudget;
|
||||
@@ -66,9 +67,7 @@ interface AvailableBudgetRepositoryInterface
|
||||
*/
|
||||
public function get(?Carbon $start = null, ?Carbon $end = null): Collection;
|
||||
|
||||
/**
|
||||
* @deprecated
|
||||
*/
|
||||
#[Deprecated]
|
||||
public function getAvailableBudget(TransactionCurrency $currency, Carbon $start, Carbon $end): string;
|
||||
|
||||
public function getAvailableBudgetWithCurrency(Carbon $start, Carbon $end): array;
|
||||
@@ -90,9 +89,7 @@ interface AvailableBudgetRepositoryInterface
|
||||
*/
|
||||
public function getByCurrencyDate(Carbon $start, Carbon $end, TransactionCurrency $currency): ?AvailableBudget;
|
||||
|
||||
/**
|
||||
* @deprecated
|
||||
*/
|
||||
#[Deprecated]
|
||||
public function setAvailableBudget(TransactionCurrency $currency, Carbon $start, Carbon $end, string $amount): AvailableBudget;
|
||||
|
||||
public function store(array $data): ?AvailableBudget;
|
||||
|
@@ -24,6 +24,7 @@ declare(strict_types=1);
|
||||
|
||||
namespace FireflyIII\Repositories\Budget;
|
||||
|
||||
use Deprecated;
|
||||
use Carbon\Carbon;
|
||||
use FireflyIII\Enums\UserRoleEnum;
|
||||
use FireflyIII\Models\TransactionCurrency;
|
||||
@@ -44,9 +45,7 @@ use Illuminate\Support\Collection;
|
||||
*/
|
||||
interface NoBudgetRepositoryInterface
|
||||
{
|
||||
/**
|
||||
* @deprecated
|
||||
*/
|
||||
#[Deprecated]
|
||||
public function getNoBudgetPeriodReport(Collection $accounts, Carbon $start, Carbon $end): array;
|
||||
|
||||
public function sumExpenses(Carbon $start, Carbon $end, ?Collection $accounts = null, ?TransactionCurrency $currency = null): array;
|
||||
|
@@ -25,12 +25,15 @@ declare(strict_types=1);
|
||||
namespace FireflyIII\Repositories\Budget;
|
||||
|
||||
use Carbon\Carbon;
|
||||
use Deprecated;
|
||||
use FireflyIII\Enums\TransactionTypeEnum;
|
||||
use FireflyIII\Helpers\Collector\GroupCollectorInterface;
|
||||
use FireflyIII\Models\Account;
|
||||
use FireflyIII\Models\Budget;
|
||||
use FireflyIII\Models\TransactionCurrency;
|
||||
use FireflyIII\Repositories\Account\AccountRepositoryInterface;
|
||||
use FireflyIII\Support\Facades\Amount;
|
||||
use FireflyIII\Support\Http\Api\ExchangeRateConverter;
|
||||
use FireflyIII\Support\Report\Summarizer\TransactionSummarizer;
|
||||
use FireflyIII\Support\Repositories\UserGroup\UserGroupInterface;
|
||||
use FireflyIII\Support\Repositories\UserGroup\UserGroupTrait;
|
||||
@@ -54,17 +57,17 @@ class OperationsRepository implements OperationsRepositoryInterface, UserGroupIn
|
||||
$total = '0';
|
||||
$count = 0;
|
||||
foreach ($budget->budgetlimits as $limit) {
|
||||
$diff = (int) $limit->start_date->diffInDays($limit->end_date, true);
|
||||
$diff = (int)$limit->start_date->diffInDays($limit->end_date, true);
|
||||
$diff = 0 === $diff ? 1 : $diff;
|
||||
$amount = $limit->amount;
|
||||
$perDay = bcdiv((string) $amount, (string) $diff);
|
||||
$perDay = bcdiv((string)$amount, (string)$diff);
|
||||
$total = bcadd($total, $perDay);
|
||||
++$count;
|
||||
app('log')->debug(sprintf('Found %d budget limits. Per day is %s, total is %s', $count, $perDay, $total));
|
||||
}
|
||||
$avg = $total;
|
||||
if ($count > 0) {
|
||||
$avg = bcdiv($total, (string) $count);
|
||||
$avg = bcdiv($total, (string)$count);
|
||||
}
|
||||
app('log')->debug(sprintf('%s / %d = %s = average.', $total, $count, $avg));
|
||||
|
||||
@@ -74,9 +77,8 @@ class OperationsRepository implements OperationsRepositoryInterface, UserGroupIn
|
||||
/**
|
||||
* This method is being used to generate the budget overview in the year/multi-year report. Its used
|
||||
* in both the year/multi-year budget overview AND in the accompanying chart.
|
||||
*
|
||||
* @deprecated
|
||||
*/
|
||||
#[Deprecated]
|
||||
public function getBudgetPeriodReport(Collection $budgets, Collection $accounts, Carbon $start, Carbon $end): array
|
||||
{
|
||||
$carbonFormat = app('navigation')->preferredCarbonFormat($start, $end);
|
||||
@@ -93,9 +95,9 @@ class OperationsRepository implements OperationsRepositoryInterface, UserGroupIn
|
||||
/** @var array $journal */
|
||||
foreach ($journals as $journal) {
|
||||
// prep data array for currency:
|
||||
$budgetId = (int) $journal['budget_id'];
|
||||
$budgetId = (int)$journal['budget_id'];
|
||||
$budgetName = $journal['budget_name'];
|
||||
$currencyId = (int) $journal['currency_id'];
|
||||
$currencyId = (int)$journal['currency_id'];
|
||||
$key = sprintf('%d-%d', $budgetId, $currencyId);
|
||||
|
||||
$data[$key] ??= [
|
||||
@@ -110,7 +112,7 @@ class OperationsRepository implements OperationsRepositoryInterface, UserGroupIn
|
||||
'entries' => [],
|
||||
];
|
||||
$date = $journal['date']->format($carbonFormat);
|
||||
$data[$key]['entries'][$date] = bcadd($data[$key]['entries'][$date] ?? '0', (string) $journal['amount']);
|
||||
$data[$key]['entries'][$date] = bcadd($data[$key]['entries'][$date] ?? '0', (string)$journal['amount']);
|
||||
}
|
||||
|
||||
return $data;
|
||||
@@ -124,7 +126,7 @@ class OperationsRepository implements OperationsRepositoryInterface, UserGroupIn
|
||||
public function listExpenses(Carbon $start, Carbon $end, ?Collection $accounts = null, ?Collection $budgets = null): array
|
||||
{
|
||||
/** @var GroupCollectorInterface $collector */
|
||||
$collector = app(GroupCollectorInterface::class);
|
||||
$collector = app(GroupCollectorInterface::class);
|
||||
$collector->setUser($this->user)->setRange($start, $end)->setTypes([TransactionTypeEnum::WITHDRAWAL->value]);
|
||||
if ($accounts instanceof Collection && $accounts->count() > 0) {
|
||||
$collector->setAccounts($accounts);
|
||||
@@ -136,15 +138,41 @@ class OperationsRepository implements OperationsRepositoryInterface, UserGroupIn
|
||||
$collector->setBudgets($this->getBudgets());
|
||||
}
|
||||
$collector->withBudgetInformation()->withAccountInformation()->withCategoryInformation();
|
||||
$journals = $collector->getExtractedJournals();
|
||||
$array = [];
|
||||
$journals = $collector->getExtractedJournals();
|
||||
$array = [];
|
||||
|
||||
// if needs conversion to native.
|
||||
$convertToNative = Amount::convertToNative($this->user);
|
||||
$nativeCurrency = Amount::getNativeCurrencyByUserGroup($this->userGroup);
|
||||
$currencyId = (int) $nativeCurrency->id;
|
||||
$currencyCode = $nativeCurrency->code;
|
||||
$currencyName = $nativeCurrency->name;
|
||||
$currencySymbol = $nativeCurrency->symbol;
|
||||
$currencyDecimalPlaces = $nativeCurrency->decimal_places;
|
||||
$converter = new ExchangeRateConverter();
|
||||
$currencies = [
|
||||
$currencyId => $nativeCurrency,
|
||||
];
|
||||
|
||||
foreach ($journals as $journal) {
|
||||
$currencyId = (int) $journal['currency_id'];
|
||||
$budgetId = (int) $journal['budget_id'];
|
||||
$budgetName = (string) $journal['budget_name'];
|
||||
$amount = app('steam')->negative($journal['amount']);
|
||||
$journalCurrencyId = (int)$journal['currency_id'];
|
||||
if (false === $convertToNative) {
|
||||
$currencyId = $journalCurrencyId;
|
||||
$currencyName = $journal['currency_name'];
|
||||
$currencySymbol = $journal['currency_symbol'];
|
||||
$currencyCode = $journal['currency_code'];
|
||||
$currencyDecimalPlaces = $journal['currency_decimal_places'];
|
||||
}
|
||||
if (true === $convertToNative && $journalCurrencyId !== $currencyId) {
|
||||
$currencies[$journalCurrencyId] ??= TransactionCurrency::find($journalCurrencyId);
|
||||
$amount = $converter->convert($currencies[$journalCurrencyId], $nativeCurrency, $journal['date'], $amount);
|
||||
}
|
||||
|
||||
// catch "no category" entries.
|
||||
$budgetId = (int)$journal['budget_id'];
|
||||
$budgetName = (string)$journal['budget_name'];
|
||||
|
||||
// catch "no budget" entries.
|
||||
if (0 === $budgetId) {
|
||||
continue;
|
||||
}
|
||||
@@ -153,10 +181,10 @@ class OperationsRepository implements OperationsRepositoryInterface, UserGroupIn
|
||||
$array[$currencyId] ??= [
|
||||
'budgets' => [],
|
||||
'currency_id' => $currencyId,
|
||||
'currency_name' => $journal['currency_name'],
|
||||
'currency_symbol' => $journal['currency_symbol'],
|
||||
'currency_code' => $journal['currency_code'],
|
||||
'currency_decimal_places' => $journal['currency_decimal_places'],
|
||||
'currency_name' => $currencyName,
|
||||
'currency_symbol' => $currencySymbol,
|
||||
'currency_code' => $currencyCode,
|
||||
'currency_decimal_places' => $currencyDecimalPlaces,
|
||||
];
|
||||
|
||||
// info about the categories:
|
||||
@@ -168,9 +196,9 @@ class OperationsRepository implements OperationsRepositoryInterface, UserGroupIn
|
||||
|
||||
// add journal to array:
|
||||
// only a subset of the fields.
|
||||
$journalId = (int) $journal['transaction_journal_id'];
|
||||
$journalId = (int)$journal['transaction_journal_id'];
|
||||
$array[$currencyId]['budgets'][$budgetId]['transaction_journals'][$journalId] = [
|
||||
'amount' => app('steam')->negative($journal['amount']),
|
||||
'amount' => $amount,
|
||||
'destination_account_id' => $journal['destination_account_id'],
|
||||
'destination_account_name' => $journal['destination_account_name'],
|
||||
'source_account_id' => $journal['source_account_id'],
|
||||
@@ -204,7 +232,7 @@ class OperationsRepository implements OperationsRepositoryInterface, UserGroupIn
|
||||
?TransactionCurrency $currency = null,
|
||||
bool $convertToNative = false
|
||||
): array {
|
||||
Log::debug(sprintf('Start of %s(date, date, array, array, "%s", "%s").', __METHOD__, $currency?->code, var_export($convertToNative, true)));
|
||||
Log::debug(sprintf('Start of %s(date, date, array, array, "%s", %s).', __METHOD__, $currency?->code, var_export($convertToNative, true)));
|
||||
// this collector excludes all transfers TO liabilities (which are also withdrawals)
|
||||
// because those expenses only become expenses once they move from the liability to the friend.
|
||||
// 2024-12-24 disable the exclusion for now.
|
||||
|
@@ -24,6 +24,7 @@ declare(strict_types=1);
|
||||
|
||||
namespace FireflyIII\Repositories\Budget;
|
||||
|
||||
use Deprecated;
|
||||
use Carbon\Carbon;
|
||||
use FireflyIII\Enums\UserRoleEnum;
|
||||
use FireflyIII\Models\Budget;
|
||||
@@ -51,9 +52,7 @@ interface OperationsRepositoryInterface
|
||||
*/
|
||||
public function budgetedPerDay(Budget $budget): string;
|
||||
|
||||
/**
|
||||
* @deprecated
|
||||
*/
|
||||
#[Deprecated]
|
||||
public function getBudgetPeriodReport(Collection $budgets, Collection $accounts, Carbon $start, Carbon $end): array;
|
||||
|
||||
/**
|
||||
@@ -71,6 +70,7 @@ interface OperationsRepositoryInterface
|
||||
Carbon $end,
|
||||
?Collection $accounts = null,
|
||||
?Collection $budgets = null,
|
||||
?TransactionCurrency $currency = null
|
||||
?TransactionCurrency $currency = null,
|
||||
bool $convertToNative = false
|
||||
): array;
|
||||
}
|
||||
|
@@ -444,7 +444,7 @@ class PiggyBankRepository implements PiggyBankRepositoryInterface, UserGroupInte
|
||||
{
|
||||
$piggyBank->piggyBankEvents()->delete();
|
||||
foreach ($piggyBank->accounts as $account) {
|
||||
if (0 !== bccomp('0', $account->pivot->current_amount)) {
|
||||
if (0 !== bccomp('0', (string) $account->pivot->current_amount)) {
|
||||
event(new ChangedAmount($piggyBank, $account->pivot->current_amount, null, null));
|
||||
}
|
||||
}
|
||||
|
@@ -140,8 +140,9 @@ class TagRepository implements TagRepositoryInterface, UserGroupInterface
|
||||
}
|
||||
|
||||
if (null !== $year) {
|
||||
$year = min(2038, max(1970, $year));
|
||||
app('log')->debug(sprintf('Get tags with year %s.', $year));
|
||||
$tagQuery->where('tags.date', '>=', $year.'-01-01 00:00:00')->where('tags.date', '<=', $year.'-12-31 23:59:59');
|
||||
$tagQuery->where('tags.date', '>=', sprintf('%d-01-01 00:00:00', $year))->where('tags.date', '<=', sprintf('%d-12-31 23:59:59', $year));
|
||||
}
|
||||
$collection = $tagQuery->get();
|
||||
$return = [];
|
||||
|
@@ -440,10 +440,12 @@ class TransactionGroupRepository implements TransactionGroupRepositoryInterface,
|
||||
|
||||
/** @var TransactionJournal $journal */
|
||||
foreach ($group->transactionJournals as $journal) {
|
||||
$names = sprintf('%s%s', $names, $journal->date->format('Y-m-d-H:i:s'));
|
||||
|
||||
/** @var Transaction $transaction */
|
||||
foreach ($journal->transactions as $transaction) {
|
||||
if (-1 === bccomp('0', (string)$transaction->amount)) {
|
||||
$sum = bcadd($sum, $transaction->amount);
|
||||
$sum = bcadd($sum, (string) $transaction->amount);
|
||||
$names = sprintf('%s%s', $names, $transaction->account->name);
|
||||
}
|
||||
}
|
||||
|
@@ -24,6 +24,7 @@ declare(strict_types=1);
|
||||
|
||||
namespace FireflyIII\Services\Internal\Support;
|
||||
|
||||
use Deprecated;
|
||||
use Carbon\Carbon;
|
||||
use FireflyIII\Enums\AccountTypeEnum;
|
||||
use FireflyIII\Exceptions\DuplicateTransactionException;
|
||||
@@ -193,8 +194,8 @@ trait AccountServiceTrait
|
||||
/**
|
||||
* @throws FireflyException
|
||||
* *
|
||||
* @deprecated
|
||||
*/
|
||||
#[Deprecated]
|
||||
protected function createOBGroup(Account $account, array $data): TransactionGroup
|
||||
{
|
||||
app('log')->debug('Now going to create an OB group.');
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user