Compare commits

..

208 Commits

Author SHA1 Message Date
github-actions[bot]
5577be7b08 Merge pull request #10428 from firefly-iii/release-1749383237
🤖 Automatically merge the PR into the develop branch.
2025-06-08 13:47:27 +02:00
JC5
e3bab9d7d8 🤖 Auto commit for release 'develop' on 2025-06-08 2025-06-08 13:47:17 +02:00
James Cole
e0512bee3d Fix #10427 2025-06-08 13:17:01 +02:00
James Cole
20827a5fd1 Fix #10426 2025-06-08 05:55:22 +02:00
James Cole
8819dac1e1 Merge branches 'develop' and 'develop' of github.com:firefly-iii/firefly-iii into develop 2025-06-07 06:31:19 +02:00
James Cole
da0a07262c Fix # 2025-06-07 06:31:14 +02:00
github-actions[bot]
9c195dcc66 Merge pull request #10416 from firefly-iii/release-1749057506
🤖 Automatically merge the PR into the develop branch.
2025-06-04 19:18:33 +02:00
JC5
0b45506e52 🤖 Auto commit for release 'develop' on 2025-06-04 2025-06-04 19:18:26 +02:00
James Cole
51e58f8d88 Fix #10413 2025-06-04 15:40:29 +02:00
James Cole
d0c658e79a Update message to include IP 2025-06-03 20:00:13 +02:00
github-actions[bot]
35e0791a9f Merge pull request #10411 from firefly-iii/release-1748971941
🤖 Automatically merge the PR into the develop branch.
2025-06-03 19:32:29 +02:00
JC5
637ecc66d2 🤖 Auto commit for release 'develop' on 2025-06-03 2025-06-03 19:32:21 +02:00
James Cole
3a38175b2a Fix renamed variable. 2025-06-03 19:26:07 +02:00
James Cole
d78fd86d7a Catch already linked transactions. 2025-06-02 20:46:09 +02:00
James Cole
395332d6dd Fix #10403 2025-06-02 20:32:58 +02:00
James Cole
c5cbceb81a Fix #10399 2025-06-02 05:39:43 +02:00
github-actions[bot]
ec94f1bcf1 Merge pull request #10401 from firefly-iii/release-1748835078
🤖 Automatically merge the PR into the develop branch.
2025-06-02 05:31:25 +02:00
JC5
ee3d18a8ea 🤖 Auto commit for release 'develop' on 2025-06-02 2025-06-02 05:31:18 +02:00
James Cole
a9cd8b6512 Better fit for run recalculations. 2025-06-01 14:00:35 +02:00
James Cole
5bd87036b0 Config works now. Does not feel solved yet, but still. 2025-06-01 13:32:18 +02:00
github-actions[bot]
0e7d72023d Merge pull request #10398 from firefly-iii/release-1748774144
🤖 Automatically merge the PR into the develop branch.
2025-06-01 12:35:50 +02:00
JC5
314f91ff24 🤖 Auto commit for release 'develop' on 2025-06-01 2025-06-01 12:35:44 +02:00
James Cole
ed54a5c9a4 Fix cache issue in recurring cron job report. 2025-06-01 12:24:02 +02:00
github-actions[bot]
5d35edb126 Merge pull request #10397 from firefly-iii/release-1748670980
🤖 Automatically merge the PR into the develop branch.
2025-05-31 07:56:29 +02:00
JC5
8bdfdc39cb 🤖 Auto commit for release 'develop' on 2025-05-31 2025-05-31 07:56:20 +02:00
James Cole
d465b51da8 Only trigger running balance when amount actually changes. 2025-05-31 07:22:42 +02:00
James Cole
3344d2e5f3 Expand and pick up layout. 2025-05-30 08:11:12 +02:00
James Cole
0521da124e Add new fields to API. 2025-05-30 08:10:51 +02:00
James Cole
7e9c5a668f Remove spaces from account numbers. 2025-05-29 22:04:42 +02:00
github-actions[bot]
08e2c1684f Merge pull request #10388 from firefly-iii/release-1748541535
🤖 Automatically merge the PR into the develop branch.
2025-05-29 19:59:02 +02:00
JC5
36ab188ad1 🤖 Auto commit for release 'develop' on 2025-05-29 2025-05-29 19:58:55 +02:00
James Cole
2e69e09808 Catch error 2025-05-29 19:55:13 +02:00
James Cole
adba360466 Update some code with rector. 2025-05-29 15:22:55 +02:00
James Cole
5be6bb755d Update files using Rector. 2025-05-29 15:01:06 +02:00
James Cole
189a323f3c Catch a nullpointer. 2025-05-29 13:38:40 +02:00
github-actions[bot]
b1258d0b43 Merge pull request #10380 from firefly-iii/release-1748363232
🤖 Automatically merge the PR into the develop branch.
2025-05-27 18:27:26 +02:00
JC5
f33ec58e7c 🤖 Auto commit for release 'v6.2.16' on 2025-05-27 2025-05-27 18:27:12 +02:00
github-actions[bot]
58bd818539 Merge pull request #10379 from firefly-iii/release-1748362919
🤖 Automatically merge the PR into the develop branch.
2025-05-27 18:22:05 +02:00
JC5
b875e67fe0 🤖 Auto commit for release 'develop' on 2025-05-27 2025-05-27 18:21:59 +02:00
James Cole
b9528c05a0 Add language 2025-05-27 18:18:08 +02:00
James Cole
bc98100401 Remove comments. 2025-05-27 17:35:22 +02:00
James Cole
26bbb21520 Add Afrikaans to config 2025-05-27 17:28:41 +02:00
github-actions[bot]
86a51b5caa Merge pull request #10378 from firefly-iii/release-1748359419
🤖 Automatically merge the PR into the develop branch.
2025-05-27 17:23:46 +02:00
JC5
c3e039a757 🤖 Auto commit for release 'develop' on 2025-05-27 2025-05-27 17:23:39 +02:00
James Cole
7762f555c5 Merge pull request #10377 from firefly-iii/rector-fixes
Rector fixes
2025-05-27 17:13:21 +02:00
James Cole
e412e23c87 Final fixes. 2025-05-27 17:09:35 +02:00
James Cole
2cb14f6b72 Fix various code. 2025-05-27 17:06:15 +02:00
James Cole
d8f512ca3a Update configuration and fix some files. 2025-05-27 17:02:18 +02:00
James Cole
c074fec0a7 Import statements and update configuration. 2025-05-27 16:57:36 +02:00
James Cole
7c04c4c2bc Fix a bunch of rector issues. 2025-05-27 16:53:48 +02:00
github-actions[bot]
df82252c95 Merge pull request #10371 from firefly-iii/release-1748282618
🤖 Automatically merge the PR into the develop branch.
2025-05-26 20:03:51 +02:00
JC5
c747f4afd8 🤖 Auto commit for release 'develop' on 2025-05-26 2025-05-26 20:03:38 +02:00
James Cole
bcd7db0256 Fix nullpointer in groups.twig. 2025-05-26 19:59:15 +02:00
James Cole
469acce76d Merge pull request #10369 from firefly-iii/fix-10367
Fix 10367
2025-05-26 06:08:14 +02:00
James Cole
568f71ce63 Update changelog. 2025-05-26 06:07:52 +02:00
James Cole
f6fbcf54aa Fix #10367 2025-05-26 06:07:21 +02:00
github-actions[bot]
c194a1ae20 Merge pull request #10368 from firefly-iii/release-1748230057
🤖 Automatically merge the PR into the develop branch.
2025-05-26 05:27:43 +02:00
JC5
7df3728394 🤖 Auto commit for release 'develop' on 2025-05-26 2025-05-26 05:27:37 +02:00
James Cole
acad0b5b55 Actual changelog 2025-05-25 07:13:06 +02:00
github-actions[bot]
605ab38660 Merge pull request #10365 from firefly-iii/release-1748149867
🤖 Automatically merge the PR into the develop branch.
2025-05-25 07:11:18 +02:00
JC5
75b21b20d8 🤖 Auto commit for release 'v6.2.15' on 2025-05-25 2025-05-25 07:11:07 +02:00
github-actions[bot]
e82459cd29 Merge pull request #10364 from firefly-iii/release-1748149540
🤖 Automatically merge the PR into the develop branch.
2025-05-25 07:05:46 +02:00
JC5
6dcf80967e 🤖 Auto commit for release 'develop' on 2025-05-25 2025-05-25 07:05:40 +02:00
James Cole
3d9edaeaac Restore missing facades. Whoops. 2025-05-25 07:01:31 +02:00
github-actions[bot]
4a5a31bf69 Merge pull request #10362 from firefly-iii/release-1748148584
🤖 Automatically merge the PR into the develop branch.
2025-05-25 06:49:50 +02:00
JC5
5f73e37657 🤖 Auto commit for release 'v6.2.14' on 2025-05-25 2025-05-25 06:49:44 +02:00
github-actions[bot]
7a9c0a8172 Merge pull request #10361 from firefly-iii/release-1748147782
🤖 Automatically merge the PR into the develop branch.
2025-05-25 06:36:31 +02:00
JC5
39914e2380 🤖 Auto commit for release 'develop' on 2025-05-25 2025-05-25 06:36:22 +02:00
James Cole
5a3240f69d Update changelog. 2025-05-25 06:27:05 +02:00
James Cole
19e5fd6277 Back to passport 12 for the time being. 2025-05-25 06:24:01 +02:00
James Cole
e9844dc2f5 Fix #10353 2025-05-24 19:48:09 +02:00
James Cole
c9f07c093a Fix tests and migrations 2025-05-24 17:30:08 +02:00
James Cole
6a986d8119 Merge pull request #10352 from firefly-iii/rector-cleanup-2
Rector cleanup 2
2025-05-24 17:20:07 +02:00
James Cole
f780de9e71 Replace magic facades 2025-05-24 17:19:18 +02:00
James Cole
b830bd2732 Replace magic facades 2025-05-24 17:15:46 +02:00
James Cole
e333dedeec Replace magic facades. 2025-05-24 17:07:12 +02:00
James Cole
6e5a08245c Rector code cleanup 2025-05-24 16:39:20 +02:00
James Cole
6a82a813e0 Fix version, I guess. 2025-05-24 07:24:28 +02:00
James Cole
7992ecf7f6 Use other workflow thing. 2025-05-24 07:22:18 +02:00
James Cole
967f7cb015 Move fix around 2025-05-24 06:37:19 +02:00
James Cole
7ca5e03752 Fix access rights in Sonar test 2025-05-24 06:36:06 +02:00
github-actions[bot]
abc6c611fa Merge pull request #10344 from firefly-iii/release-1748061087
🤖 Automatically merge the PR into the develop branch.
2025-05-24 06:31:36 +02:00
JC5
7673b939a1 🤖 Auto commit for release 'v6.2.13' on 2025-05-24 2025-05-24 06:31:28 +02:00
github-actions[bot]
c029bd42a7 Merge pull request #10343 from firefly-iii/release-1748060657
🤖 Automatically merge the PR into the develop branch.
2025-05-24 06:24:24 +02:00
JC5
63d051d9ba 🤖 Auto commit for release 'develop' on 2025-05-24 2025-05-24 06:24:17 +02:00
James Cole
1ec5ee08aa Update changelog and some final fixes. 2025-05-24 06:19:07 +02:00
James Cole
66be8ee80e Merge pull request #10342 from firefly-iii/fix-phpunit
Fix phpunit tests
2025-05-24 06:09:47 +02:00
James Cole
d26d1b4b87 Fix phpunit tests 2025-05-24 06:07:59 +02:00
James Cole
3716b50616 Merge pull request #10341 from firefly-iii/fix-10320
Fix #10320
2025-05-24 05:53:39 +02:00
James Cole
5e398bd07a Merge pull request #10340 from firefly-iii/nestor
Nestor
2025-05-24 05:53:10 +02:00
James Cole
2ee000debb Fix #10320 2025-05-24 05:52:46 +02:00
James Cole
b8e33201bd Not sure why I keep calling this tool nestor, it's called rector 2025-05-24 05:52:31 +02:00
James Cole
1c33be4828 Various nestor-related fixes. 2025-05-24 05:46:39 +02:00
James Cole
c40229e9fa Various nestor-related fixes. 2025-05-24 05:40:20 +02:00
James Cole
b7ec7625c0 Merge pull request #10339 from firefly-iii/fix-10336
Fix #10336
2025-05-24 05:36:04 +02:00
James Cole
64170d4957 Fix #10336 2025-05-24 05:35:31 +02:00
James Cole
d82c3b55e0 Merge pull request #10331 from firefly-iii/fix-10308
Fix #10308
2025-05-22 06:41:46 +02:00
James Cole
01800a3534 Fix #10308 2025-05-22 06:41:17 +02:00
James Cole
01404bf9cd Merge pull request #10330 from firefly-iii/fix-10305
Fix #10305
2025-05-22 06:11:22 +02:00
James Cole
2f9d73c0b3 Fix #10305 2025-05-22 06:10:54 +02:00
James Cole
670c2e4872 Merge pull request #10329 from firefly-iii/fix-10302
Fix #10302
2025-05-22 06:07:02 +02:00
James Cole
1261122a57 Fix #10302 2025-05-22 06:06:30 +02:00
James Cole
2a17ec9280 Merge pull request #10328 from firefly-iii/fix-10290
Fix #10290
2025-05-22 06:03:05 +02:00
James Cole
1424410115 Fix #10290 2025-05-22 06:02:32 +02:00
James Cole
f20eccf279 Update static cron token 2025-05-19 19:45:19 +02:00
github-actions[bot]
c18cbe1d26 Merge pull request #10319 from firefly-iii/release-1747670547
🤖 Automatically merge the PR into the develop branch.
2025-05-19 18:02:33 +02:00
JC5
d5a3ae43e0 🤖 Auto commit for release 'develop' on 2025-05-19 2025-05-19 18:02:27 +02:00
James Cole
767abacd27 Add spaces. 2025-05-19 17:58:37 +02:00
James Cole
2b3172ba8e Update packcages 2025-05-19 17:53:33 +02:00
github-actions[bot]
1ff8a48ca3 Merge pull request #10317 from firefly-iii/release-1747668888
🤖 Automatically merge the PR into the develop branch.
2025-05-19 17:34:55 +02:00
JC5
5b7645b6d5 🤖 Auto commit for release 'develop' on 2025-05-19 2025-05-19 17:34:48 +02:00
James Cole
ae82474b19 Update packages. 2025-05-19 17:30:53 +02:00
github-actions[bot]
d38c59c5b1 Merge pull request #10313 from firefly-iii/release-1747625288
🤖 Automatically merge the PR into the develop branch.
2025-05-19 05:28:15 +02:00
JC5
a4205afb7b 🤖 Auto commit for release 'develop' on 2025-05-19 2025-05-19 05:28:08 +02:00
github-actions[bot]
75e187ee34 Merge pull request #10303 from firefly-iii/release-1747228276
🤖 Automatically merge the PR into the develop branch.
2025-05-14 15:11:26 +02:00
JC5
a37ed82bb4 🤖 Auto commit for release 'develop' on 2025-05-14 2025-05-14 15:11:16 +02:00
Sander Dorigo
a7233de561 Downgrade 2025-05-14 15:06:10 +02:00
github-actions[bot]
e87c5eee6b Merge pull request #10301 from firefly-iii/release-1747184469
🤖 Automatically merge the PR into the develop branch.
2025-05-14 03:01:16 +02:00
JC5
7a75290709 🤖 Auto commit for release 'develop' on 2025-05-14 2025-05-14 03:01:10 +02:00
James Cole
981f6df9ee Merge branch 'main' into develop 2025-05-14 02:57:20 +02:00
James Cole
c4572c66d3 Restore and update packages. 2025-05-14 02:56:53 +02:00
github-actions[bot]
8e7d750a5a Merge pull request #10298 from firefly-iii/release-1747132859
🤖 Automatically merge the PR into the develop branch.
2025-05-13 12:41:07 +02:00
JC5
94961466f9 🤖 Auto commit for release 'develop' on 2025-05-13 2025-05-13 12:40:59 +02:00
Sander Dorigo
0f3fe45b06 Make parameter optional 2025-05-13 12:36:26 +02:00
Sander Dorigo
0650457ea5 Experimental extra fix for #10265 2025-05-12 13:25:01 +02:00
github-actions[bot]
2e1ce03f13 Merge pull request #10296 from firefly-iii/release-1747034656
🤖 Automatically merge the PR into the develop branch.
2025-05-12 09:24:22 +02:00
JC5
9b345db623 🤖 Auto commit for release 'develop' on 2025-05-12 2025-05-12 09:24:16 +02:00
Sander Dorigo
c1afcc5219 add code improvement 2025-05-12 09:20:38 +02:00
Sander Dorigo
fb394b7f45 Fix nullpointer 2025-05-12 09:19:42 +02:00
Sander Dorigo
381598f1bb Fix optional web routes 2025-05-12 08:39:21 +02:00
James Cole
25b7a76da9 Merge pull request #10294 from firefly-iii/dependabot/github_actions/github/command-2.0.1 2025-05-12 06:37:59 +02:00
dependabot[bot]
4b03ebe3cb Bump github/command from 2.0.0 to 2.0.1
Bumps [github/command](https://github.com/github/command) from 2.0.0 to 2.0.1.
- [Release notes](https://github.com/github/command/releases)
- [Commits](https://github.com/github/command/compare/v2.0.0...v2.0.1)

---
updated-dependencies:
- dependency-name: github/command
  dependency-version: 2.0.1
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-05-12 03:26:53 +00:00
github-actions[bot]
664c59136a Merge pull request #10293 from firefly-iii/release-1747020359
🤖 Automatically merge the PR into the develop branch.
2025-05-12 05:26:07 +02:00
JC5
27b61aae73 🤖 Auto commit for release 'develop' on 2025-05-12 2025-05-12 05:26:00 +02:00
github-actions[bot]
d90fcd1889 Merge pull request #10288 from firefly-iii/release-1746966536
🤖 Automatically merge the PR into the develop branch.
2025-05-11 14:29:03 +02:00
JC5
979d5c579b 🤖 Auto commit for release 'develop' on 2025-05-11 2025-05-11 14:28:56 +02:00
James Cole
5124ca1738 Introduce change for CI to catch. 2025-05-11 14:24:59 +02:00
James Cole
ac5d9b656a Merge pull request #10287 from firefly-iii/add-safe
Include safe methods and require the correct package.
2025-05-11 14:19:33 +02:00
James Cole
9a02739251 Include safe methods and require the correct package. 2025-05-11 14:19:07 +02:00
James Cole
4af2aadc48 Merge pull request #10286 from firefly-iii/remove-safe-methods
Remove safe methods.
2025-05-11 14:09:02 +02:00
James Cole
84779b8d02 Remove safe methods. 2025-05-11 14:08:32 +02:00
github-actions[bot]
145e8d23f0 Merge pull request #10285 from firefly-iii/release-1746964861
🤖 Automatically merge the PR into the develop branch.
2025-05-11 14:01:08 +02:00
JC5
d0ba0583a5 🤖 Auto commit for release 'develop' on 2025-05-11 2025-05-11 14:01:01 +02:00
James Cole
17d8b54280 Merge pull request #10284 from firefly-iii/fix-missing-import-2
Temp commit because the build fails otherwise and I haven't fixed tha…
2025-05-11 13:56:41 +02:00
James Cole
2cf0bfe3c4 Temp commit because the build fails otherwise and I haven't fixed that yet. 2025-05-11 13:56:07 +02:00
James Cole
070a8cf148 Remove safe functions 2025-05-11 13:16:09 +02:00
github-actions[bot]
f94c21446a Merge pull request #10283 from firefly-iii/release-1746961946
🤖 Automatically merge the PR into the develop branch.
2025-05-11 13:12:33 +02:00
JC5
1ef1873016 🤖 Auto commit for release 'develop' on 2025-05-11 2025-05-11 13:12:26 +02:00
James Cole
32e4e29e7c Merge pull request #10282 from firefly-iii/fix-missing-import
Fix missing import.
2025-05-11 13:08:28 +02:00
James Cole
65ca0dd9e0 Fix missing import. 2025-05-11 13:07:37 +02:00
github-actions[bot]
3385e12c01 Merge pull request #10281 from firefly-iii/release-1746961196
🤖 Automatically merge the PR into the develop branch.
2025-05-11 13:00:03 +02:00
JC5
3566a4afa3 🤖 Auto commit for release 'develop' on 2025-05-11 2025-05-11 12:59:56 +02:00
James Cole
68ff033342 Merge pull request #10279 from firefly-iii/fix-10265-addendum
Fix 10265 addendum
2025-05-11 08:33:52 +02:00
James Cole
f141b0be5c Merge branch 'develop' into fix-10265-addendum
# Conflicts:
#	app/Factory/TransactionJournalFactory.php
2025-05-11 08:33:35 +02:00
James Cole
d399dd160f Merge pull request #10278 from firefly-iii/fix-10265
Fix #10265
2025-05-11 08:31:10 +02:00
James Cole
4c8ed784cd Final check for transaction types 2025-05-11 08:29:31 +02:00
James Cole
fb3402acd4 Fix storage issue with transactions. 2025-05-11 08:00:38 +02:00
James Cole
8cad430816 Fix validation error in transaction processing. 2025-05-11 07:35:20 +02:00
James Cole
01502b456e Disable fix for the moment. 2025-05-11 07:29:18 +02:00
James Cole
9b6314066b Clean up logs. 2025-05-11 07:23:35 +02:00
James Cole
e61dadcbc6 Implement correction method. 2025-05-11 07:20:17 +02:00
James Cole
f7baf5b2fd Better debug info 2025-05-11 07:11:00 +02:00
James Cole
0545826d57 Do not try to correct transactions between asset / liability with foreign amount info. 2025-05-11 07:09:48 +02:00
James Cole
a29904704c Fix #10265 2025-05-11 07:01:36 +02:00
James Cole
899d374222 Merge pull request #10271 from firefly-iii/various-updates
Fix account list and remove sanctum
2025-05-08 20:22:24 +02:00
James Cole
07ff2305fd Fix account list and remove sanctum 2025-05-08 20:22:01 +02:00
James Cole
ee96dd3ab6 Merge pull request #10270 from firefly-iii/main
Update packages
2025-05-08 20:21:12 +02:00
James Cole
a766d3a133 Merge pull request #10263 from firefly-iii/dependabot/composer/composer-761f56e718 2025-05-06 07:22:08 +02:00
dependabot[bot]
67545b0371 Bump league/commonmark in the composer group across 1 directory
Bumps the composer group with 1 update in the / directory: [league/commonmark](https://github.com/thephpleague/commonmark).


Updates `league/commonmark` from 2.6.2 to 2.7.0
- [Release notes](https://github.com/thephpleague/commonmark/releases)
- [Changelog](https://github.com/thephpleague/commonmark/blob/2.7/CHANGELOG.md)
- [Commits](https://github.com/thephpleague/commonmark/compare/2.6.2...2.7.0)

---
updated-dependencies:
- dependency-name: league/commonmark
  dependency-version: 2.7.0
  dependency-type: direct:production
  dependency-group: composer
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-05-06 01:59:56 +00:00
James Cole
6b86d825ea Merge pull request #10261 from firefly-iii/update-packages
Update packages
2025-05-05 07:48:50 +02:00
James Cole
31dbc57e8b Update packages 2025-05-05 07:48:13 +02:00
github-actions[bot]
00050f629c Merge pull request #10259 from firefly-iii/release-1746415513
🤖 Automatically merge the PR into the develop branch.
2025-05-05 05:25:21 +02:00
JC5
3760aabf13 🤖 Auto commit for release 'develop' on 2025-05-05 2025-05-05 05:25:13 +02:00
James Cole
22e092b513 Merge pull request #10255 from firefly-iii/fix-v2
Fix back and forth between v1 and v2
2025-05-04 21:26:52 +02:00
James Cole
a4f7c90e09 Fix back and forth between v1 and v2 2025-05-04 21:24:50 +02:00
James Cole
4b92ab46a3 Merge pull request #10253 from firefly-iii/cleanup-code
Clean up code.
2025-05-04 17:41:52 +02:00
James Cole
0573bf2402 Clean up code. 2025-05-04 17:41:26 +02:00
github-actions[bot]
e28e538272 Merge pull request #10252 from firefly-iii/release-1746372029
🤖 Automatically merge the PR into the develop branch.
2025-05-04 17:20:36 +02:00
JC5
6f8f175890 🤖 Auto commit for release 'develop' on 2025-05-04 2025-05-04 17:20:29 +02:00
James Cole
fbf9ab6c5f Merge pull request #10251 from firefly-iii/branch-function
Import function.
2025-05-04 17:16:30 +02:00
James Cole
3c67175e68 Import function. 2025-05-04 17:16:07 +02:00
James Cole
b0d25a1d33 Merge pull request #10250 from firefly-iii/fix-nulls
Fix nullpointers.
2025-05-04 17:09:16 +02:00
James Cole
9ea8709835 Fix nullpointers. 2025-05-04 17:08:42 +02:00
James Cole
ae22c59f21 Merge pull request #10249 from firefly-iii/add-rector
Add rector
2025-05-04 17:05:23 +02:00
James Cole
12b8ba68b3 Add script to run rector.sh 2025-05-04 17:01:04 +02:00
James Cole
6b086c9bff Add config for rector. 2025-05-04 16:57:38 +02:00
github-actions[bot]
546a1198a1 Merge pull request #10248 from firefly-iii/release-1746359742
🤖 Automatically merge the PR into the develop branch.
2025-05-04 13:55:49 +02:00
JC5
1001e04b63 🤖 Auto commit for release 'develop' on 2025-05-04 2025-05-04 13:55:42 +02:00
James Cole
2c96729d76 Merge pull request #10247 from firefly-iii/to-php-8.4
To php 8.4
2025-05-04 13:51:43 +02:00
James Cole
194d22ad90 Final set of php8.4 changes. 2025-05-04 13:50:20 +02:00
James Cole
51e86448c7 More PHP8.4 updates 2025-05-04 13:47:00 +02:00
James Cole
e42107c03c Update more code. 2025-05-04 13:04:33 +02:00
James Cole
abd9260193 Update code to use php 8.4 code, using Nestor. 2025-05-04 12:57:14 +02:00
James Cole
042e2ba97d Merge pull request #10243 from firefly-iii/split-strings
Replace string operators.
2025-05-04 12:21:14 +02:00
James Cole
d5240f7afd Replace string operators. 2025-05-04 12:20:54 +02:00
James Cole
cda90df995 Merge pull request #10242 from firefly-iii/safe-methods
Replace methods with safe variants. Let's see how this works out.
2025-05-04 12:18:24 +02:00
James Cole
446e855b74 Replace methods with safe variants. Let's see how this works out. 2025-05-04 12:11:25 +02:00
James Cole
fb31f25d71 Merge pull request #10241 from firefly-iii/type-error
Fix type error.
2025-05-04 06:17:23 +02:00
James Cole
ba43d8c3f5 Fix type error. 2025-05-04 06:15:49 +02:00
James Cole
3924781797 Make sure running balance also updates when transactions are removed. 2025-05-02 06:45:34 +02:00
James Cole
b99a6a9fc9 Merge branch 'main' into develop
# Conflicts:
#	package-lock.json
2025-05-02 05:47:08 +02:00
James Cole
2967f4d4c7 Update PR template 2025-05-02 05:46:35 +02:00
James Cole
285eeb1d12 Merge pull request #10222 from firefly-iii/dependabot/npm_and_yarn/npm_and_yarn-de653eece3 2025-05-01 06:31:58 +02:00
dependabot[bot]
6374215ebc Bump vite in the npm_and_yarn group across 1 directory
Bumps the npm_and_yarn group with 1 update in the / directory: [vite](https://github.com/vitejs/vite/tree/HEAD/packages/vite).


Updates `vite` from 6.3.2 to 6.3.4
- [Release notes](https://github.com/vitejs/vite/releases)
- [Changelog](https://github.com/vitejs/vite/blob/main/packages/vite/CHANGELOG.md)
- [Commits](https://github.com/vitejs/vite/commits/v6.3.4/packages/vite)

---
updated-dependencies:
- dependency-name: vite
  dependency-version: 6.3.4
  dependency-type: direct:development
  dependency-group: npm_and_yarn
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-04-30 17:41:40 +00:00
github-actions[bot]
8f0c0f215c Merge pull request #10215 from firefly-iii/release-1745810633
🤖 Automatically merge the PR into the develop branch.
2025-04-28 05:24:02 +02:00
JC5
5fc764e72b 🤖 Auto commit for release 'develop' on 2025-04-28 2025-04-28 05:23:53 +02:00
github-actions[bot]
b330313c55 Merge pull request #10213 from firefly-iii/release-1745742741
🤖 Automatically merge the PR into the develop branch.
2025-04-27 10:32:28 +02:00
JC5
aa9ce73758 🤖 Auto commit for release 'develop' on 2025-04-27 2025-04-27 10:32:21 +02:00
746 changed files with 8237 additions and 7470 deletions

View File

@@ -53,6 +53,9 @@ return $config->setRules(
'statement_indentation' => true, 'statement_indentation' => true,
'void_return' => true, 'void_return' => true,
// about importing statements
'global_namespace_import' => ['import_classes' => true, 'import_constants' => true, 'import_functions' => true],
// disabled rules // disabled rules
'native_function_invocation' => false, // annoying 'native_function_invocation' => false, // annoying
'php_unit_data_provider_name' => false, // bloody annoying long test names 'php_unit_data_provider_name' => false, // bloody annoying long test names

View File

@@ -1256,23 +1256,24 @@
}, },
{ {
"name": "symfony/console", "name": "symfony/console",
"version": "v7.2.5", "version": "v7.3.0",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/symfony/console.git", "url": "https://github.com/symfony/console.git",
"reference": "e51498ea18570c062e7df29d05a7003585b19b88" "reference": "66c1440edf6f339fd82ed6c7caa76cb006211b44"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/symfony/console/zipball/e51498ea18570c062e7df29d05a7003585b19b88", "url": "https://api.github.com/repos/symfony/console/zipball/66c1440edf6f339fd82ed6c7caa76cb006211b44",
"reference": "e51498ea18570c062e7df29d05a7003585b19b88", "reference": "66c1440edf6f339fd82ed6c7caa76cb006211b44",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
"php": ">=8.2", "php": ">=8.2",
"symfony/deprecation-contracts": "^2.5|^3",
"symfony/polyfill-mbstring": "~1.0", "symfony/polyfill-mbstring": "~1.0",
"symfony/service-contracts": "^2.5|^3", "symfony/service-contracts": "^2.5|^3",
"symfony/string": "^6.4|^7.0" "symfony/string": "^7.2"
}, },
"conflict": { "conflict": {
"symfony/dependency-injection": "<6.4", "symfony/dependency-injection": "<6.4",
@@ -1329,7 +1330,7 @@
"terminal" "terminal"
], ],
"support": { "support": {
"source": "https://github.com/symfony/console/tree/v7.2.5" "source": "https://github.com/symfony/console/tree/v7.3.0"
}, },
"funding": [ "funding": [
{ {
@@ -1345,20 +1346,20 @@
"type": "tidelift" "type": "tidelift"
} }
], ],
"time": "2025-03-12T08:11:12+00:00" "time": "2025-05-24T10:34:04+00:00"
}, },
{ {
"name": "symfony/deprecation-contracts", "name": "symfony/deprecation-contracts",
"version": "v3.5.1", "version": "v3.6.0",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/symfony/deprecation-contracts.git", "url": "https://github.com/symfony/deprecation-contracts.git",
"reference": "74c71c939a79f7d5bf3c1ce9f5ea37ba0114c6f6" "reference": "63afe740e99a13ba87ec199bb07bbdee937a5b62"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/symfony/deprecation-contracts/zipball/74c71c939a79f7d5bf3c1ce9f5ea37ba0114c6f6", "url": "https://api.github.com/repos/symfony/deprecation-contracts/zipball/63afe740e99a13ba87ec199bb07bbdee937a5b62",
"reference": "74c71c939a79f7d5bf3c1ce9f5ea37ba0114c6f6", "reference": "63afe740e99a13ba87ec199bb07bbdee937a5b62",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@@ -1371,7 +1372,7 @@
"name": "symfony/contracts" "name": "symfony/contracts"
}, },
"branch-alias": { "branch-alias": {
"dev-main": "3.5-dev" "dev-main": "3.6-dev"
} }
}, },
"autoload": { "autoload": {
@@ -1396,7 +1397,7 @@
"description": "A generic function and convention to trigger deprecation notices", "description": "A generic function and convention to trigger deprecation notices",
"homepage": "https://symfony.com", "homepage": "https://symfony.com",
"support": { "support": {
"source": "https://github.com/symfony/deprecation-contracts/tree/v3.5.1" "source": "https://github.com/symfony/deprecation-contracts/tree/v3.6.0"
}, },
"funding": [ "funding": [
{ {
@@ -1412,20 +1413,20 @@
"type": "tidelift" "type": "tidelift"
} }
], ],
"time": "2024-09-25T14:20:29+00:00" "time": "2024-09-25T14:21:43+00:00"
}, },
{ {
"name": "symfony/event-dispatcher", "name": "symfony/event-dispatcher",
"version": "v7.2.0", "version": "v7.3.0",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/symfony/event-dispatcher.git", "url": "https://github.com/symfony/event-dispatcher.git",
"reference": "910c5db85a5356d0fea57680defec4e99eb9c8c1" "reference": "497f73ac996a598c92409b44ac43b6690c4f666d"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/910c5db85a5356d0fea57680defec4e99eb9c8c1", "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/497f73ac996a598c92409b44ac43b6690c4f666d",
"reference": "910c5db85a5356d0fea57680defec4e99eb9c8c1", "reference": "497f73ac996a598c92409b44ac43b6690c4f666d",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@@ -1476,7 +1477,7 @@
"description": "Provides tools that allow your application components to communicate with each other by dispatching events and listening to them", "description": "Provides tools that allow your application components to communicate with each other by dispatching events and listening to them",
"homepage": "https://symfony.com", "homepage": "https://symfony.com",
"support": { "support": {
"source": "https://github.com/symfony/event-dispatcher/tree/v7.2.0" "source": "https://github.com/symfony/event-dispatcher/tree/v7.3.0"
}, },
"funding": [ "funding": [
{ {
@@ -1492,20 +1493,20 @@
"type": "tidelift" "type": "tidelift"
} }
], ],
"time": "2024-09-25T14:21:43+00:00" "time": "2025-04-22T09:11:45+00:00"
}, },
{ {
"name": "symfony/event-dispatcher-contracts", "name": "symfony/event-dispatcher-contracts",
"version": "v3.5.1", "version": "v3.6.0",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/symfony/event-dispatcher-contracts.git", "url": "https://github.com/symfony/event-dispatcher-contracts.git",
"reference": "7642f5e970b672283b7823222ae8ef8bbc160b9f" "reference": "59eb412e93815df44f05f342958efa9f46b1e586"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/symfony/event-dispatcher-contracts/zipball/7642f5e970b672283b7823222ae8ef8bbc160b9f", "url": "https://api.github.com/repos/symfony/event-dispatcher-contracts/zipball/59eb412e93815df44f05f342958efa9f46b1e586",
"reference": "7642f5e970b672283b7823222ae8ef8bbc160b9f", "reference": "59eb412e93815df44f05f342958efa9f46b1e586",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@@ -1519,7 +1520,7 @@
"name": "symfony/contracts" "name": "symfony/contracts"
}, },
"branch-alias": { "branch-alias": {
"dev-main": "3.5-dev" "dev-main": "3.6-dev"
} }
}, },
"autoload": { "autoload": {
@@ -1552,7 +1553,7 @@
"standards" "standards"
], ],
"support": { "support": {
"source": "https://github.com/symfony/event-dispatcher-contracts/tree/v3.5.1" "source": "https://github.com/symfony/event-dispatcher-contracts/tree/v3.6.0"
}, },
"funding": [ "funding": [
{ {
@@ -1568,11 +1569,11 @@
"type": "tidelift" "type": "tidelift"
} }
], ],
"time": "2024-09-25T14:20:29+00:00" "time": "2024-09-25T14:21:43+00:00"
}, },
{ {
"name": "symfony/filesystem", "name": "symfony/filesystem",
"version": "v7.2.0", "version": "v7.3.0",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/symfony/filesystem.git", "url": "https://github.com/symfony/filesystem.git",
@@ -1618,7 +1619,7 @@
"description": "Provides basic utilities for the filesystem", "description": "Provides basic utilities for the filesystem",
"homepage": "https://symfony.com", "homepage": "https://symfony.com",
"support": { "support": {
"source": "https://github.com/symfony/filesystem/tree/v7.2.0" "source": "https://github.com/symfony/filesystem/tree/v7.3.0"
}, },
"funding": [ "funding": [
{ {
@@ -1638,16 +1639,16 @@
}, },
{ {
"name": "symfony/finder", "name": "symfony/finder",
"version": "v7.2.2", "version": "v7.3.0",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/symfony/finder.git", "url": "https://github.com/symfony/finder.git",
"reference": "87a71856f2f56e4100373e92529eed3171695cfb" "reference": "ec2344cf77a48253bbca6939aa3d2477773ea63d"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/symfony/finder/zipball/87a71856f2f56e4100373e92529eed3171695cfb", "url": "https://api.github.com/repos/symfony/finder/zipball/ec2344cf77a48253bbca6939aa3d2477773ea63d",
"reference": "87a71856f2f56e4100373e92529eed3171695cfb", "reference": "ec2344cf77a48253bbca6939aa3d2477773ea63d",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@@ -1682,7 +1683,7 @@
"description": "Finds files and directories via an intuitive fluent interface", "description": "Finds files and directories via an intuitive fluent interface",
"homepage": "https://symfony.com", "homepage": "https://symfony.com",
"support": { "support": {
"source": "https://github.com/symfony/finder/tree/v7.2.2" "source": "https://github.com/symfony/finder/tree/v7.3.0"
}, },
"funding": [ "funding": [
{ {
@@ -1698,20 +1699,20 @@
"type": "tidelift" "type": "tidelift"
} }
], ],
"time": "2024-12-30T19:00:17+00:00" "time": "2024-12-30T19:00:26+00:00"
}, },
{ {
"name": "symfony/options-resolver", "name": "symfony/options-resolver",
"version": "v7.2.0", "version": "v7.3.0",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/symfony/options-resolver.git", "url": "https://github.com/symfony/options-resolver.git",
"reference": "7da8fbac9dcfef75ffc212235d76b2754ce0cf50" "reference": "afb9a8038025e5dbc657378bfab9198d75f10fca"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/symfony/options-resolver/zipball/7da8fbac9dcfef75ffc212235d76b2754ce0cf50", "url": "https://api.github.com/repos/symfony/options-resolver/zipball/afb9a8038025e5dbc657378bfab9198d75f10fca",
"reference": "7da8fbac9dcfef75ffc212235d76b2754ce0cf50", "reference": "afb9a8038025e5dbc657378bfab9198d75f10fca",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@@ -1749,7 +1750,7 @@
"options" "options"
], ],
"support": { "support": {
"source": "https://github.com/symfony/options-resolver/tree/v7.2.0" "source": "https://github.com/symfony/options-resolver/tree/v7.3.0"
}, },
"funding": [ "funding": [
{ {
@@ -1765,11 +1766,11 @@
"type": "tidelift" "type": "tidelift"
} }
], ],
"time": "2024-11-20T11:17:29+00:00" "time": "2025-04-04T13:12:05+00:00"
}, },
{ {
"name": "symfony/polyfill-ctype", "name": "symfony/polyfill-ctype",
"version": "v1.31.0", "version": "v1.32.0",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/symfony/polyfill-ctype.git", "url": "https://github.com/symfony/polyfill-ctype.git",
@@ -1828,7 +1829,7 @@
"portable" "portable"
], ],
"support": { "support": {
"source": "https://github.com/symfony/polyfill-ctype/tree/v1.31.0" "source": "https://github.com/symfony/polyfill-ctype/tree/v1.32.0"
}, },
"funding": [ "funding": [
{ {
@@ -1848,7 +1849,7 @@
}, },
{ {
"name": "symfony/polyfill-intl-grapheme", "name": "symfony/polyfill-intl-grapheme",
"version": "v1.31.0", "version": "v1.32.0",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/symfony/polyfill-intl-grapheme.git", "url": "https://github.com/symfony/polyfill-intl-grapheme.git",
@@ -1906,7 +1907,7 @@
"shim" "shim"
], ],
"support": { "support": {
"source": "https://github.com/symfony/polyfill-intl-grapheme/tree/v1.31.0" "source": "https://github.com/symfony/polyfill-intl-grapheme/tree/v1.32.0"
}, },
"funding": [ "funding": [
{ {
@@ -1926,7 +1927,7 @@
}, },
{ {
"name": "symfony/polyfill-intl-normalizer", "name": "symfony/polyfill-intl-normalizer",
"version": "v1.31.0", "version": "v1.32.0",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/symfony/polyfill-intl-normalizer.git", "url": "https://github.com/symfony/polyfill-intl-normalizer.git",
@@ -1987,7 +1988,7 @@
"shim" "shim"
], ],
"support": { "support": {
"source": "https://github.com/symfony/polyfill-intl-normalizer/tree/v1.31.0" "source": "https://github.com/symfony/polyfill-intl-normalizer/tree/v1.32.0"
}, },
"funding": [ "funding": [
{ {
@@ -2007,19 +2008,20 @@
}, },
{ {
"name": "symfony/polyfill-mbstring", "name": "symfony/polyfill-mbstring",
"version": "v1.31.0", "version": "v1.32.0",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/symfony/polyfill-mbstring.git", "url": "https://github.com/symfony/polyfill-mbstring.git",
"reference": "85181ba99b2345b0ef10ce42ecac37612d9fd341" "reference": "6d857f4d76bd4b343eac26d6b539585d2bc56493"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/85181ba99b2345b0ef10ce42ecac37612d9fd341", "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/6d857f4d76bd4b343eac26d6b539585d2bc56493",
"reference": "85181ba99b2345b0ef10ce42ecac37612d9fd341", "reference": "6d857f4d76bd4b343eac26d6b539585d2bc56493",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
"ext-iconv": "*",
"php": ">=7.2" "php": ">=7.2"
}, },
"provide": { "provide": {
@@ -2067,7 +2069,7 @@
"shim" "shim"
], ],
"support": { "support": {
"source": "https://github.com/symfony/polyfill-mbstring/tree/v1.31.0" "source": "https://github.com/symfony/polyfill-mbstring/tree/v1.32.0"
}, },
"funding": [ "funding": [
{ {
@@ -2083,20 +2085,20 @@
"type": "tidelift" "type": "tidelift"
} }
], ],
"time": "2024-09-09T11:45:10+00:00" "time": "2024-12-23T08:48:59+00:00"
}, },
{ {
"name": "symfony/polyfill-php80", "name": "symfony/polyfill-php80",
"version": "v1.31.0", "version": "v1.32.0",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/symfony/polyfill-php80.git", "url": "https://github.com/symfony/polyfill-php80.git",
"reference": "60328e362d4c2c802a54fcbf04f9d3fb892b4cf8" "reference": "0cc9dd0f17f61d8131e7df6b84bd344899fe2608"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/symfony/polyfill-php80/zipball/60328e362d4c2c802a54fcbf04f9d3fb892b4cf8", "url": "https://api.github.com/repos/symfony/polyfill-php80/zipball/0cc9dd0f17f61d8131e7df6b84bd344899fe2608",
"reference": "60328e362d4c2c802a54fcbf04f9d3fb892b4cf8", "reference": "0cc9dd0f17f61d8131e7df6b84bd344899fe2608",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@@ -2147,7 +2149,7 @@
"shim" "shim"
], ],
"support": { "support": {
"source": "https://github.com/symfony/polyfill-php80/tree/v1.31.0" "source": "https://github.com/symfony/polyfill-php80/tree/v1.32.0"
}, },
"funding": [ "funding": [
{ {
@@ -2163,11 +2165,11 @@
"type": "tidelift" "type": "tidelift"
} }
], ],
"time": "2024-09-09T11:45:10+00:00" "time": "2025-01-02T08:10:11+00:00"
}, },
{ {
"name": "symfony/polyfill-php81", "name": "symfony/polyfill-php81",
"version": "v1.31.0", "version": "v1.32.0",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/symfony/polyfill-php81.git", "url": "https://github.com/symfony/polyfill-php81.git",
@@ -2223,7 +2225,7 @@
"shim" "shim"
], ],
"support": { "support": {
"source": "https://github.com/symfony/polyfill-php81/tree/v1.31.0" "source": "https://github.com/symfony/polyfill-php81/tree/v1.32.0"
}, },
"funding": [ "funding": [
{ {
@@ -2243,16 +2245,16 @@
}, },
{ {
"name": "symfony/process", "name": "symfony/process",
"version": "v7.2.5", "version": "v7.3.0",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/symfony/process.git", "url": "https://github.com/symfony/process.git",
"reference": "87b7c93e57df9d8e39a093d32587702380ff045d" "reference": "40c295f2deb408d5e9d2d32b8ba1dd61e36f05af"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/symfony/process/zipball/87b7c93e57df9d8e39a093d32587702380ff045d", "url": "https://api.github.com/repos/symfony/process/zipball/40c295f2deb408d5e9d2d32b8ba1dd61e36f05af",
"reference": "87b7c93e57df9d8e39a093d32587702380ff045d", "reference": "40c295f2deb408d5e9d2d32b8ba1dd61e36f05af",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@@ -2284,7 +2286,7 @@
"description": "Executes commands in sub-processes", "description": "Executes commands in sub-processes",
"homepage": "https://symfony.com", "homepage": "https://symfony.com",
"support": { "support": {
"source": "https://github.com/symfony/process/tree/v7.2.5" "source": "https://github.com/symfony/process/tree/v7.3.0"
}, },
"funding": [ "funding": [
{ {
@@ -2300,20 +2302,20 @@
"type": "tidelift" "type": "tidelift"
} }
], ],
"time": "2025-03-13T12:21:46+00:00" "time": "2025-04-17T09:11:12+00:00"
}, },
{ {
"name": "symfony/service-contracts", "name": "symfony/service-contracts",
"version": "v3.5.1", "version": "v3.6.0",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/symfony/service-contracts.git", "url": "https://github.com/symfony/service-contracts.git",
"reference": "e53260aabf78fb3d63f8d79d69ece59f80d5eda0" "reference": "f021b05a130d35510bd6b25fe9053c2a8a15d5d4"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/symfony/service-contracts/zipball/e53260aabf78fb3d63f8d79d69ece59f80d5eda0", "url": "https://api.github.com/repos/symfony/service-contracts/zipball/f021b05a130d35510bd6b25fe9053c2a8a15d5d4",
"reference": "e53260aabf78fb3d63f8d79d69ece59f80d5eda0", "reference": "f021b05a130d35510bd6b25fe9053c2a8a15d5d4",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@@ -2331,7 +2333,7 @@
"name": "symfony/contracts" "name": "symfony/contracts"
}, },
"branch-alias": { "branch-alias": {
"dev-main": "3.5-dev" "dev-main": "3.6-dev"
} }
}, },
"autoload": { "autoload": {
@@ -2367,7 +2369,7 @@
"standards" "standards"
], ],
"support": { "support": {
"source": "https://github.com/symfony/service-contracts/tree/v3.5.1" "source": "https://github.com/symfony/service-contracts/tree/v3.6.0"
}, },
"funding": [ "funding": [
{ {
@@ -2383,11 +2385,11 @@
"type": "tidelift" "type": "tidelift"
} }
], ],
"time": "2024-09-25T14:20:29+00:00" "time": "2025-04-25T09:37:31+00:00"
}, },
{ {
"name": "symfony/stopwatch", "name": "symfony/stopwatch",
"version": "v7.2.4", "version": "v7.3.0",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/symfony/stopwatch.git", "url": "https://github.com/symfony/stopwatch.git",
@@ -2429,7 +2431,7 @@
"description": "Provides a way to profile code", "description": "Provides a way to profile code",
"homepage": "https://symfony.com", "homepage": "https://symfony.com",
"support": { "support": {
"source": "https://github.com/symfony/stopwatch/tree/v7.2.4" "source": "https://github.com/symfony/stopwatch/tree/v7.3.0"
}, },
"funding": [ "funding": [
{ {
@@ -2449,16 +2451,16 @@
}, },
{ {
"name": "symfony/string", "name": "symfony/string",
"version": "v7.2.0", "version": "v7.3.0",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/symfony/string.git", "url": "https://github.com/symfony/string.git",
"reference": "446e0d146f991dde3e73f45f2c97a9faad773c82" "reference": "f3570b8c61ca887a9e2938e85cb6458515d2b125"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/symfony/string/zipball/446e0d146f991dde3e73f45f2c97a9faad773c82", "url": "https://api.github.com/repos/symfony/string/zipball/f3570b8c61ca887a9e2938e85cb6458515d2b125",
"reference": "446e0d146f991dde3e73f45f2c97a9faad773c82", "reference": "f3570b8c61ca887a9e2938e85cb6458515d2b125",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@@ -2516,7 +2518,7 @@
"utf8" "utf8"
], ],
"support": { "support": {
"source": "https://github.com/symfony/string/tree/v7.2.0" "source": "https://github.com/symfony/string/tree/v7.3.0"
}, },
"funding": [ "funding": [
{ {
@@ -2532,7 +2534,7 @@
"type": "tidelift" "type": "tidelift"
} }
], ],
"time": "2024-11-13T13:31:26+00:00" "time": "2025-04-20T20:19:01+00:00"
} }
], ],
"packages-dev": [], "packages-dev": [],

80
.ci/rector.php Normal file
View File

@@ -0,0 +1,80 @@
<?php
/*
* rector.php
* Copyright (c) 2025 james@firefly-iii.org.
*
* This file is part of Firefly III (https://github.com/firefly-iii).
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see https://www.gnu.org/licenses/.
*/
declare(strict_types=1);
use Rector\Config\RectorConfig;
use Rector\EarlyReturn\Rector\If_\ChangeOrIfContinueToMultiContinueRector;
use Rector\Transform\Rector\String_\StringToClassConstantRector;
use RectorLaravel\Set\LaravelLevelSetList;
return RectorConfig::configure()
->withSkip([
ChangeOrIfContinueToMultiContinueRector::class,
StringToClassConstantRector::class => [
__DIR__ . '/../app/Http/Controllers/Auth/LoginController.php',
],
__DIR__.'/../bootstrap/cache/*'
])
->withPaths([
__DIR__ . '/../app',
__DIR__ . '/../bootstrap',
__DIR__ . '/../config',
__DIR__ . '/../public',
__DIR__ . '/../resources/lang/en_US',
__DIR__ . '/../routes',
__DIR__ . '/../tests',
])
->withSets([
LaravelLevelSetList::UP_TO_LARAVEL_120,
])
// ->withConfiguredRule(ReplaceServiceContainerCallArgRector::class, [
// new ReplaceServiceContainerCallArg('log', new ClassConstFetch(new Name('Illuminate\Support\Facades\Log'), 'class')),
// ])
// uncomment to reach your current PHP version
->withPhpSets()
->withPreparedSets(
codingStyle: false, // leave false
privatization: false, // leave false.
naming: false, // leave false
instanceOf: true,
earlyReturn: true,
strictBooleans: true,
carbon: true,
rectorPreset: true,
phpunitCodeQuality: true,
doctrineCodeQuality: true,
symfonyCodeQuality: true,
symfonyConfigs: true
)
->withComposerBased(
twig: true,
doctrine: true,
phpunit: true,
symfony: true)
->withTypeCoverageLevel(0)
->withDeadCodeLevel(0)
->withCodeQualityLevel(0)
->withImportNames(removeUnusedImports: true);// import statements instead of full classes.

36
.ci/rector.sh Executable file
View File

@@ -0,0 +1,36 @@
#!/usr/bin/env bash
#
# phpstan.sh
# Copyright (c) 2021 james@firefly-iii.org
#
# This file is part of Firefly III (https://github.com/firefly-iii).
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the
# License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>.
#
# Install composer packages
#composer install --no-scripts --no-ansi
SCRIPT_DIR="$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )"
echo $1
if [ "$1" == "--dry-run" ]; then
echo "Running rector in dry run."
$SCRIPT_DIR/../vendor/bin/rector --config $SCRIPT_DIR/rector.php --dry-run
exit $?
fi
$SCRIPT_DIR/../vendor/bin/rector --config $SCRIPT_DIR/rector.php

View File

@@ -289,20 +289,13 @@ ALLOW_WEBHOOKS=false
# #
# You can set this variable from a file by appending it with _FILE # You can set this variable from a file by appending it with _FILE
# #
STATIC_CRON_TOKEN= STATIC_CRON_TOKEN=PLEASE_REPLACE_WITH_32_CHAR_CODE
# You can fine tune the start-up of a Docker container by editing these environment variables. # You can fine tune the start-up of a Docker container by editing these environment variables.
# Use this at your own risk. Disabling certain checks and features may result in lots of inconsistent data. # Use this at your own risk. Disabling certain checks and features may result in lots of inconsistent data.
# However if you know what you're doing you can significantly speed up container start times. # However if you know what you're doing you can significantly speed up container start times.
# Set each value to true to enable, or false to disable. # Set each value to true to enable, or false to disable.
# Set this to true to build all locales supported by Firefly III.
# This may take quite some time (several minutes) and is generally not recommended.
# If you wish to change or alter the list of locales, start your Docker container with
# `docker run -v locale.gen:/etc/locale.gen -e DKR_BUILD_LOCALE=true`
# and make sure your preferred locales are in your own locale.gen.
DKR_BUILD_LOCALE=false
# Check if the SQLite database exists. Can be skipped if you're not using SQLite. # Check if the SQLite database exists. Can be skipped if you're not using SQLite.
# Won't significantly speed up things. # Won't significantly speed up things.
DKR_CHECK_SQLITE=true DKR_CHECK_SQLITE=true

View File

@@ -21,5 +21,3 @@ Changes in this pull request:
- -
- -
- -
@JC5

View File

@@ -13,7 +13,7 @@ jobs:
close_duplicates: close_duplicates:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: github/command@v2.0.0 - uses: github/command@v2.0.1
id: command id: command
with: with:
allowed_contexts: "issue" allowed_contexts: "issue"

View File

@@ -5,7 +5,6 @@ on:
push: push:
branches: branches:
- main - main
- develop
env: env:
DB_CONNECTION: sqlite DB_CONNECTION: sqlite
APP_KEY: TestTestTestTestTestTestTestTest APP_KEY: TestTestTestTestTestTestTestTest
@@ -51,7 +50,10 @@ jobs:
wget -q https://github.com/firefly-iii/test-fixtures/raw/refs/heads/main/test-database.sqlite -O 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" - name: "Upgrades the database to the latest version"
run: php artisan firefly-iii:upgrade-database run: |
php artisan firefly-iii:upgrade-database
chmod 600 storage/oauth-public.key
chmod 600 storage/oauth-private.key
- name: "Integrity Database Report" - name: "Integrity Database Report"
run: php artisan firefly-iii:report-integrity run: php artisan firefly-iii:report-integrity
@@ -63,7 +65,7 @@ jobs:
run: sed -i 's@'$GITHUB_WORKSPACE'@/github/workspace/@g' coverage.xml run: sed -i 's@'$GITHUB_WORKSPACE'@/github/workspace/@g' coverage.xml
- name: SonarCloud Scan - name: SonarCloud Scan
uses: SonarSource/sonarcloud-github-action@master uses: SonarSource/sonarqube-scan-action@v5.2.0
env: env:
GITHUB_TOKEN: ${{ secrets.GH_ACTIONS_PERSONAL_ACCESS_TOKEN }} GITHUB_TOKEN: ${{ secrets.GH_ACTIONS_PERSONAL_ACCESS_TOKEN }}
SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }} SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}

View File

@@ -43,6 +43,7 @@ use Illuminate\Support\Facades\Log;
class AccountController extends Controller class AccountController extends Controller
{ {
use AccountFilter; use AccountFilter;
// this array only exists to test if the constructor will use it properly. // this array only exists to test if the constructor will use it properly.
protected array $accepts = ['application/json', 'application/vnd.api+json']; protected array $accepts = ['application/json', 'application/vnd.api+json'];

View File

@@ -65,13 +65,11 @@ class BillController extends Controller
$data = $request->getData(); $data = $request->getData();
$result = $this->repository->searchBill($data['query'], $this->parameters->get('limit')); $result = $this->repository->searchBill($data['query'], $this->parameters->get('limit'));
$filtered = $result->map( $filtered = $result->map(
static function (Bill $item) { static fn (Bill $item) => [
return [
'id' => (string) $item->id, 'id' => (string) $item->id,
'name' => $item->name, 'name' => $item->name,
'active' => $item->active, 'active' => $item->active,
]; ]
}
); );
return response()->api($filtered->toArray()); return response()->api($filtered->toArray());

View File

@@ -65,12 +65,10 @@ class BudgetController extends Controller
$data = $request->getData(); $data = $request->getData();
$result = $this->repository->searchBudget($data['query'], $this->parameters->get('limit')); $result = $this->repository->searchBudget($data['query'], $this->parameters->get('limit'));
$filtered = $result->map( $filtered = $result->map(
static function (Budget $item) { static fn (Budget $item) => [
return [
'id' => (string) $item->id, 'id' => (string) $item->id,
'name' => $item->name, 'name' => $item->name,
]; ]
}
); );
return response()->api($filtered->toArray()); return response()->api($filtered->toArray());

View File

@@ -65,12 +65,10 @@ class CategoryController extends Controller
$data = $request->getData(); $data = $request->getData();
$result = $this->repository->searchCategory($data['query'], $this->parameters->get('limit')); $result = $this->repository->searchCategory($data['query'], $this->parameters->get('limit'));
$filtered = $result->map( $filtered = $result->map(
static function (Category $item) { static fn (Category $item) => [
return [
'id' => (string) $item->id, 'id' => (string) $item->id,
'name' => $item->name, 'name' => $item->name,
]; ]
}
); );
return response()->api($filtered->toArray()); return response()->api($filtered->toArray());

View File

@@ -24,6 +24,7 @@ declare(strict_types=1);
namespace FireflyIII\Api\V1\Controllers\Autocomplete; namespace FireflyIII\Api\V1\Controllers\Autocomplete;
use FireflyIII\Models\TransactionGroup;
use FireflyIII\Api\V1\Controllers\Controller; use FireflyIII\Api\V1\Controllers\Controller;
use FireflyIII\Api\V1\Requests\Autocomplete\AutocompleteRequest; use FireflyIII\Api\V1\Requests\Autocomplete\AutocompleteRequest;
use FireflyIII\Enums\UserRoleEnum; use FireflyIII\Enums\UserRoleEnum;
@@ -39,11 +40,10 @@ use Illuminate\Support\Collection;
*/ */
class TransactionController extends Controller class TransactionController extends Controller
{ {
protected array $acceptedRoles = [UserRoleEnum::READ_ONLY];
private TransactionGroupRepositoryInterface $groupRepository; private TransactionGroupRepositoryInterface $groupRepository;
private JournalRepositoryInterface $repository; private JournalRepositoryInterface $repository;
protected array $acceptedRoles = [UserRoleEnum::READ_ONLY];
/** /**
* TransactionController constructor. * TransactionController constructor.
*/ */
@@ -103,7 +103,7 @@ class TransactionController extends Controller
if (is_numeric($data['query'])) { if (is_numeric($data['query'])) {
// search for group, not journal. // search for group, not journal.
$firstResult = $this->groupRepository->find((int) $data['query']); $firstResult = $this->groupRepository->find((int) $data['query']);
if (null !== $firstResult) { if ($firstResult instanceof TransactionGroup) {
// group may contain multiple journals, each a result: // group may contain multiple journals, each a result:
foreach ($firstResult->transactionJournals as $journal) { foreach ($firstResult->transactionJournals as $journal) {
$result->push($journal); $result->push($journal);

View File

@@ -24,10 +24,11 @@ declare(strict_types=1);
namespace FireflyIII\Api\V1\Controllers\Chart; namespace FireflyIII\Api\V1\Controllers\Chart;
use FireflyIII\Models\TransactionCurrency;
use Carbon\Carbon; use Carbon\Carbon;
use FireflyIII\Api\V1\Controllers\Controller; use FireflyIII\Api\V1\Controllers\Controller;
use FireflyIII\Api\V1\Requests\Data\DateRequest;
use FireflyIII\Api\V1\Requests\Chart\ChartRequest; use FireflyIII\Api\V1\Requests\Chart\ChartRequest;
use FireflyIII\Api\V1\Requests\Data\DateRequest;
use FireflyIII\Enums\AccountTypeEnum; use FireflyIII\Enums\AccountTypeEnum;
use FireflyIII\Exceptions\FireflyException; use FireflyIII\Exceptions\FireflyException;
use FireflyIII\Models\Account; use FireflyIII\Models\Account;
@@ -48,8 +49,8 @@ class AccountController extends Controller
use ApiSupport; use ApiSupport;
use CollectsAccountsFromFilter; use CollectsAccountsFromFilter;
private AccountRepositoryInterface $repository;
private ChartData $chartData; private ChartData $chartData;
private AccountRepositoryInterface $repository;
/** /**
* AccountController constructor. * AccountController constructor.
@@ -93,6 +94,47 @@ class AccountController extends Controller
return response()->json($this->chartData->render()); return response()->json($this->chartData->render());
} }
/**
* @throws FireflyException
*/
private function renderAccountData(array $params, Account $account): void
{
$currency = $this->repository->getAccountCurrency($account);
if (!$currency instanceof TransactionCurrency) {
$currency = $this->default;
}
$currentSet = [
'label' => $account->name,
// the currency that belongs to the account.
'currency_id' => (string) $currency->id,
'currency_code' => $currency->code,
'currency_symbol' => $currency->symbol,
'currency_decimal_places' => $currency->decimal_places,
// the default currency of the user (could be the same!)
'date' => $params['start']->toAtomString(),
'start' => $params['start']->toAtomString(),
'end' => $params['end']->toAtomString(),
'period' => '1D',
'entries' => [],
];
$currentStart = clone $params['start'];
$range = Steam::finalAccountBalanceInRange($account, $params['start'], clone $params['end'], $this->convertToNative);
$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;
$currentStart->addDay();
$currentSet['entries'][$label] = $balance;
}
$this->chartData->add($currentSet);
}
/** /**
* This endpoint is documented at: * This endpoint is documented at:
* https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/charts/getChartAccountOverview * https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/charts/getChartAccountOverview
@@ -162,45 +204,4 @@ class AccountController extends Controller
return response()->json($chartData); return response()->json($chartData);
} }
/**
* @throws FireflyException
*/
private function renderAccountData(array $params, Account $account): void
{
$currency = $this->repository->getAccountCurrency($account);
if (null === $currency) {
$currency = $this->default;
}
$currentSet = [
'label' => $account->name,
// the currency that belongs to the account.
'currency_id' => (string) $currency->id,
'currency_code' => $currency->code,
'currency_symbol' => $currency->symbol,
'currency_decimal_places' => $currency->decimal_places,
// the default currency of the user (could be the same!)
'date' => $params['start']->toAtomString(),
'start' => $params['start']->toAtomString(),
'end' => $params['end']->toAtomString(),
'period' => '1D',
'entries' => [],
];
$currentStart = clone $params['start'];
$range = Steam::finalAccountBalanceInRange($account, $params['start'], clone $params['end'], $this->convertToNative);
$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;
$currentStart->addDay();
$currentSet['entries'][$label] = $balance;
}
$this->chartData->add($currentSet);
}
} }

View File

@@ -193,7 +193,7 @@ class BudgetController extends Controller
// var_dump($return); // var_dump($return);
/** @var array $journal */ /** @var array $journal */
foreach ($currentBudgetArray['transaction_journals'] as $journal) { foreach ($currentBudgetArray['transaction_journals'] as $journal) {
$return[$currencyId]['spent'] = bcadd($return[$currencyId]['spent'], $journal['amount']); $return[$currencyId]['spent'] = bcadd($return[$currencyId]['spent'], (string) $journal['amount']);
} }
} }
@@ -245,13 +245,13 @@ class BudgetController extends Controller
} }
$result = $this->processExpenses($budget->id, $filtered, $limit->start_date, $end); $result = $this->processExpenses($budget->id, $filtered, $limit->start_date, $end);
if (1 === count($result)) { if (1 === count($result)) {
$compare = bccomp($limit->amount, app('steam')->positive($result[$limitCurrencyId]['spent'])); $compare = bccomp($limit->amount, (string) app('steam')->positive($result[$limitCurrencyId]['spent']));
if (1 === $compare) { if (1 === $compare) {
// convert this amount into the native currency: // convert this amount into the native currency:
$result[$limitCurrencyId]['left'] = bcadd($limit->amount, $result[$limitCurrencyId]['spent']); $result[$limitCurrencyId]['left'] = bcadd($limit->amount, (string) $result[$limitCurrencyId]['spent']);
} }
if ($compare <= 0) { if ($compare <= 0) {
$result[$limitCurrencyId]['overspent'] = app('steam')->positive(bcadd($limit->amount, $result[$limitCurrencyId]['spent'])); $result[$limitCurrencyId]['overspent'] = app('steam')->positive(bcadd($limit->amount, (string) $result[$limitCurrencyId]['spent']));
} }
} }

View File

@@ -96,7 +96,7 @@ class CategoryController extends Controller
$currencyId = (int) $journal['currency_id']; $currencyId = (int) $journal['currency_id'];
$currency = $currencies[$currencyId] ?? $this->currencyRepos->find($currencyId); $currency = $currencies[$currencyId] ?? $this->currencyRepos->find($currencyId);
$currencies[$currencyId] = $currency; $currencies[$currencyId] = $currency;
$categoryName = null === $journal['category_name'] ? (string) trans('firefly.no_category') : $journal['category_name']; $categoryName = $journal['category_name'] ?? (string) trans('firefly.no_category');
$amount = app('steam')->positive($journal['amount']); $amount = app('steam')->positive($journal['amount']);
$key = sprintf('%s-%s', $categoryName, $currency->code); $key = sprintf('%s-%s', $categoryName, $currency->code);
// create arrays // create arrays
@@ -114,14 +114,12 @@ class CategoryController extends Controller
]; ];
// add monies // add monies
$return[$key]['amount'] = bcadd($return[$key]['amount'], $amount); $return[$key]['amount'] = bcadd($return[$key]['amount'], (string) $amount);
} }
$return = array_values($return); $return = array_values($return);
// order by amount // order by amount
usort($return, static function (array $a, array $b) { usort($return, static fn (array $a, array $b) => (float) $a['amount'] < (float) $b['amount'] ? 1 : -1);
return (float) $a['amount'] < (float) $b['amount'] ? 1 : -1;
});
return response()->json($this->clean($return)); return response()->json($this->clean($return));
} }

View File

@@ -40,7 +40,7 @@ use Illuminate\Foundation\Bus\DispatchesJobs;
use Illuminate\Foundation\Validation\ValidatesRequests; use Illuminate\Foundation\Validation\ValidatesRequests;
use Illuminate\Pagination\LengthAwarePaginator; use Illuminate\Pagination\LengthAwarePaginator;
use Illuminate\Routing\Controller as BaseController; use Illuminate\Routing\Controller as BaseController;
use Illuminate\Support\Collection; use Illuminate\Support\Facades\Log;
use League\Fractal\Manager; use League\Fractal\Manager;
use League\Fractal\Pagination\IlluminatePaginatorAdapter; use League\Fractal\Pagination\IlluminatePaginatorAdapter;
use League\Fractal\Resource\Collection as FractalCollection; use League\Fractal\Resource\Collection as FractalCollection;
@@ -64,13 +64,13 @@ abstract class Controller extends BaseController
protected const string CONTENT_TYPE = 'application/vnd.api+json'; protected const string CONTENT_TYPE = 'application/vnd.api+json';
protected const string JSON_CONTENT_TYPE = 'application/json'; protected const string JSON_CONTENT_TYPE = 'application/json';
protected array $accepts = ['application/json', 'application/vnd.api+json'];
/** @var array<int, string> */ /** @var array<int, string> */
protected array $allowedSort; protected array $allowedSort;
protected ParameterBag $parameters;
protected bool $convertToNative = false; protected bool $convertToNative = false;
protected array $accepts = ['application/json', 'application/vnd.api+json'];
protected TransactionCurrency $nativeCurrency; protected TransactionCurrency $nativeCurrency;
protected ParameterBag $parameters;
/** /**
* Controller constructor. * Controller constructor.
@@ -124,9 +124,9 @@ abstract class Controller extends BaseController
try { try {
$date = request()->query->get($field); $date = request()->query->get($field);
} catch (BadRequestException $e) { } catch (BadRequestException $e) {
app('log')->error(sprintf('Request field "%s" contains a non-scalar value. Value set to NULL.', $field)); Log::error(sprintf('Request field "%s" contains a non-scalar value. Value set to NULL.', $field));
app('log')->error($e->getMessage()); Log::error($e->getMessage());
app('log')->error($e->getTraceAsString()); Log::error($e->getTraceAsString());
$value = null; $value = null;
} }
$obj = null; $obj = null;
@@ -135,7 +135,7 @@ abstract class Controller extends BaseController
$obj = Carbon::parse((string) $date); $obj = Carbon::parse((string) $date);
} catch (InvalidFormatException $e) { } catch (InvalidFormatException $e) {
// don't care // don't care
app('log')->warning( Log::warning(
sprintf( sprintf(
'Ignored invalid date "%s" in API controller parameter check: %s', 'Ignored invalid date "%s" in API controller parameter check: %s',
substr((string) $date, 0, 20), substr((string) $date, 0, 20),
@@ -153,9 +153,9 @@ abstract class Controller extends BaseController
try { try {
$value = request()->query->get($integer); $value = request()->query->get($integer);
} catch (BadRequestException $e) { } catch (BadRequestException $e) {
app('log')->error(sprintf('Request field "%s" contains a non-scalar value. Value set to NULL.', $integer)); Log::error(sprintf('Request field "%s" contains a non-scalar value. Value set to NULL.', $integer));
app('log')->error($e->getMessage()); Log::error($e->getMessage());
app('log')->error($e->getTraceAsString()); Log::error($e->getTraceAsString());
$value = null; $value = null;
} }
if (null !== $value) { if (null !== $value) {
@@ -193,9 +193,9 @@ abstract class Controller extends BaseController
try { try {
$param = (string) request()->query->get('sort'); $param = (string) request()->query->get('sort');
} catch (BadRequestException $e) { } catch (BadRequestException $e) {
app('log')->error('Request field "sort" contains a non-scalar value. Value set to NULL.'); Log::error('Request field "sort" contains a non-scalar value. Value set to NULL.');
app('log')->error($e->getMessage()); Log::error($e->getMessage());
app('log')->error($e->getTraceAsString()); Log::error($e->getTraceAsString());
$param = ''; $param = '';
} }
if ('' === $param) { if ('' === $param) {

View File

@@ -30,6 +30,8 @@ use FireflyIII\Exceptions\FireflyException;
use FireflyIII\Support\Export\ExportDataGenerator; use FireflyIII\Support\Export\ExportDataGenerator;
use Illuminate\Http\Response as LaravelResponse; use Illuminate\Http\Response as LaravelResponse;
use function Safe\date;
/** /**
* Class ExportController * Class ExportController
*/ */
@@ -88,7 +90,7 @@ class ExportController extends Controller
->header('Expires', '0') ->header('Expires', '0')
->header('Cache-Control', 'must-revalidate, post-check=0, pre-check=0') ->header('Cache-Control', 'must-revalidate, post-check=0, pre-check=0')
->header('Pragma', 'public') ->header('Pragma', 'public')
->header('Content-Length', (string) strlen($data[$key])) ->header('Content-Length', (string) strlen((string) $data[$key]))
; ;
return $response; return $response;

View File

@@ -160,7 +160,7 @@ class TagController extends Controller
'currency_id' => (string) $currencyId, 'currency_id' => (string) $currencyId,
'currency_code' => $journal['currency_code'], 'currency_code' => $journal['currency_code'],
]; ];
$response[$key]['difference'] = bcadd($response[$key]['difference'], $journal['amount']); $response[$key]['difference'] = bcadd((string) $response[$key]['difference'], (string) $journal['amount']);
$response[$key]['difference_float'] = (float) $response[$key]['difference']; // float but on purpose. $response[$key]['difference_float'] = (float) $response[$key]['difference']; // float but on purpose.
} }
@@ -172,7 +172,7 @@ class TagController extends Controller
'currency_id' => (string) $foreignCurrencyId, 'currency_id' => (string) $foreignCurrencyId,
'currency_code' => $journal['foreign_currency_code'], 'currency_code' => $journal['foreign_currency_code'],
]; ];
$response[$foreignKey]['difference'] = bcadd($response[$foreignKey]['difference'], $journal['foreign_amount']); $response[$foreignKey]['difference'] = bcadd((string) $response[$foreignKey]['difference'], (string) $journal['foreign_amount']);
$response[$foreignKey]['difference_float'] = (float) $response[$foreignKey]['difference']; // float but on purpose. $response[$foreignKey]['difference_float'] = (float) $response[$foreignKey]['difference']; // float but on purpose.
} }
} }

View File

@@ -75,7 +75,7 @@ class PeriodController extends Controller
'currency_id' => (string) $currencyId, 'currency_id' => (string) $currencyId,
'currency_code' => $currencyCode, 'currency_code' => $currencyCode,
]; ];
$response[$currencyId]['difference'] = bcadd($response[$currencyId]['difference'], app('steam')->positive($journal[$field])); $response[$currencyId]['difference'] = bcadd($response[$currencyId]['difference'], (string) app('steam')->positive($journal[$field]));
$response[$currencyId]['difference_float'] = (float) $response[$currencyId]['difference']; // float but on purpose. $response[$currencyId]['difference_float'] = (float) $response[$currencyId]['difference']; // float but on purpose.
} }

View File

@@ -100,7 +100,7 @@ class TagController extends Controller
'currency_id' => (string) $currencyId, 'currency_id' => (string) $currencyId,
'currency_code' => $currencyCode, 'currency_code' => $currencyCode,
]; ];
$response[$currencyId]['difference'] = bcadd($response[$currencyId]['difference'], app('steam')->positive($journal[$field])); $response[$currencyId]['difference'] = bcadd($response[$currencyId]['difference'], (string) app('steam')->positive($journal[$field]));
$response[$currencyId]['difference_float'] = (float) $response[$currencyId]['difference']; $response[$currencyId]['difference_float'] = (float) $response[$currencyId]['difference'];
} }
@@ -154,7 +154,7 @@ class TagController extends Controller
'currency_id' => (string) $currencyId, 'currency_id' => (string) $currencyId,
'currency_code' => $journal['currency_code'], 'currency_code' => $journal['currency_code'],
]; ];
$response[$key]['difference'] = bcadd($response[$key]['difference'], app('steam')->positive($journal['amount'])); $response[$key]['difference'] = bcadd((string) $response[$key]['difference'], (string) app('steam')->positive($journal['amount']));
$response[$key]['difference_float'] = (float) $response[$key]['difference']; $response[$key]['difference_float'] = (float) $response[$key]['difference'];
} }
@@ -167,8 +167,8 @@ class TagController extends Controller
'currency_code' => $journal['foreign_currency_code'], 'currency_code' => $journal['foreign_currency_code'],
]; ];
$response[$foreignKey]['difference'] = bcadd( $response[$foreignKey]['difference'] = bcadd(
$response[$foreignKey]['difference'], (string) $response[$foreignKey]['difference'],
app('steam')->positive($journal['foreign_amount']) (string) app('steam')->positive($journal['foreign_amount'])
); );
$response[$foreignKey]['difference_float'] = (float) $response[$foreignKey]['difference']; $response[$foreignKey]['difference_float'] = (float) $response[$foreignKey]['difference'];
} }

View File

@@ -75,7 +75,7 @@ class PeriodController extends Controller
'currency_id' => (string) $currencyId, 'currency_id' => (string) $currencyId,
'currency_code' => $currencyCode, 'currency_code' => $currencyCode,
]; ];
$response[$currencyId]['difference'] = bcadd($response[$currencyId]['difference'], app('steam')->positive($journal[$field])); $response[$currencyId]['difference'] = bcadd($response[$currencyId]['difference'], (string) app('steam')->positive($journal[$field]));
$response[$currencyId]['difference_float'] = (float) $response[$currencyId]['difference']; $response[$currencyId]['difference_float'] = (float) $response[$currencyId]['difference'];
} }

View File

@@ -99,7 +99,7 @@ class TagController extends Controller
'currency_id' => (string) $currencyId, 'currency_id' => (string) $currencyId,
'currency_code' => $currencyCode, 'currency_code' => $currencyCode,
]; ];
$response[$currencyId]['difference'] = bcadd($response[$currencyId]['difference'], app('steam')->positive($journal[$field])); $response[$currencyId]['difference'] = bcadd($response[$currencyId]['difference'], (string) app('steam')->positive($journal[$field]));
$response[$currencyId]['difference_float'] = (float) $response[$currencyId]['difference']; $response[$currencyId]['difference_float'] = (float) $response[$currencyId]['difference'];
} }
@@ -153,7 +153,7 @@ class TagController extends Controller
'currency_id' => (string) $currencyId, 'currency_id' => (string) $currencyId,
'currency_code' => $journal['currency_code'], 'currency_code' => $journal['currency_code'],
]; ];
$response[$key]['difference'] = bcadd($response[$key]['difference'], app('steam')->positive($journal['amount'])); $response[$key]['difference'] = bcadd((string) $response[$key]['difference'], (string) app('steam')->positive($journal['amount']));
$response[$key]['difference_float'] = (float) $response[$key]['difference']; $response[$key]['difference_float'] = (float) $response[$key]['difference'];
} }
@@ -166,8 +166,8 @@ class TagController extends Controller
'currency_code' => $journal['foreign_currency_code'], 'currency_code' => $journal['foreign_currency_code'],
]; ];
$response[$foreignKey]['difference'] = bcadd( $response[$foreignKey]['difference'] = bcadd(
$response[$foreignKey]['difference'], (string) $response[$foreignKey]['difference'],
app('steam')->positive($journal['foreign_amount']) (string) app('steam')->positive($journal['foreign_amount'])
); );
$response[$foreignKey]['difference_float'] = (float) $response[$foreignKey]['difference']; // intentional float $response[$foreignKey]['difference_float'] = (float) $response[$foreignKey]['difference']; // intentional float
} }

View File

@@ -24,6 +24,7 @@ declare(strict_types=1);
namespace FireflyIII\Api\V1\Controllers\Models\CurrencyExchangeRate; namespace FireflyIII\Api\V1\Controllers\Models\CurrencyExchangeRate;
use Carbon\Carbon;
use FireflyIII\Api\V1\Controllers\Controller; use FireflyIII\Api\V1\Controllers\Controller;
use FireflyIII\Api\V1\Requests\Models\CurrencyExchangeRate\DestroyRequest; use FireflyIII\Api\V1\Requests\Models\CurrencyExchangeRate\DestroyRequest;
use FireflyIII\Enums\UserRoleEnum; use FireflyIII\Enums\UserRoleEnum;
@@ -39,10 +40,8 @@ class DestroyController extends Controller
{ {
use ValidatesUserGroupTrait; use ValidatesUserGroupTrait;
protected array $acceptedRoles = [UserRoleEnum::OWNER];
public const string RESOURCE_KEY = 'exchange-rates'; public const string RESOURCE_KEY = 'exchange-rates';
protected array $acceptedRoles = [UserRoleEnum::OWNER];
private ExchangeRateRepositoryInterface $repository; private ExchangeRateRepositoryInterface $repository;
public function __construct() public function __construct()
@@ -61,11 +60,11 @@ class DestroyController extends Controller
public function destroy(DestroyRequest $request, TransactionCurrency $from, TransactionCurrency $to): JsonResponse public function destroy(DestroyRequest $request, TransactionCurrency $from, TransactionCurrency $to): JsonResponse
{ {
$date = $request->getDate(); $date = $request->getDate();
if (null === $date) { if (!$date instanceof Carbon) {
throw new ValidationException('Date is required'); throw new ValidationException('Date is required');
} }
$rate = $this->repository->getSpecificRateOnDate($from, $to, $date); $rate = $this->repository->getSpecificRateOnDate($from, $to, $date);
if (null === $rate) { if (!$rate instanceof CurrencyExchangeRate) {
throw new NotFoundHttpException(); throw new NotFoundHttpException();
} }
$this->repository->deleteRate($rate); $this->repository->deleteRate($rate);

View File

@@ -24,6 +24,7 @@ declare(strict_types=1);
namespace FireflyIII\Api\V1\Controllers\Models\CurrencyExchangeRate; namespace FireflyIII\Api\V1\Controllers\Models\CurrencyExchangeRate;
use FireflyIII\Models\CurrencyExchangeRate;
use FireflyIII\Api\V1\Requests\Models\CurrencyExchangeRate\StoreRequest; use FireflyIII\Api\V1\Requests\Models\CurrencyExchangeRate\StoreRequest;
use FireflyIII\Api\V2\Controllers\Controller; use FireflyIII\Api\V2\Controllers\Controller;
use FireflyIII\Repositories\ExchangeRate\ExchangeRateRepositoryInterface; use FireflyIII\Repositories\ExchangeRate\ExchangeRateRepositoryInterface;
@@ -61,11 +62,11 @@ class StoreController extends Controller
// already has rate? // already has rate?
$object = $this->repository->getSpecificRateOnDate($from, $to, $date); $object = $this->repository->getSpecificRateOnDate($from, $to, $date);
if (null !== $object) { if ($object instanceof CurrencyExchangeRate) {
// just update it, no matter. // just update it, no matter.
$rate = $this->repository->updateExchangeRate($object, $rate, $date); $rate = $this->repository->updateExchangeRate($object, $rate, $date);
} }
if (null === $object) { if (!$object instanceof CurrencyExchangeRate) {
// store new // store new
$rate = $this->repository->storeExchangeRate($from, $to, $rate, $date); $rate = $this->repository->storeExchangeRate($from, $to, $rate, $date);
} }

View File

@@ -24,6 +24,7 @@ declare(strict_types=1);
namespace FireflyIII\Api\V1\Controllers\Models\RuleGroup; namespace FireflyIII\Api\V1\Controllers\Models\RuleGroup;
use Exception;
use FireflyIII\Api\V1\Controllers\Controller; use FireflyIII\Api\V1\Controllers\Controller;
use FireflyIII\Api\V1\Requests\Models\RuleGroup\TestRequest; use FireflyIII\Api\V1\Requests\Models\RuleGroup\TestRequest;
use FireflyIII\Api\V1\Requests\Models\RuleGroup\TriggerRequest; use FireflyIII\Api\V1\Requests\Models\RuleGroup\TriggerRequest;
@@ -128,7 +129,7 @@ class TriggerController extends Controller
* *
* Execute the given rule group on a set of existing transactions. * Execute the given rule group on a set of existing transactions.
* *
* @throws \Exception * @throws Exception
*/ */
public function triggerGroup(TriggerRequest $request, RuleGroup $group): JsonResponse public function triggerGroup(TriggerRequest $request, RuleGroup $group): JsonResponse
{ {

View File

@@ -50,9 +50,8 @@ class StoreController extends Controller
{ {
use TransactionFilter; use TransactionFilter;
private TransactionGroupRepositoryInterface $groupRepository;
protected array $acceptedRoles = [UserRoleEnum::MANAGE_TRANSACTIONS]; protected array $acceptedRoles = [UserRoleEnum::MANAGE_TRANSACTIONS];
private TransactionGroupRepositoryInterface $groupRepository;
/** /**
* TransactionController constructor. * TransactionController constructor.

View File

@@ -73,13 +73,16 @@ class UpdateController extends Controller
{ {
app('log')->debug('Now in update routine for transaction group'); app('log')->debug('Now in update routine for transaction group');
$data = $request->getAll(); $data = $request->getAll();
$oldHash = $this->groupRepository->getCompareHash($transactionGroup);
$transactionGroup = $this->groupRepository->update($transactionGroup, $data); $transactionGroup = $this->groupRepository->update($transactionGroup, $data);
$newHash = $this->groupRepository->getCompareHash($transactionGroup);
$manager = $this->getManager(); $manager = $this->getManager();
app('preferences')->mark(); app('preferences')->mark();
$applyRules = $data['apply_rules'] ?? true; $applyRules = $data['apply_rules'] ?? true;
$fireWebhooks = $data['fire_webhooks'] ?? true; $fireWebhooks = $data['fire_webhooks'] ?? true;
event(new UpdatedTransactionGroup($transactionGroup, $applyRules, $fireWebhooks)); $runRecalculations = $oldHash !== $newHash;
event(new UpdatedTransactionGroup($transactionGroup, $applyRules, $fireWebhooks, $runRecalculations));
/** @var User $admin */ /** @var User $admin */
$admin = auth()->user(); $admin = auth()->user();

View File

@@ -24,11 +24,12 @@ declare(strict_types=1);
namespace FireflyIII\Api\V1\Controllers\Models\TransactionCurrency; namespace FireflyIII\Api\V1\Controllers\Models\TransactionCurrency;
use Illuminate\Support\Facades\Validator;
use FireflyIII\Api\V1\Controllers\Controller; use FireflyIII\Api\V1\Controllers\Controller;
use FireflyIII\Exceptions\FireflyException; use FireflyIII\Exceptions\FireflyException;
use FireflyIII\Models\TransactionCurrency; use FireflyIII\Models\TransactionCurrency;
use FireflyIII\Repositories\User\UserRepositoryInterface;
use FireflyIII\Repositories\Currency\CurrencyRepositoryInterface; use FireflyIII\Repositories\Currency\CurrencyRepositoryInterface;
use FireflyIII\Repositories\User\UserRepositoryInterface;
use FireflyIII\User; use FireflyIII\User;
use Illuminate\Http\JsonResponse; use Illuminate\Http\JsonResponse;
@@ -74,15 +75,15 @@ class DestroyController extends Controller
if (!$this->userRepository->hasRole($admin, 'owner')) { if (!$this->userRepository->hasRole($admin, 'owner')) {
// access denied: // access denied:
$messages = ['currency_code' => '200005: You need the "owner" role to do this.']; $messages = ['currency_code' => '200005: You need the "owner" role to do this.'];
\Validator::make([], $rules, $messages)->validate(); Validator::make([], $rules, $messages)->validate();
} }
if ($this->repository->currencyInUse($currency)) { if ($this->repository->currencyInUse($currency)) {
$messages = ['currency_code' => '200006: Currency in use.']; $messages = ['currency_code' => '200006: Currency in use.'];
\Validator::make([], $rules, $messages)->validate(); Validator::make([], $rules, $messages)->validate();
} }
if ($this->repository->isFallbackCurrency($currency)) { if ($this->repository->isFallbackCurrency($currency)) {
$messages = ['currency_code' => '200026: Currency is fallback.']; $messages = ['currency_code' => '200026: Currency is fallback.'];
\Validator::make([], $rules, $messages)->validate(); Validator::make([], $rules, $messages)->validate();
} }
$this->repository->destroy($currency); $this->repository->destroy($currency);

View File

@@ -177,9 +177,7 @@ class ListController extends Controller
// filter and paginate list: // filter and paginate list:
$collection = $unfiltered->filter( $collection = $unfiltered->filter(
static function (Bill $bill) use ($currency) { static fn (Bill $bill) => $bill->transaction_currency_id === $currency->id
return $bill->transaction_currency_id === $currency->id;
}
); );
$count = $collection->count(); $count = $collection->count();
$bills = $collection->slice(($this->parameters->get('page') - 1) * $pageSize, $pageSize); $bills = $collection->slice(($this->parameters->get('page') - 1) * $pageSize, $pageSize);

View File

@@ -24,6 +24,7 @@ declare(strict_types=1);
namespace FireflyIII\Api\V1\Controllers\Models\TransactionLink; namespace FireflyIII\Api\V1\Controllers\Models\TransactionLink;
use FireflyIII\Models\TransactionJournal;
use FireflyIII\Api\V1\Controllers\Controller; use FireflyIII\Api\V1\Controllers\Controller;
use FireflyIII\Api\V1\Requests\Models\TransactionLink\StoreRequest; use FireflyIII\Api\V1\Requests\Models\TransactionLink\StoreRequest;
use FireflyIII\Exceptions\FireflyException; use FireflyIII\Exceptions\FireflyException;
@@ -81,7 +82,7 @@ class StoreController extends Controller
$data = $request->getAll(); $data = $request->getAll();
$inward = $this->journalRepository->find($data['inward_id'] ?? 0); $inward = $this->journalRepository->find($data['inward_id'] ?? 0);
$outward = $this->journalRepository->find($data['outward_id'] ?? 0); $outward = $this->journalRepository->find($data['outward_id'] ?? 0);
if (null === $inward || null === $outward) { if (!$inward instanceof TransactionJournal || !$outward instanceof TransactionJournal) {
throw new FireflyException('200024: Source or destination does not exist.'); throw new FireflyException('200024: Source or destination does not exist.');
} }
$data['direction'] = 'inward'; $data['direction'] = 'inward';

View File

@@ -24,6 +24,7 @@ declare(strict_types=1);
namespace FireflyIII\Api\V1\Controllers\Models\TransactionLinkType; namespace FireflyIII\Api\V1\Controllers\Models\TransactionLinkType;
use Illuminate\Support\Facades\Validator;
use FireflyIII\Api\V1\Controllers\Controller; use FireflyIII\Api\V1\Controllers\Controller;
use FireflyIII\Api\V1\Requests\Models\TransactionLinkType\StoreRequest; use FireflyIII\Api\V1\Requests\Models\TransactionLinkType\StoreRequest;
use FireflyIII\Exceptions\FireflyException; use FireflyIII\Exceptions\FireflyException;
@@ -81,7 +82,7 @@ class StoreController extends Controller
if (!$this->userRepository->hasRole($admin, 'owner')) { if (!$this->userRepository->hasRole($admin, 'owner')) {
// access denied: // access denied:
$messages = ['name' => '200005: You need the "owner" role to do this.']; $messages = ['name' => '200005: You need the "owner" role to do this.'];
\Validator::make([], $rules, $messages)->validate(); Validator::make([], $rules, $messages)->validate();
} }
$data = $request->getAll(); $data = $request->getAll();
// if currency ID is 0, find the currency by the code: // if currency ID is 0, find the currency by the code:

View File

@@ -24,6 +24,7 @@ declare(strict_types=1);
namespace FireflyIII\Api\V1\Controllers\Models\TransactionLinkType; namespace FireflyIII\Api\V1\Controllers\Models\TransactionLinkType;
use Illuminate\Support\Facades\Validator;
use FireflyIII\Api\V1\Controllers\Controller; use FireflyIII\Api\V1\Controllers\Controller;
use FireflyIII\Api\V1\Requests\Models\TransactionLinkType\UpdateRequest; use FireflyIII\Api\V1\Requests\Models\TransactionLinkType\UpdateRequest;
use FireflyIII\Exceptions\FireflyException; use FireflyIII\Exceptions\FireflyException;
@@ -85,7 +86,7 @@ class UpdateController extends Controller
if (!$this->userRepository->hasRole($admin, 'owner')) { if (!$this->userRepository->hasRole($admin, 'owner')) {
$messages = ['name' => '200005: You need the "owner" role to do this.']; $messages = ['name' => '200005: You need the "owner" role to do this.'];
\Validator::make([], $rules, $messages)->validate(); Validator::make([], $rules, $messages)->validate();
} }
$data = $request->getAll(); $data = $request->getAll();

View File

@@ -24,6 +24,7 @@ declare(strict_types=1);
namespace FireflyIII\Api\V1\Controllers\Summary; namespace FireflyIII\Api\V1\Controllers\Summary;
use Exception;
use Carbon\Carbon; use Carbon\Carbon;
use FireflyIII\Api\V1\Controllers\Controller; use FireflyIII\Api\V1\Controllers\Controller;
use FireflyIII\Api\V1\Requests\Data\DateRequest; use FireflyIII\Api\V1\Requests\Data\DateRequest;
@@ -91,7 +92,7 @@ class BasicController extends Controller
* This endpoint is documented at: * This endpoint is documented at:
* https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/summary/getBasicSummary * https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/summary/getBasicSummary
* *
* @throws \Exception * @throws Exception
*/ */
public function basic(DateRequest $request): JsonResponse public function basic(DateRequest $request): JsonResponse
{ {
@@ -191,14 +192,14 @@ class BasicController extends Controller
// if it is the native currency already. // if it is the native currency already.
if ($entry['currency_id'] === $default->id) { if ($entry['currency_id'] === $default->id) {
$sums[$default->id]['sum'] = bcadd($entry['sum'], $sums[$default->id]['sum']); $sums[$default->id]['sum'] = bcadd((string) $entry['sum'], $sums[$default->id]['sum']);
// don't forget to add it to newExpenses and newIncome // don't forget to add it to newExpenses and newIncome
if (0 === $index) { if (0 === $index) {
$newExpenses[$default->id]['sum'] = bcadd($newExpenses[$default->id]['sum'], $entry['sum']); $newExpenses[$default->id]['sum'] = bcadd($newExpenses[$default->id]['sum'], (string) $entry['sum']);
} }
if (1 === $index) { if (1 === $index) {
$newIncomes[$default->id]['sum'] = bcadd($newIncomes[$default->id]['sum'], $entry['sum']); $newIncomes[$default->id]['sum'] = bcadd($newIncomes[$default->id]['sum'], (string) $entry['sum']);
} }
continue; continue;
@@ -229,7 +230,7 @@ class BasicController extends Controller
'currency_decimal_places' => $entry['currency_decimal_places'], 'currency_decimal_places' => $entry['currency_decimal_places'],
'sum' => '0', 'sum' => '0',
]; ];
$sums[$currencyId]['sum'] = bcadd($sums[$currencyId]['sum'], $entry['sum']); $sums[$currencyId]['sum'] = bcadd($sums[$currencyId]['sum'], (string) $entry['sum']);
} }
} }
} }
@@ -362,7 +363,7 @@ class BasicController extends Controller
if (0 === $index) { if (0 === $index) {
// paid amount // paid amount
if ($currencyId === $this->nativeCurrency->id) { if ($currencyId === $this->nativeCurrency->id) {
$newPaidAmount[0]['sum'] = bcadd($newPaidAmount[0]['sum'], $item['sum']); $newPaidAmount[0]['sum'] = bcadd($newPaidAmount[0]['sum'], (string) $item['sum']);
continue; continue;
} }
@@ -374,7 +375,7 @@ class BasicController extends Controller
} }
// unpaid amount // unpaid amount
if ($currencyId === $this->nativeCurrency->id) { if ($currencyId === $this->nativeCurrency->id) {
$newUnpaidAmount[0]['sum'] = bcadd($newUnpaidAmount[0]['sum'], $item['sum']); $newUnpaidAmount[0]['sum'] = bcadd($newUnpaidAmount[0]['sum'], (string) $item['sum']);
continue; continue;
} }
@@ -397,7 +398,7 @@ class BasicController extends Controller
* @var array $info * @var array $info
*/ */
foreach ($paidAmount as $info) { foreach ($paidAmount as $info) {
$amount = bcmul($info['sum'], '-1'); $amount = bcmul((string) $info['sum'], '-1');
$return[] = [ $return[] = [
'key' => sprintf('bills-paid-in-%s', $info['code']), 'key' => sprintf('bills-paid-in-%s', $info['code']),
'title' => trans('firefly.box_bill_paid_in_currency', ['currency' => $info['symbol']]), 'title' => trans('firefly.box_bill_paid_in_currency', ['currency' => $info['symbol']]),
@@ -416,7 +417,7 @@ class BasicController extends Controller
* @var array $info * @var array $info
*/ */
foreach ($unpaidAmount as $info) { foreach ($unpaidAmount as $info) {
$amount = bcmul($info['sum'], '-1'); $amount = bcmul((string) $info['sum'], '-1');
$return[] = [ $return[] = [
'key' => sprintf('bills-unpaid-in-%s', $info['code']), 'key' => sprintf('bills-unpaid-in-%s', $info['code']),
'title' => trans('firefly.box_bill_unpaid_in_currency', ['currency' => $info['symbol']]), 'title' => trans('firefly.box_bill_unpaid_in_currency', ['currency' => $info['symbol']]),
@@ -467,7 +468,7 @@ class BasicController extends Controller
} }
/** /**
* @throws \Exception * @throws Exception
*/ */
private function getLeftToSpendInfo(Carbon $start, Carbon $end): array private function getLeftToSpendInfo(Carbon $start, Carbon $end): array
{ {
@@ -513,7 +514,7 @@ class BasicController extends Controller
continue; continue;
} }
$spentInCurrency = $row['sum']; $spentInCurrency = $row['sum'];
$leftToSpend = bcadd($amount, $spentInCurrency); $leftToSpend = bcadd($amount, (string) $spentInCurrency);
$perDay = '0'; $perDay = '0';
if (0 !== $days && bccomp($leftToSpend, '0') > -1) { if (0 !== $days && bccomp($leftToSpend, '0') > -1) {
$perDay = bcdiv($leftToSpend, (string) $days); $perDay = bcdiv($leftToSpend, (string) $days);
@@ -549,8 +550,8 @@ class BasicController extends Controller
$currencyId = (int) $row['currency_id']; $currencyId = (int) $row['currency_id'];
$spentInCurrency = $row['sum']; $spentInCurrency = $row['sum'];
$perDay = '0'; $perDay = '0';
if (0 !== $days && -1 === bccomp($spentInCurrency, '0')) { if (0 !== $days && -1 === bccomp((string) $spentInCurrency, '0')) {
$perDay = bcdiv($spentInCurrency, (string) $days); $perDay = bcdiv((string) $spentInCurrency, (string) $days);
} }
Log::debug(sprintf('Spent %s %s', $row['currency_code'], $row['sum'])); Log::debug(sprintf('Spent %s %s', $row['currency_code'], $row['sum']));
@@ -631,7 +632,7 @@ class BasicController extends Controller
continue; continue;
} }
$amount = $data['balance']; $amount = $data['balance'];
if (0 === bccomp($amount, '0')) { if (0 === bccomp((string) $amount, '0')) {
continue; continue;
} }
// return stuff // return stuff
@@ -674,15 +675,14 @@ class BasicController extends Controller
*/ */
protected function notInDateRange(Carbon $date, Carbon $start, Carbon $end): bool // Validate a preference protected function notInDateRange(Carbon $date, Carbon $start, Carbon $end): bool // Validate a preference
{ {
$result = false;
if ($start->greaterThanOrEqualTo($date) && $end->greaterThanOrEqualTo($date)) { if ($start->greaterThanOrEqualTo($date) && $end->greaterThanOrEqualTo($date)) {
$result = true; return true;
} }
// start and end in the past? use $end // start and end in the past? use $end
if ($start->lessThanOrEqualTo($date) && $end->lessThanOrEqualTo($date)) { if ($start->lessThanOrEqualTo($date) && $end->lessThanOrEqualTo($date)) {
$result = true; return true;
} }
return $result; return false;
} }
} }

View File

@@ -24,6 +24,7 @@ declare(strict_types=1);
namespace FireflyIII\Api\V1\Controllers\System; namespace FireflyIII\Api\V1\Controllers\System;
use Illuminate\Support\Facades\Validator;
use FireflyIII\Api\V1\Controllers\Controller; use FireflyIII\Api\V1\Controllers\Controller;
use FireflyIII\Api\V1\Requests\System\UpdateRequest; use FireflyIII\Api\V1\Requests\System\UpdateRequest;
use FireflyIII\Exceptions\FireflyException; use FireflyIII\Exceptions\FireflyException;
@@ -158,7 +159,7 @@ class ConfigurationController extends Controller
$rules = ['value' => 'required']; $rules = ['value' => 'required'];
if (!$this->repository->hasRole(auth()->user(), 'owner')) { if (!$this->repository->hasRole(auth()->user(), 'owner')) {
$messages = ['value' => '200005: You need the "owner" role to do this.']; $messages = ['value' => '200005: You need the "owner" role to do this.'];
\Validator::make([], $rules, $messages)->validate(); Validator::make([], $rules, $messages)->validate();
} }
$data = $request->getAll(); $data = $request->getAll();
$shortName = str_replace('configuration.', '', $name); $shortName = str_replace('configuration.', '', $name);

View File

@@ -23,6 +23,7 @@ declare(strict_types=1);
namespace FireflyIII\Api\V1\Middleware; namespace FireflyIII\Api\V1\Middleware;
use Closure;
use FireflyIII\User; use FireflyIII\User;
use Illuminate\Http\Request; use Illuminate\Http\Request;
@@ -36,7 +37,7 @@ class ApiDemoUser
* *
* @return mixed * @return mixed
*/ */
public function handle(Request $request, \Closure $next) public function handle(Request $request, Closure $next)
{ {
/** @var null|User $user */ /** @var null|User $user */
$user = $request->user(); $user = $request->user();

View File

@@ -24,13 +24,13 @@ declare(strict_types=1);
namespace FireflyIII\Api\V1\Requests\Chart; namespace FireflyIII\Api\V1\Requests\Chart;
use Illuminate\Contracts\Validation\Validator;
use FireflyIII\Enums\UserRoleEnum; use FireflyIII\Enums\UserRoleEnum;
use FireflyIII\Support\Http\Api\ValidatesUserGroupTrait; use FireflyIII\Support\Http\Api\ValidatesUserGroupTrait;
use FireflyIII\Support\Request\ChecksLogin; use FireflyIII\Support\Request\ChecksLogin;
use FireflyIII\Support\Request\ConvertsDataTypes; use FireflyIII\Support\Request\ConvertsDataTypes;
use Illuminate\Foundation\Http\FormRequest; use Illuminate\Foundation\Http\FormRequest;
use Illuminate\Support\Facades\Log; use Illuminate\Support\Facades\Log;
use Illuminate\Validation\Validator;
/** /**
* Class ChartRequest * Class ChartRequest
@@ -85,7 +85,7 @@ class ChartRequest extends FormRequest
} }
); );
if ($validator->fails()) { if ($validator->fails()) {
Log::channel('audit')->error(sprintf('Validation errors in %s', __CLASS__), $validator->errors()->toArray()); Log::channel('audit')->error(sprintf('Validation errors in %s', self::class), $validator->errors()->toArray());
} }
} }
} }

View File

@@ -24,12 +24,12 @@ declare(strict_types=1);
namespace FireflyIII\Api\V1\Requests\Data\Bulk; namespace FireflyIII\Api\V1\Requests\Data\Bulk;
use Illuminate\Contracts\Validation\Validator;
use FireflyIII\Repositories\Account\AccountRepositoryInterface; use FireflyIII\Repositories\Account\AccountRepositoryInterface;
use FireflyIII\Support\Request\ChecksLogin; use FireflyIII\Support\Request\ChecksLogin;
use FireflyIII\Support\Request\ConvertsDataTypes; use FireflyIII\Support\Request\ConvertsDataTypes;
use Illuminate\Foundation\Http\FormRequest; use Illuminate\Foundation\Http\FormRequest;
use Illuminate\Support\Facades\Log; use Illuminate\Support\Facades\Log;
use Illuminate\Validation\Validator;
/** /**
* Class MoveTransactionsRequest * Class MoveTransactionsRequest
@@ -74,7 +74,7 @@ class MoveTransactionsRequest extends FormRequest
} }
); );
if ($validator->fails()) { if ($validator->fails()) {
Log::channel('audit')->error(sprintf('Validation errors in %s', __CLASS__), $validator->errors()->toArray()); Log::channel('audit')->error(sprintf('Validation errors in %s', self::class), $validator->errors()->toArray());
} }
} }

View File

@@ -24,6 +24,8 @@ declare(strict_types=1);
namespace FireflyIII\Api\V1\Requests\Data\Bulk; namespace FireflyIII\Api\V1\Requests\Data\Bulk;
use Illuminate\Contracts\Validation\Validator;
use JsonException;
use FireflyIII\Enums\ClauseType; use FireflyIII\Enums\ClauseType;
use FireflyIII\Rules\IsValidBulkClause; use FireflyIII\Rules\IsValidBulkClause;
use FireflyIII\Support\Request\ChecksLogin; use FireflyIII\Support\Request\ChecksLogin;
@@ -31,7 +33,8 @@ use FireflyIII\Support\Request\ConvertsDataTypes;
use FireflyIII\Validation\Api\Data\Bulk\ValidatesBulkTransactionQuery; use FireflyIII\Validation\Api\Data\Bulk\ValidatesBulkTransactionQuery;
use Illuminate\Foundation\Http\FormRequest; use Illuminate\Foundation\Http\FormRequest;
use Illuminate\Support\Facades\Log; use Illuminate\Support\Facades\Log;
use Illuminate\Validation\Validator;
use function Safe\json_decode;
/** /**
* Class TransactionRequest * Class TransactionRequest
@@ -50,7 +53,7 @@ class TransactionRequest extends FormRequest
$data = [ $data = [
'query' => json_decode($this->get('query'), true, 8, JSON_THROW_ON_ERROR), 'query' => json_decode($this->get('query'), true, 8, JSON_THROW_ON_ERROR),
]; ];
} catch (\JsonException $e) { } catch (JsonException $e) {
// dont really care. the validation should catch invalid json. // dont really care. the validation should catch invalid json.
app('log')->error($e->getMessage()); app('log')->error($e->getMessage());
} }
@@ -74,7 +77,7 @@ class TransactionRequest extends FormRequest
} }
); );
if ($validator->fails()) { if ($validator->fails()) {
Log::channel('audit')->error(sprintf('Validation errors in %s', __CLASS__), $validator->errors()->toArray()); Log::channel('audit')->error(sprintf('Validation errors in %s', self::class), $validator->errors()->toArray());
} }
} }
} }

View File

@@ -24,6 +24,7 @@ declare(strict_types=1);
namespace FireflyIII\Api\V1\Requests\Models\Account; namespace FireflyIII\Api\V1\Requests\Models\Account;
use Illuminate\Contracts\Validation\Validator;
use FireflyIII\Models\Account; use FireflyIII\Models\Account;
use FireflyIII\Models\Location; use FireflyIII\Models\Location;
use FireflyIII\Repositories\Account\AccountRepositoryInterface; use FireflyIII\Repositories\Account\AccountRepositoryInterface;
@@ -35,7 +36,6 @@ use FireflyIII\Support\Request\ChecksLogin;
use FireflyIII\Support\Request\ConvertsDataTypes; use FireflyIII\Support\Request\ConvertsDataTypes;
use Illuminate\Foundation\Http\FormRequest; use Illuminate\Foundation\Http\FormRequest;
use Illuminate\Support\Facades\Log; use Illuminate\Support\Facades\Log;
use Illuminate\Validation\Validator;
/** /**
* Class UpdateRequest * Class UpdateRequest
@@ -144,7 +144,7 @@ class UpdateRequest extends FormRequest
} }
); );
if ($validator->fails()) { if ($validator->fails()) {
Log::channel('audit')->error(sprintf('Validation errors in %s', __CLASS__), $validator->errors()->toArray()); Log::channel('audit')->error(sprintf('Validation errors in %s', self::class), $validator->errors()->toArray());
} }
} }
} }

View File

@@ -58,9 +58,7 @@ class StoreRequest extends FormRequest
{ {
$models = config('firefly.valid_attachment_models'); $models = config('firefly.valid_attachment_models');
$models = array_map( $models = array_map(
static function (string $className) { static fn (string $className) => str_replace('FireflyIII\Models\\', '', $className),
return str_replace('FireflyIII\Models\\', '', $className);
},
$models $models
); );
$models = implode(',', $models); $models = implode(',', $models);

View File

@@ -60,9 +60,7 @@ class UpdateRequest extends FormRequest
{ {
$models = config('firefly.valid_attachment_models'); $models = config('firefly.valid_attachment_models');
$models = array_map( $models = array_map(
static function (string $className) { static fn (string $className) => str_replace('FireflyIII\Models\\', '', $className),
return str_replace('FireflyIII\Models\\', '', $className);
},
$models $models
); );
$models = implode(',', $models); $models = implode(',', $models);

View File

@@ -24,13 +24,13 @@ declare(strict_types=1);
namespace FireflyIII\Api\V1\Requests\Models\AvailableBudget; namespace FireflyIII\Api\V1\Requests\Models\AvailableBudget;
use Illuminate\Contracts\Validation\Validator;
use Carbon\Carbon; use Carbon\Carbon;
use FireflyIII\Rules\IsValidPositiveAmount; use FireflyIII\Rules\IsValidPositiveAmount;
use FireflyIII\Support\Request\ChecksLogin; use FireflyIII\Support\Request\ChecksLogin;
use FireflyIII\Support\Request\ConvertsDataTypes; use FireflyIII\Support\Request\ConvertsDataTypes;
use Illuminate\Foundation\Http\FormRequest; use Illuminate\Foundation\Http\FormRequest;
use Illuminate\Support\Facades\Log; use Illuminate\Support\Facades\Log;
use Illuminate\Validation\Validator;
/** /**
* Class Request * Class Request
@@ -90,7 +90,7 @@ class Request extends FormRequest
} }
); );
if ($validator->fails()) { if ($validator->fails()) {
Log::channel('audit')->error(sprintf('Validation errors in %s', __CLASS__), $validator->errors()->toArray()); Log::channel('audit')->error(sprintf('Validation errors in %s', self::class), $validator->errors()->toArray());
} }
} }
} }

View File

@@ -24,13 +24,15 @@ declare(strict_types=1);
namespace FireflyIII\Api\V1\Requests\Models\Bill; namespace FireflyIII\Api\V1\Requests\Models\Bill;
use Illuminate\Contracts\Validation\Validator;
use ValueError;
use TypeError;
use FireflyIII\Rules\IsBoolean; use FireflyIII\Rules\IsBoolean;
use FireflyIII\Rules\IsValidPositiveAmount; use FireflyIII\Rules\IsValidPositiveAmount;
use FireflyIII\Support\Request\ChecksLogin; use FireflyIII\Support\Request\ChecksLogin;
use FireflyIII\Support\Request\ConvertsDataTypes; use FireflyIII\Support\Request\ConvertsDataTypes;
use Illuminate\Foundation\Http\FormRequest; use Illuminate\Foundation\Http\FormRequest;
use Illuminate\Support\Facades\Log; use Illuminate\Support\Facades\Log;
use Illuminate\Validation\Validator;
/** /**
* Class StoreRequest * Class StoreRequest
@@ -109,7 +111,7 @@ class StoreRequest extends FormRequest
try { try {
$result = bccomp($min, $max); $result = bccomp($min, $max);
} catch (\ValueError $e) { } catch (ValueError $e) {
Log::error($e->getMessage()); Log::error($e->getMessage());
$validator->errors()->add('amount_min', (string) trans('validation.generic_invalid')); $validator->errors()->add('amount_min', (string) trans('validation.generic_invalid'));
$validator->errors()->add('amount_max', (string) trans('validation.generic_invalid')); $validator->errors()->add('amount_max', (string) trans('validation.generic_invalid'));
@@ -124,12 +126,12 @@ class StoreRequest extends FormRequest
try { try {
$failed = $validator->fails(); $failed = $validator->fails();
} catch (\TypeError $e) { } catch (TypeError $e) {
Log::error($e->getMessage()); Log::error($e->getMessage());
$failed = false; $failed = false;
} }
if ($failed) { if ($failed) {
Log::channel('audit')->error(sprintf('Validation errors in %s', __CLASS__), $validator->errors()->toArray()); Log::channel('audit')->error(sprintf('Validation errors in %s', self::class), $validator->errors()->toArray());
} }
} }
} }

View File

@@ -24,6 +24,7 @@ declare(strict_types=1);
namespace FireflyIII\Api\V1\Requests\Models\Bill; namespace FireflyIII\Api\V1\Requests\Models\Bill;
use Illuminate\Contracts\Validation\Validator;
use FireflyIII\Models\Bill; use FireflyIII\Models\Bill;
use FireflyIII\Rules\IsBoolean; use FireflyIII\Rules\IsBoolean;
use FireflyIII\Rules\IsValidPositiveAmount; use FireflyIII\Rules\IsValidPositiveAmount;
@@ -31,7 +32,6 @@ use FireflyIII\Support\Request\ChecksLogin;
use FireflyIII\Support\Request\ConvertsDataTypes; use FireflyIII\Support\Request\ConvertsDataTypes;
use Illuminate\Foundation\Http\FormRequest; use Illuminate\Foundation\Http\FormRequest;
use Illuminate\Support\Facades\Log; use Illuminate\Support\Facades\Log;
use Illuminate\Validation\Validator;
/** /**
* Class UpdateRequest * Class UpdateRequest
@@ -110,7 +110,7 @@ class UpdateRequest extends FormRequest
} }
); );
if ($validator->fails()) { if ($validator->fails()) {
Log::channel('audit')->error(sprintf('Validation errors in %s', __CLASS__), $validator->errors()->toArray()); Log::channel('audit')->error(sprintf('Validation errors in %s', self::class), $validator->errors()->toArray());
} }
} }
} }

View File

@@ -24,6 +24,7 @@ declare(strict_types=1);
namespace FireflyIII\Api\V1\Requests\Models\Budget; namespace FireflyIII\Api\V1\Requests\Models\Budget;
use Illuminate\Contracts\Validation\Validator;
use FireflyIII\Rules\IsBoolean; use FireflyIII\Rules\IsBoolean;
use FireflyIII\Rules\IsValidPositiveAmount; use FireflyIII\Rules\IsValidPositiveAmount;
use FireflyIII\Support\Request\ChecksLogin; use FireflyIII\Support\Request\ChecksLogin;
@@ -31,7 +32,6 @@ use FireflyIII\Support\Request\ConvertsDataTypes;
use FireflyIII\Validation\AutoBudget\ValidatesAutoBudgetRequest; use FireflyIII\Validation\AutoBudget\ValidatesAutoBudgetRequest;
use Illuminate\Foundation\Http\FormRequest; use Illuminate\Foundation\Http\FormRequest;
use Illuminate\Support\Facades\Log; use Illuminate\Support\Facades\Log;
use Illuminate\Validation\Validator;
/** /**
* Class StoreRequest * Class StoreRequest
@@ -94,7 +94,7 @@ class StoreRequest extends FormRequest
} }
); );
if ($validator->fails()) { if ($validator->fails()) {
Log::channel('audit')->error(sprintf('Validation errors in %s', __CLASS__), $validator->errors()->toArray()); Log::channel('audit')->error(sprintf('Validation errors in %s', self::class), $validator->errors()->toArray());
} }
} }
} }

View File

@@ -24,6 +24,7 @@ declare(strict_types=1);
namespace FireflyIII\Api\V1\Requests\Models\Budget; namespace FireflyIII\Api\V1\Requests\Models\Budget;
use Illuminate\Contracts\Validation\Validator;
use FireflyIII\Models\Budget; use FireflyIII\Models\Budget;
use FireflyIII\Rules\IsBoolean; use FireflyIII\Rules\IsBoolean;
use FireflyIII\Rules\IsValidPositiveAmount; use FireflyIII\Rules\IsValidPositiveAmount;
@@ -32,7 +33,6 @@ use FireflyIII\Support\Request\ConvertsDataTypes;
use FireflyIII\Validation\AutoBudget\ValidatesAutoBudgetRequest; use FireflyIII\Validation\AutoBudget\ValidatesAutoBudgetRequest;
use Illuminate\Foundation\Http\FormRequest; use Illuminate\Foundation\Http\FormRequest;
use Illuminate\Support\Facades\Log; use Illuminate\Support\Facades\Log;
use Illuminate\Validation\Validator;
/** /**
* Class UpdateRequest * Class UpdateRequest
@@ -106,7 +106,7 @@ class UpdateRequest extends FormRequest
} }
); );
if ($validator->fails()) { if ($validator->fails()) {
Log::channel('audit')->error(sprintf('Validation errors in %s', __CLASS__), $validator->errors()->toArray()); Log::channel('audit')->error(sprintf('Validation errors in %s', self::class), $validator->errors()->toArray());
} }
} }
} }

View File

@@ -24,13 +24,13 @@ declare(strict_types=1);
namespace FireflyIII\Api\V1\Requests\Models\BudgetLimit; namespace FireflyIII\Api\V1\Requests\Models\BudgetLimit;
use Illuminate\Contracts\Validation\Validator;
use Carbon\Carbon; use Carbon\Carbon;
use FireflyIII\Rules\IsValidPositiveAmount; use FireflyIII\Rules\IsValidPositiveAmount;
use FireflyIII\Support\Request\ChecksLogin; use FireflyIII\Support\Request\ChecksLogin;
use FireflyIII\Support\Request\ConvertsDataTypes; use FireflyIII\Support\Request\ConvertsDataTypes;
use Illuminate\Foundation\Http\FormRequest; use Illuminate\Foundation\Http\FormRequest;
use Illuminate\Support\Facades\Log; use Illuminate\Support\Facades\Log;
use Illuminate\Validation\Validator;
/** /**
* Class UpdateRequest * Class UpdateRequest
@@ -96,7 +96,7 @@ class UpdateRequest extends FormRequest
} }
); );
if ($validator->fails()) { if ($validator->fails()) {
Log::channel('audit')->error(sprintf('Validation errors in %s', __CLASS__), $validator->errors()->toArray()); Log::channel('audit')->error(sprintf('Validation errors in %s', self::class), $validator->errors()->toArray());
} }
} }
} }

View File

@@ -40,16 +40,16 @@ class StoreRequest extends FormRequest
return $this->getCarbonDate('date'); return $this->getCarbonDate('date');
} }
public function getRate(): string
{
return (string) $this->get('rate');
}
public function getFromCurrency(): TransactionCurrency public function getFromCurrency(): TransactionCurrency
{ {
return TransactionCurrency::where('code', $this->get('from'))->first(); return TransactionCurrency::where('code', $this->get('from'))->first();
} }
public function getRate(): string
{
return (string) $this->get('rate');
}
public function getToCurrency(): TransactionCurrency public function getToCurrency(): TransactionCurrency
{ {
return TransactionCurrency::where('code', $this->get('to'))->first(); return TransactionCurrency::where('code', $this->get('to'))->first();

View File

@@ -24,6 +24,7 @@ declare(strict_types=1);
namespace FireflyIII\Api\V1\Requests\Models\PiggyBank; namespace FireflyIII\Api\V1\Requests\Models\PiggyBank;
use Illuminate\Contracts\Validation\Validator;
use FireflyIII\Exceptions\FireflyException; use FireflyIII\Exceptions\FireflyException;
use FireflyIII\Models\TransactionCurrency; use FireflyIII\Models\TransactionCurrency;
use FireflyIII\Repositories\Account\AccountRepositoryInterface; use FireflyIII\Repositories\Account\AccountRepositoryInterface;
@@ -32,7 +33,6 @@ use FireflyIII\Support\Request\ChecksLogin;
use FireflyIII\Support\Request\ConvertsDataTypes; use FireflyIII\Support\Request\ConvertsDataTypes;
use Illuminate\Foundation\Http\FormRequest; use Illuminate\Foundation\Http\FormRequest;
use Illuminate\Support\Facades\Log; use Illuminate\Support\Facades\Log;
use Illuminate\Validation\Validator;
/** /**
* Class StoreRequest * Class StoreRequest
@@ -126,7 +126,7 @@ class StoreRequest extends FormRequest
} }
); );
if ($validator->fails()) { if ($validator->fails()) {
Log::channel('audit')->error(sprintf('Validation errors in %s', __CLASS__), $validator->errors()->toArray()); Log::channel('audit')->error(sprintf('Validation errors in %s', self::class), $validator->errors()->toArray());
} }
} }

View File

@@ -24,6 +24,7 @@ declare(strict_types=1);
namespace FireflyIII\Api\V1\Requests\Models\Recurrence; namespace FireflyIII\Api\V1\Requests\Models\Recurrence;
use Illuminate\Contracts\Validation\Validator;
use FireflyIII\Rules\BelongsUser; use FireflyIII\Rules\BelongsUser;
use FireflyIII\Rules\IsBoolean; use FireflyIII\Rules\IsBoolean;
use FireflyIII\Rules\IsValidPositiveAmount; use FireflyIII\Rules\IsValidPositiveAmount;
@@ -35,7 +36,6 @@ use FireflyIII\Validation\RecurrenceValidation;
use FireflyIII\Validation\TransactionValidation; use FireflyIII\Validation\TransactionValidation;
use Illuminate\Foundation\Http\FormRequest; use Illuminate\Foundation\Http\FormRequest;
use Illuminate\Support\Facades\Log; use Illuminate\Support\Facades\Log;
use Illuminate\Validation\Validator;
/** /**
* Class StoreRequest * Class StoreRequest
@@ -193,7 +193,7 @@ class StoreRequest extends FormRequest
} }
); );
if ($validator->fails()) { if ($validator->fails()) {
Log::channel('audit')->error(sprintf('Validation errors in %s', __CLASS__), $validator->errors()->toArray()); Log::channel('audit')->error(sprintf('Validation errors in %s', self::class), $validator->errors()->toArray());
} }
} }
} }

View File

@@ -24,6 +24,7 @@ declare(strict_types=1);
namespace FireflyIII\Api\V1\Requests\Models\Recurrence; namespace FireflyIII\Api\V1\Requests\Models\Recurrence;
use Illuminate\Contracts\Validation\Validator;
use FireflyIII\Models\Recurrence; use FireflyIII\Models\Recurrence;
use FireflyIII\Rules\BelongsUser; use FireflyIII\Rules\BelongsUser;
use FireflyIII\Rules\IsBoolean; use FireflyIII\Rules\IsBoolean;
@@ -36,7 +37,6 @@ use FireflyIII\Validation\RecurrenceValidation;
use FireflyIII\Validation\TransactionValidation; use FireflyIII\Validation\TransactionValidation;
use Illuminate\Foundation\Http\FormRequest; use Illuminate\Foundation\Http\FormRequest;
use Illuminate\Support\Facades\Log; use Illuminate\Support\Facades\Log;
use Illuminate\Validation\Validator;
/** /**
* Class UpdateRequest * Class UpdateRequest
@@ -208,7 +208,7 @@ class UpdateRequest extends FormRequest
} }
); );
if ($validator->fails()) { if ($validator->fails()) {
Log::channel('audit')->error(sprintf('Validation errors in %s', __CLASS__), $validator->errors()->toArray()); Log::channel('audit')->error(sprintf('Validation errors in %s', self::class), $validator->errors()->toArray());
} }
} }
} }

View File

@@ -24,6 +24,7 @@ declare(strict_types=1);
namespace FireflyIII\Api\V1\Requests\Models\Rule; namespace FireflyIII\Api\V1\Requests\Models\Rule;
use Illuminate\Contracts\Validation\Validator;
use FireflyIII\Rules\IsBoolean; use FireflyIII\Rules\IsBoolean;
use FireflyIII\Rules\IsValidActionExpression; use FireflyIII\Rules\IsValidActionExpression;
use FireflyIII\Support\Request\ChecksLogin; use FireflyIII\Support\Request\ChecksLogin;
@@ -31,7 +32,6 @@ use FireflyIII\Support\Request\ConvertsDataTypes;
use FireflyIII\Support\Request\GetRuleConfiguration; use FireflyIII\Support\Request\GetRuleConfiguration;
use Illuminate\Foundation\Http\FormRequest; use Illuminate\Foundation\Http\FormRequest;
use Illuminate\Support\Facades\Log; use Illuminate\Support\Facades\Log;
use Illuminate\Validation\Validator;
/** /**
* Class StoreRequest * Class StoreRequest
@@ -148,7 +148,7 @@ class StoreRequest extends FormRequest
} }
); );
if ($validator->fails()) { if ($validator->fails()) {
Log::channel('audit')->error(sprintf('Validation errors in %s', __CLASS__), $validator->errors()->toArray()); Log::channel('audit')->error(sprintf('Validation errors in %s', self::class), $validator->errors()->toArray());
} }
} }

View File

@@ -24,6 +24,7 @@ declare(strict_types=1);
namespace FireflyIII\Api\V1\Requests\Models\Rule; namespace FireflyIII\Api\V1\Requests\Models\Rule;
use Illuminate\Contracts\Validation\Validator;
use FireflyIII\Models\Rule; use FireflyIII\Models\Rule;
use FireflyIII\Rules\IsBoolean; use FireflyIII\Rules\IsBoolean;
use FireflyIII\Rules\IsValidActionExpression; use FireflyIII\Rules\IsValidActionExpression;
@@ -32,7 +33,6 @@ use FireflyIII\Support\Request\ConvertsDataTypes;
use FireflyIII\Support\Request\GetRuleConfiguration; use FireflyIII\Support\Request\GetRuleConfiguration;
use Illuminate\Foundation\Http\FormRequest; use Illuminate\Foundation\Http\FormRequest;
use Illuminate\Support\Facades\Log; use Illuminate\Support\Facades\Log;
use Illuminate\Validation\Validator;
/** /**
* Class UpdateRequest * Class UpdateRequest
@@ -168,7 +168,7 @@ class UpdateRequest extends FormRequest
} }
); );
if ($validator->fails()) { if ($validator->fails()) {
Log::channel('audit')->error(sprintf('Validation errors in %s', __CLASS__), $validator->errors()->toArray()); Log::channel('audit')->error(sprintf('Validation errors in %s', self::class), $validator->errors()->toArray());
} }
} }

View File

@@ -24,6 +24,7 @@ declare(strict_types=1);
namespace FireflyIII\Api\V1\Requests\Models\Transaction; namespace FireflyIII\Api\V1\Requests\Models\Transaction;
use Illuminate\Contracts\Validation\Validator;
use FireflyIII\Models\Location; use FireflyIII\Models\Location;
use FireflyIII\Rules\BelongsUser; use FireflyIII\Rules\BelongsUser;
use FireflyIII\Rules\IsBoolean; use FireflyIII\Rules\IsBoolean;
@@ -39,7 +40,6 @@ use FireflyIII\Validation\GroupValidation;
use FireflyIII\Validation\TransactionValidation; use FireflyIII\Validation\TransactionValidation;
use Illuminate\Foundation\Http\FormRequest; use Illuminate\Foundation\Http\FormRequest;
use Illuminate\Support\Facades\Log; use Illuminate\Support\Facades\Log;
use Illuminate\Validation\Validator;
/** /**
* Class StoreRequest * Class StoreRequest
@@ -300,7 +300,7 @@ class StoreRequest extends FormRequest
} }
); );
if ($validator->fails()) { if ($validator->fails()) {
Log::channel('audit')->error(sprintf('Validation errors in %s', __CLASS__), $validator->errors()->toArray()); Log::channel('audit')->error(sprintf('Validation errors in %s', self::class), $validator->errors()->toArray());
} }
} }
} }

View File

@@ -24,6 +24,7 @@ declare(strict_types=1);
namespace FireflyIII\Api\V1\Requests\Models\Transaction; namespace FireflyIII\Api\V1\Requests\Models\Transaction;
use Illuminate\Contracts\Validation\Validator;
use FireflyIII\Exceptions\FireflyException; use FireflyIII\Exceptions\FireflyException;
use FireflyIII\Models\TransactionGroup; use FireflyIII\Models\TransactionGroup;
use FireflyIII\Rules\BelongsUser; use FireflyIII\Rules\BelongsUser;
@@ -37,7 +38,6 @@ use FireflyIII\Validation\GroupValidation;
use FireflyIII\Validation\TransactionValidation; use FireflyIII\Validation\TransactionValidation;
use Illuminate\Foundation\Http\FormRequest; use Illuminate\Foundation\Http\FormRequest;
use Illuminate\Support\Facades\Log; use Illuminate\Support\Facades\Log;
use Illuminate\Validation\Validator;
/** /**
* Class UpdateRequest * Class UpdateRequest
@@ -359,7 +359,7 @@ class UpdateRequest extends FormRequest
} }
); );
if ($validator->fails()) { if ($validator->fails()) {
Log::channel('audit')->error(sprintf('Validation errors in %s', __CLASS__), $validator->errors()->toArray()); Log::channel('audit')->error(sprintf('Validation errors in %s', self::class), $validator->errors()->toArray());
} }
} }
} }

View File

@@ -24,6 +24,7 @@ declare(strict_types=1);
namespace FireflyIII\Api\V1\Requests\Models\TransactionLink; namespace FireflyIII\Api\V1\Requests\Models\TransactionLink;
use Illuminate\Contracts\Validation\Validator;
use FireflyIII\Repositories\Journal\JournalRepositoryInterface; use FireflyIII\Repositories\Journal\JournalRepositoryInterface;
use FireflyIII\Repositories\LinkType\LinkTypeRepositoryInterface; use FireflyIII\Repositories\LinkType\LinkTypeRepositoryInterface;
use FireflyIII\Support\Request\ChecksLogin; use FireflyIII\Support\Request\ChecksLogin;
@@ -31,7 +32,6 @@ use FireflyIII\Support\Request\ConvertsDataTypes;
use FireflyIII\User; use FireflyIII\User;
use Illuminate\Foundation\Http\FormRequest; use Illuminate\Foundation\Http\FormRequest;
use Illuminate\Support\Facades\Log; use Illuminate\Support\Facades\Log;
use Illuminate\Validation\Validator;
/** /**
* Class StoreRequest * Class StoreRequest
@@ -80,7 +80,7 @@ class StoreRequest extends FormRequest
} }
); );
if ($validator->fails()) { if ($validator->fails()) {
Log::channel('audit')->error(sprintf('Validation errors in %s', __CLASS__), $validator->errors()->toArray()); Log::channel('audit')->error(sprintf('Validation errors in %s', self::class), $validator->errors()->toArray());
} }
} }

View File

@@ -24,6 +24,7 @@ declare(strict_types=1);
namespace FireflyIII\Api\V1\Requests\Models\TransactionLink; namespace FireflyIII\Api\V1\Requests\Models\TransactionLink;
use Illuminate\Contracts\Validation\Validator;
use FireflyIII\Models\TransactionJournalLink; use FireflyIII\Models\TransactionJournalLink;
use FireflyIII\Repositories\Journal\JournalRepositoryInterface; use FireflyIII\Repositories\Journal\JournalRepositoryInterface;
use FireflyIII\Repositories\LinkType\LinkTypeRepositoryInterface; use FireflyIII\Repositories\LinkType\LinkTypeRepositoryInterface;
@@ -31,7 +32,6 @@ use FireflyIII\Support\Request\ChecksLogin;
use FireflyIII\Support\Request\ConvertsDataTypes; use FireflyIII\Support\Request\ConvertsDataTypes;
use Illuminate\Foundation\Http\FormRequest; use Illuminate\Foundation\Http\FormRequest;
use Illuminate\Support\Facades\Log; use Illuminate\Support\Facades\Log;
use Illuminate\Validation\Validator;
/** /**
* Class UpdateRequest * Class UpdateRequest
@@ -80,7 +80,7 @@ class UpdateRequest extends FormRequest
} }
); );
if ($validator->fails()) { if ($validator->fails()) {
Log::channel('audit')->error(sprintf('Validation errors in %s', __CLASS__), $validator->errors()->toArray()); Log::channel('audit')->error(sprintf('Validation errors in %s', self::class), $validator->errors()->toArray());
} }
} }

View File

@@ -24,6 +24,7 @@ declare(strict_types=1);
namespace FireflyIII\Api\V1\Requests\System; namespace FireflyIII\Api\V1\Requests\System;
use Carbon\Carbon;
use FireflyIII\Support\Request\ConvertsDataTypes; use FireflyIII\Support\Request\ConvertsDataTypes;
use Illuminate\Foundation\Http\FormRequest; use Illuminate\Foundation\Http\FormRequest;
@@ -58,7 +59,7 @@ class CronRequest extends FormRequest
$data['date'] = $this->getCarbonDate('date'); $data['date'] = $this->getCarbonDate('date');
} }
// catch NULL. // catch NULL.
if (null === $data['date']) { if (!$data['date'] instanceof Carbon) {
$data['date'] = today(config('app.timezone')); $data['date'] = today(config('app.timezone'));
} }

View File

@@ -24,13 +24,13 @@ declare(strict_types=1);
namespace FireflyIII\Api\V1\Requests\System; namespace FireflyIII\Api\V1\Requests\System;
use Illuminate\Contracts\Validation\Validator;
use FireflyIII\Rules\IsBoolean; use FireflyIII\Rules\IsBoolean;
use FireflyIII\Support\Request\ChecksLogin; use FireflyIII\Support\Request\ChecksLogin;
use FireflyIII\Support\Request\ConvertsDataTypes; use FireflyIII\Support\Request\ConvertsDataTypes;
use FireflyIII\User; use FireflyIII\User;
use Illuminate\Foundation\Http\FormRequest; use Illuminate\Foundation\Http\FormRequest;
use Illuminate\Support\Facades\Log; use Illuminate\Support\Facades\Log;
use Illuminate\Validation\Validator;
/** /**
* Class UserUpdateRequest * Class UserUpdateRequest
@@ -99,7 +99,7 @@ class UserUpdateRequest extends FormRequest
} }
); );
if ($validator->fails()) { if ($validator->fails()) {
Log::channel('audit')->error(sprintf('Validation errors in %s', __CLASS__), $validator->errors()->toArray()); Log::channel('audit')->error(sprintf('Validation errors in %s', self::class), $validator->errors()->toArray());
} }
} }
} }

View File

@@ -90,7 +90,7 @@ class AccountController extends Controller
'meta' => [ 'meta' => [
'type' => $account->accountType->type, 'type' => $account->accountType->type,
// TODO is multi currency property. // TODO is multi currency property.
'currency_id' => null === $currency ? null : (string) $currency->id, 'currency_id' => $currency instanceof TransactionCurrency ? (string) $currency->id : null,
'currency_code' => $currency?->code, 'currency_code' => $currency?->code,
'currency_symbol' => $currency?->symbol, 'currency_symbol' => $currency?->symbol,
'currency_decimal_places' => $currency?->decimal_places, 'currency_decimal_places' => $currency?->decimal_places,

View File

@@ -61,13 +61,11 @@ class CategoryController extends Controller
$queryParameters = $request->getParameters(); $queryParameters = $request->getParameters();
$result = $this->repository->searchCategory($queryParameters['query'], $queryParameters['size']); $result = $this->repository->searchCategory($queryParameters['query'], $queryParameters['size']);
$filtered = $result->map( $filtered = $result->map(
static function (Category $item) { static fn (Category $item) => [
return [
'id' => (string) $item->id, 'id' => (string) $item->id,
'title' => $item->name, 'title' => $item->name,
'meta' => [], 'meta' => [],
]; ]
}
); );
return response()->json($filtered); return response()->json($filtered);

View File

@@ -61,15 +61,13 @@ class TagController extends Controller
$queryParameters = $request->getParameters(); $queryParameters = $request->getParameters();
$result = $this->repository->searchTag($queryParameters['query']); $result = $this->repository->searchTag($queryParameters['query']);
$filtered = $result->map( $filtered = $result->map(
static function (Tag $item) { static fn (Tag $item) => [
return [
'id' => (string) $item->id, 'id' => (string) $item->id,
'title' => $item->tag, 'title' => $item->tag,
'value' => (string) $item->id, 'value' => (string) $item->id,
'label' => $item->tag, 'label' => $item->tag,
'meta' => [], 'meta' => [],
]; ]
}
); );
return response()->json($filtered); return response()->json($filtered);

View File

@@ -94,7 +94,7 @@ class AccountController extends Controller
private function renderAccountData(array $params, Account $account): void private function renderAccountData(array $params, Account $account): void
{ {
$currency = $this->repository->getAccountCurrency($account); $currency = $this->repository->getAccountCurrency($account);
if (null === $currency) { if (!$currency instanceof TransactionCurrency) {
$currency = $this->default; $currency = $this->default;
} }
$currentSet = [ $currentSet = [

View File

@@ -212,13 +212,13 @@ class BudgetController extends Controller
foreach ($currentBudgetArray['transaction_journals'] as $journal) { foreach ($currentBudgetArray['transaction_journals'] as $journal) {
// convert the amount to the native currency. // convert the amount to the native currency.
$rate = $converter->getCurrencyRate($this->currencies[$currencyId], $this->currency, $journal['date']); $rate = $converter->getCurrencyRate($this->currencies[$currencyId], $this->currency, $journal['date']);
$convertedAmount = bcmul($journal['amount'], $rate); $convertedAmount = bcmul((string) $journal['amount'], $rate);
if ($journal['foreign_currency_id'] === $this->currency->id) { if ($journal['foreign_currency_id'] === $this->currency->id) {
$convertedAmount = $journal['foreign_amount']; $convertedAmount = $journal['foreign_amount'];
} }
$return[$currencyId]['spent'] = bcadd($return[$currencyId]['spent'], $journal['amount']); $return[$currencyId]['spent'] = bcadd($return[$currencyId]['spent'], (string) $journal['amount']);
$return[$currencyId]['native_spent'] = bcadd($return[$currencyId]['native_spent'], $convertedAmount); $return[$currencyId]['native_spent'] = bcadd($return[$currencyId]['native_spent'], (string) $convertedAmount);
} }
} }
$converter->summarize(); $converter->summarize();
@@ -275,15 +275,15 @@ class BudgetController extends Controller
} }
$result = $this->processExpenses($budget->id, $filtered, $limit->start_date, $end); $result = $this->processExpenses($budget->id, $filtered, $limit->start_date, $end);
if (1 === count($result)) { if (1 === count($result)) {
$compare = bccomp($limit->amount, app('steam')->positive($result[$limitCurrencyId]['spent'])); $compare = bccomp($limit->amount, (string) app('steam')->positive($result[$limitCurrencyId]['spent']));
if (1 === $compare) { if (1 === $compare) {
// convert this amount into the native currency: // convert this amount into the native currency:
$result[$limitCurrencyId]['left'] = bcadd($limit->amount, $result[$limitCurrencyId]['spent']); $result[$limitCurrencyId]['left'] = bcadd($limit->amount, (string) $result[$limitCurrencyId]['spent']);
$result[$limitCurrencyId]['native_left'] = bcadd($convertedLimitAmount, $result[$limitCurrencyId]['native_spent']); $result[$limitCurrencyId]['native_left'] = bcadd($convertedLimitAmount, (string) $result[$limitCurrencyId]['native_spent']);
} }
if ($compare <= 0) { if ($compare <= 0) {
$result[$limitCurrencyId]['overspent'] = app('steam')->positive(bcadd($limit->amount, $result[$limitCurrencyId]['spent'])); $result[$limitCurrencyId]['overspent'] = app('steam')->positive(bcadd($limit->amount, (string) $result[$limitCurrencyId]['spent']));
$result[$limitCurrencyId]['native_overspent'] = app('steam')->positive(bcadd($convertedLimitAmount, $result[$limitCurrencyId]['native_spent'])); $result[$limitCurrencyId]['native_overspent'] = app('steam')->positive(bcadd($convertedLimitAmount, (string) $result[$limitCurrencyId]['native_spent']));
} }
} }
$converter->summarize(); $converter->summarize();

View File

@@ -100,7 +100,7 @@ class CategoryController extends Controller
$currencyId = (int) $journal['currency_id']; $currencyId = (int) $journal['currency_id'];
$currency = $currencies[$currencyId] ?? $this->currencyRepos->find($currencyId); $currency = $currencies[$currencyId] ?? $this->currencyRepos->find($currencyId);
$currencies[$currencyId] = $currency; $currencies[$currencyId] = $currency;
$categoryName = null === $journal['category_name'] ? (string) trans('firefly.no_category') : $journal['category_name']; $categoryName = $journal['category_name'] ?? (string) trans('firefly.no_category');
$amount = app('steam')->positive($journal['amount']); $amount = app('steam')->positive($journal['amount']);
$nativeAmount = $converter->convert($default, $currency, $journal['date'], $amount); $nativeAmount = $converter->convert($default, $currency, $journal['date'], $amount);
$key = sprintf('%s-%s', $categoryName, $currency->code); $key = sprintf('%s-%s', $categoryName, $currency->code);
@@ -128,15 +128,13 @@ class CategoryController extends Controller
]; ];
// add monies // add monies
$return[$key]['amount'] = bcadd($return[$key]['amount'], $amount); $return[$key]['amount'] = bcadd($return[$key]['amount'], (string) $amount);
$return[$key]['native_amount'] = bcadd($return[$key]['native_amount'], $nativeAmount); $return[$key]['native_amount'] = bcadd($return[$key]['native_amount'], (string) $nativeAmount);
} }
$return = array_values($return); $return = array_values($return);
// order by native amount // order by native amount
usort($return, static function (array $a, array $b) { usort($return, static fn (array $a, array $b) => (float) $a['native_amount'] < (float) $b['native_amount'] ? 1 : -1);
return (float) $a['native_amount'] < (float) $b['native_amount'] ? 1 : -1;
});
$converter->summarize(); $converter->summarize();
return response()->json($this->clean($return)); return response()->json($this->clean($return));

View File

@@ -33,7 +33,6 @@ use FireflyIII\Transformers\AbstractTransformer;
use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\Model;
use Illuminate\Pagination\LengthAwarePaginator; use Illuminate\Pagination\LengthAwarePaginator;
use Illuminate\Routing\Controller as BaseController; use Illuminate\Routing\Controller as BaseController;
use Illuminate\Support\Collection;
use League\Fractal\Manager; use League\Fractal\Manager;
use League\Fractal\Pagination\IlluminatePaginatorAdapter; use League\Fractal\Pagination\IlluminatePaginatorAdapter;
use League\Fractal\Resource\Collection as FractalCollection; use League\Fractal\Resource\Collection as FractalCollection;
@@ -56,8 +55,8 @@ class Controller extends BaseController
protected const string CONTENT_TYPE = 'application/vnd.api+json'; protected const string CONTENT_TYPE = 'application/vnd.api+json';
protected array $acceptedRoles = [UserRoleEnum::READ_ONLY]; protected array $acceptedRoles = [UserRoleEnum::READ_ONLY];
protected ParameterBag $parameters;
protected bool $convertToNative = false; protected bool $convertToNative = false;
protected ParameterBag $parameters;
public function __construct() public function __construct()
{ {
@@ -118,7 +117,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())); 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. // out of range? set to null.
if (null !== $obj && ($obj->year <= 1900 || $obj->year > 2099)) { if ($obj instanceof Carbon && ($obj->year <= 1900 || $obj->year > 2099)) {
app('log')->warning(sprintf('Refuse to use date "%s" in API v2 controller parameter check: %s', $field, $obj->toAtomString())); app('log')->warning(sprintf('Refuse to use date "%s" in API v2 controller parameter check: %s', $field, $obj->toAtomString()));
$obj = null; $obj = null;
} }

View File

@@ -69,8 +69,9 @@ class UpdateController extends Controller
$transactionGroup = $this->groupRepository->update($transactionGroup, $data); $transactionGroup = $this->groupRepository->update($transactionGroup, $data);
$applyRules = $data['apply_rules'] ?? true; $applyRules = $data['apply_rules'] ?? true;
$fireWebhooks = $data['fire_webhooks'] ?? true; $fireWebhooks = $data['fire_webhooks'] ?? true;
$runRecalculations = true;
event(new UpdatedTransactionGroup($transactionGroup, $applyRules, $fireWebhooks)); event(new UpdatedTransactionGroup($transactionGroup, $applyRules, $fireWebhooks, $runRecalculations));
app('preferences')->mark(); app('preferences')->mark();
/** @var User $admin */ /** @var User $admin */

View File

@@ -24,6 +24,7 @@ declare(strict_types=1);
namespace FireflyIII\Api\V2\Controllers\Summary; namespace FireflyIII\Api\V2\Controllers\Summary;
use Exception;
use Carbon\Carbon; use Carbon\Carbon;
use FireflyIII\Api\V2\Controllers\Controller; use FireflyIII\Api\V2\Controllers\Controller;
use FireflyIII\Api\V2\Request\Generic\DateRequest; use FireflyIII\Api\V2\Request\Generic\DateRequest;
@@ -92,7 +93,7 @@ class BasicController extends Controller
* This endpoint is documented at: * This endpoint is documented at:
* https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v2)#/summary/getBasicSummary * https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v2)#/summary/getBasicSummary
* *
* @throws \Exception * @throws Exception
* *
* @SuppressWarnings("PHPMD.UnusedFormalParameter") * @SuppressWarnings("PHPMD.UnusedFormalParameter")
*/ */
@@ -174,8 +175,8 @@ class BasicController extends Controller
* @var array $info * @var array $info
*/ */
foreach ($paidAmount as $info) { foreach ($paidAmount as $info) {
$amount = bcmul($info['sum'], '-1'); $amount = bcmul((string) $info['sum'], '-1');
$nativeAmount = bcmul($info['native_sum'], '-1'); $nativeAmount = bcmul((string) $info['native_sum'], '-1');
$return[] = [ $return[] = [
'key' => sprintf('bills-paid-in-%s', $info['currency_code']), 'key' => sprintf('bills-paid-in-%s', $info['currency_code']),
'value' => $amount, 'value' => $amount,
@@ -198,8 +199,8 @@ class BasicController extends Controller
* @var array $info * @var array $info
*/ */
foreach ($unpaidAmount as $info) { foreach ($unpaidAmount as $info) {
$amount = bcmul($info['sum'], '-1'); $amount = bcmul((string) $info['sum'], '-1');
$nativeAmount = bcmul($info['native_sum'], '-1'); $nativeAmount = bcmul((string) $info['native_sum'], '-1');
$return[] = [ $return[] = [
'key' => sprintf('bills-unpaid-in-%s', $info['currency_code']), 'key' => sprintf('bills-unpaid-in-%s', $info['currency_code']),
'value' => $amount, 'value' => $amount,
@@ -279,8 +280,8 @@ class BasicController extends Controller
if ((int) $journal['foreign_currency_id'] === $default->id) { if ((int) $journal['foreign_currency_id'] === $default->id) {
$amountNative = $journal['foreign_amount']; $amountNative = $journal['foreign_amount'];
} }
$spent = bcadd($spent, $amount); $spent = bcadd($spent, (string) $amount);
$spentNative = bcadd($spentNative, $amountNative); $spentNative = bcadd($spentNative, (string) $amountNative);
} }
app('log')->debug(sprintf('Total spent in budget "%s" is %s', $budget['name'], $spent)); app('log')->debug(sprintf('Total spent in budget "%s" is %s', $budget['name'], $spent));
} }
@@ -398,15 +399,14 @@ class BasicController extends Controller
*/ */
protected function notInDateRange(Carbon $date, Carbon $start, Carbon $end): bool // Validate a preference protected function notInDateRange(Carbon $date, Carbon $start, Carbon $end): bool // Validate a preference
{ {
$result = false;
if ($start->greaterThanOrEqualTo($date) && $end->greaterThanOrEqualTo($date)) { if ($start->greaterThanOrEqualTo($date) && $end->greaterThanOrEqualTo($date)) {
$result = true; return true;
} }
// start and end in the past? use $end // start and end in the past? use $end
if ($start->lessThanOrEqualTo($date) && $end->lessThanOrEqualTo($date)) { if ($start->lessThanOrEqualTo($date) && $end->lessThanOrEqualTo($date)) {
$result = true; return true;
} }
return $result; return false;
} }
} }

View File

@@ -24,6 +24,7 @@ declare(strict_types=1);
namespace FireflyIII\Api\V2\Controllers\Transaction\List; namespace FireflyIII\Api\V2\Controllers\Transaction\List;
use Carbon\Carbon;
use FireflyIII\Api\V2\Controllers\Controller; use FireflyIII\Api\V2\Controllers\Controller;
use FireflyIII\Api\V2\Request\Model\Transaction\ListRequest; use FireflyIII\Api\V2\Request\Model\Transaction\ListRequest;
use FireflyIII\Helpers\Collector\GroupCollectorInterface; use FireflyIII\Helpers\Collector\GroupCollectorInterface;
@@ -62,11 +63,11 @@ class AccountController extends Controller
$start = $request->getStartDate(); $start = $request->getStartDate();
$end = $request->getEndDate(); $end = $request->getEndDate();
if (null !== $start) { if ($start instanceof Carbon) {
app('log')->debug(sprintf('Set start date to %s', $start->toIso8601String())); app('log')->debug(sprintf('Set start date to %s', $start->toIso8601String()));
$collector->setStart($start); $collector->setStart($start);
} }
if (null !== $end) { if ($end instanceof Carbon) {
app('log')->debug(sprintf('Set end date to %s', $start->toIso8601String())); app('log')->debug(sprintf('Set end date to %s', $start->toIso8601String()));
$collector->setEnd($end); $collector->setEnd($end);
} }

View File

@@ -24,13 +24,13 @@ declare(strict_types=1);
namespace FireflyIII\Api\V2\Request\Chart; namespace FireflyIII\Api\V2\Request\Chart;
use Illuminate\Contracts\Validation\Validator;
use FireflyIII\Enums\UserRoleEnum; use FireflyIII\Enums\UserRoleEnum;
use FireflyIII\Support\Http\Api\ValidatesUserGroupTrait; use FireflyIII\Support\Http\Api\ValidatesUserGroupTrait;
use FireflyIII\Support\Request\ChecksLogin; use FireflyIII\Support\Request\ChecksLogin;
use FireflyIII\Support\Request\ConvertsDataTypes; use FireflyIII\Support\Request\ConvertsDataTypes;
use Illuminate\Foundation\Http\FormRequest; use Illuminate\Foundation\Http\FormRequest;
use Illuminate\Support\Facades\Log; use Illuminate\Support\Facades\Log;
use Illuminate\Validation\Validator;
/** /**
* Class BalanceChartRequest * Class BalanceChartRequest
@@ -84,7 +84,7 @@ class BalanceChartRequest extends FormRequest
} }
); );
if ($validator->fails()) { if ($validator->fails()) {
Log::channel('audit')->error(sprintf('Validation errors in %s', __CLASS__), $validator->errors()->toArray()); Log::channel('audit')->error(sprintf('Validation errors in %s', self::class), $validator->errors()->toArray());
} }
} }
} }

View File

@@ -24,13 +24,13 @@ declare(strict_types=1);
namespace FireflyIII\Api\V2\Request\Chart; namespace FireflyIII\Api\V2\Request\Chart;
use Illuminate\Contracts\Validation\Validator;
use FireflyIII\Enums\UserRoleEnum; use FireflyIII\Enums\UserRoleEnum;
use FireflyIII\Support\Http\Api\ValidatesUserGroupTrait; use FireflyIII\Support\Http\Api\ValidatesUserGroupTrait;
use FireflyIII\Support\Request\ChecksLogin; use FireflyIII\Support\Request\ChecksLogin;
use FireflyIII\Support\Request\ConvertsDataTypes; use FireflyIII\Support\Request\ConvertsDataTypes;
use Illuminate\Foundation\Http\FormRequest; use Illuminate\Foundation\Http\FormRequest;
use Illuminate\Support\Facades\Log; use Illuminate\Support\Facades\Log;
use Illuminate\Validation\Validator;
/** /**
* Class ChartRequest * Class ChartRequest
@@ -86,7 +86,7 @@ class ChartRequest extends FormRequest
} }
); );
if ($validator->fails()) { if ($validator->fails()) {
Log::channel('audit')->error(sprintf('Validation errors in %s', __CLASS__), $validator->errors()->toArray()); Log::channel('audit')->error(sprintf('Validation errors in %s', self::class), $validator->errors()->toArray());
} }
} }
} }

View File

@@ -24,13 +24,13 @@ declare(strict_types=1);
namespace FireflyIII\Api\V2\Request\Chart; namespace FireflyIII\Api\V2\Request\Chart;
use Illuminate\Contracts\Validation\Validator;
use FireflyIII\Enums\UserRoleEnum; use FireflyIII\Enums\UserRoleEnum;
use FireflyIII\Support\Http\Api\ValidatesUserGroupTrait; use FireflyIII\Support\Http\Api\ValidatesUserGroupTrait;
use FireflyIII\Support\Request\ChecksLogin; use FireflyIII\Support\Request\ChecksLogin;
use FireflyIII\Support\Request\ConvertsDataTypes; use FireflyIII\Support\Request\ConvertsDataTypes;
use Illuminate\Foundation\Http\FormRequest; use Illuminate\Foundation\Http\FormRequest;
use Illuminate\Support\Facades\Log; use Illuminate\Support\Facades\Log;
use Illuminate\Validation\Validator;
/** /**
* Class DashboardChartRequest * Class DashboardChartRequest
@@ -83,7 +83,7 @@ class DashboardChartRequest extends FormRequest
} }
); );
if ($validator->fails()) { if ($validator->fails()) {
Log::channel('audit')->error(sprintf('Validation errors in %s', __CLASS__), $validator->errors()->toArray()); Log::channel('audit')->error(sprintf('Validation errors in %s', self::class), $validator->errors()->toArray());
} }
} }
} }

View File

@@ -53,7 +53,7 @@ class InfiniteListRequest extends FormRequest
$start = $this->getStartDate(); $start = $this->getStartDate();
$end = $this->getEndDate(); $end = $this->getEndDate();
if (null !== $start && null !== $end) { if ($start instanceof Carbon && $end instanceof Carbon) {
$array['start'] = $start->format('Y-m-d'); $array['start'] = $start->format('Y-m-d');
$array['end'] = $end->format('Y-m-d'); $array['end'] = $end->format('Y-m-d');
} }

View File

@@ -49,7 +49,7 @@ class ListRequest extends FormRequest
$start = $this->getStartDate(); $start = $this->getStartDate();
$end = $this->getEndDate(); $end = $this->getEndDate();
if (null !== $start && null !== $end) { if ($start instanceof Carbon && $end instanceof Carbon) {
$array['start'] = $start->format('Y-m-d'); $array['start'] = $start->format('Y-m-d');
$array['end'] = $end->format('Y-m-d'); $array['end'] = $end->format('Y-m-d');
} }

View File

@@ -24,6 +24,7 @@ declare(strict_types=1);
namespace FireflyIII\Api\V2\Request\Model\Transaction; namespace FireflyIII\Api\V2\Request\Model\Transaction;
use Illuminate\Contracts\Validation\Validator;
use FireflyIII\Enums\UserRoleEnum; use FireflyIII\Enums\UserRoleEnum;
use FireflyIII\Models\UserGroup; use FireflyIII\Models\UserGroup;
use FireflyIII\Rules\BelongsUserGroup; use FireflyIII\Rules\BelongsUserGroup;
@@ -40,7 +41,6 @@ use FireflyIII\Validation\GroupValidation;
use FireflyIII\Validation\TransactionValidation; use FireflyIII\Validation\TransactionValidation;
use Illuminate\Foundation\Http\FormRequest; use Illuminate\Foundation\Http\FormRequest;
use Illuminate\Support\Facades\Log; use Illuminate\Support\Facades\Log;
use Illuminate\Validation\Validator;
/** /**
* Class StoreRequest * Class StoreRequest
@@ -311,7 +311,7 @@ class StoreRequest extends FormRequest
} }
); );
if ($validator->fails()) { if ($validator->fails()) {
Log::channel('audit')->error(sprintf('Validation errors in %s', __CLASS__), $validator->errors()->toArray()); Log::channel('audit')->error(sprintf('Validation errors in %s', self::class), $validator->errors()->toArray());
} }
} }
} }

View File

@@ -24,6 +24,8 @@ declare(strict_types=1);
namespace FireflyIII\Api\V2\Request\Model\Transaction; namespace FireflyIII\Api\V2\Request\Model\Transaction;
use Illuminate\Contracts\Validation\Validator;
use Override;
use FireflyIII\Api\V1\Requests\Models\AvailableBudget\Request; use FireflyIII\Api\V1\Requests\Models\AvailableBudget\Request;
use FireflyIII\Exceptions\FireflyException; use FireflyIII\Exceptions\FireflyException;
use FireflyIII\Models\TransactionGroup; use FireflyIII\Models\TransactionGroup;
@@ -37,7 +39,6 @@ use FireflyIII\Support\Request\ConvertsDataTypes;
use FireflyIII\Validation\GroupValidation; use FireflyIII\Validation\GroupValidation;
use FireflyIII\Validation\TransactionValidation; use FireflyIII\Validation\TransactionValidation;
use Illuminate\Support\Facades\Log; use Illuminate\Support\Facades\Log;
use Illuminate\Validation\Validator;
/** /**
* Class UpdateRequest * Class UpdateRequest
@@ -64,6 +65,7 @@ class UpdateRequest extends Request
* *
* @throws FireflyException * @throws FireflyException
*/ */
#[Override]
public function getAll(): array public function getAll(): array
{ {
app('log')->debug(sprintf('Now in %s', __METHOD__)); app('log')->debug(sprintf('Now in %s', __METHOD__));
@@ -247,6 +249,7 @@ class UpdateRequest extends Request
/** /**
* The rules that the incoming request must be matched against. * The rules that the incoming request must be matched against.
*/ */
#[Override]
public function rules(): array public function rules(): array
{ {
app('log')->debug(sprintf('Now in %s', __METHOD__)); app('log')->debug(sprintf('Now in %s', __METHOD__));
@@ -330,6 +333,7 @@ class UpdateRequest extends Request
/** /**
* Configure the validator instance. * Configure the validator instance.
*/ */
#[Override]
public function withValidator(Validator $validator): void public function withValidator(Validator $validator): void
{ {
app('log')->debug('Now in withValidator'); app('log')->debug('Now in withValidator');
@@ -361,7 +365,7 @@ class UpdateRequest extends Request
} }
); );
if ($validator->fails()) { if ($validator->fails()) {
Log::channel('audit')->error(sprintf('Validation errors in %s', __CLASS__), $validator->errors()->toArray()); Log::channel('audit')->error(sprintf('Validation errors in %s', self::class), $validator->errors()->toArray());
} }
} }
} }

View File

@@ -24,6 +24,7 @@ declare(strict_types=1);
namespace FireflyIII\Api\V2\Response\Sum; namespace FireflyIII\Api\V2\Response\Sum;
use Closure;
use FireflyIII\Exceptions\FireflyException; use FireflyIII\Exceptions\FireflyException;
use FireflyIII\Models\TransactionCurrency; use FireflyIII\Models\TransactionCurrency;
use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\Model;
@@ -39,7 +40,7 @@ class AutoSum
/** /**
* @throws FireflyException * @throws FireflyException
*/ */
public function autoSum(Collection $objects, \Closure $getCurrency, \Closure $getSum): array public function autoSum(Collection $objects, Closure $getCurrency, Closure $getSum): array
{ {
$return = []; $return = [];

View File

@@ -42,6 +42,7 @@ use FireflyIII\Support\Facades\Amount;
use Illuminate\Console\Command; use Illuminate\Console\Command;
use Illuminate\Support\Facades\DB; use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log; use Illuminate\Support\Facades\Log;
use ValueError;
class CorrectsAmounts extends Command class CorrectsAmounts extends Command
{ {
@@ -75,6 +76,65 @@ class CorrectsAmounts extends Command
return 0; return 0;
} }
private function correctTransfers(): void
{
/** @var AccountRepositoryInterface $repository */
$repository = app(AccountRepositoryInterface::class);
$type = TransactionType::where('type', TransactionTypeEnum::TRANSFER->value)->first();
$journals = TransactionJournal::where('transaction_type_id', $type->id)->get();
/** @var TransactionJournal $journal */
foreach ($journals as $journal) {
$repository->setUser($journal->user);
$native = Amount::getNativeCurrencyByUserGroup($journal->userGroup);
/** @var null|Transaction $source */
$source = $journal->transactions()->where('amount', '<', 0)->first();
/** @var null|Transaction $destination */
$destination = $journal->transactions()->where('amount', '>', 0)->first();
if (null === $source || null === $destination) {
continue;
}
if (null === $source->foreign_currency_id || null === $destination->foreign_currency_id) {
continue;
}
$sourceAccount = $source->account;
$destAccount = $destination->account;
if (null === $sourceAccount || null === $destAccount) {
continue;
}
$sourceCurrency = $repository->getAccountCurrency($sourceAccount) ?? $native;
$destCurrency = $repository->getAccountCurrency($destAccount) ?? $native;
if ($sourceCurrency->id === $destCurrency->id) {
Log::debug('Both accounts have the same currency. Removing foreign currency info.');
$source->foreign_currency_id = null;
$source->foreign_amount = null;
$source->save();
$destination->foreign_currency_id = null;
$destination->foreign_amount = null;
$destination->save();
continue;
}
// validate source
if ($destCurrency->id !== $source->foreign_currency_id) {
Log::debug(sprintf('Journal #%d: Transaction #%d refers to "%s" but should refer to "%s".', $journal->id, $source->id, $source->foreignCurrency->code, $destCurrency->code));
$source->foreign_currency_id = $destCurrency->id;
$source->save();
}
// validate destination:
if ($sourceCurrency->id !== $destination->foreign_currency_id) {
Log::debug(sprintf('Journal #%d: Transaction #%d refers to "%s" but should refer to "%s".', $journal->id, $destination->id, $destination->foreignCurrency->code, $sourceCurrency->code));
$destination->foreign_currency_id = $sourceCurrency->id;
$destination->save();
}
}
}
private function fixAutoBudgets(): void private function fixAutoBudgets(): void
{ {
$count = AutoBudget::where('amount', '<', 0)->update(['amount' => DB::raw('amount * -1')]); $count = AutoBudget::where('amount', '<', 0)->update(['amount' => DB::raw('amount * -1')]);
@@ -175,7 +235,7 @@ class CorrectsAmounts extends Command
{ {
try { try {
$check = bccomp((string) $item->trigger_value, '0'); $check = bccomp((string) $item->trigger_value, '0');
} catch (\ValueError $e) { } catch (ValueError) {
$this->friendlyError(sprintf('Rule #%d contained invalid %s-trigger "%s". The trigger has been removed, and the rule is disabled.', $item->rule_id, $item->trigger_type, $item->trigger_value)); $this->friendlyError(sprintf('Rule #%d contained invalid %s-trigger "%s". The trigger has been removed, and the rule is disabled.', $item->rule_id, $item->trigger_type, $item->trigger_value));
$item->rule->active = false; $item->rule->active = false;
$item->rule->save(); $item->rule->save();
@@ -192,63 +252,4 @@ class CorrectsAmounts extends Command
return false; return false;
} }
private function correctTransfers(): void
{
/** @var AccountRepositoryInterface $repository */
$repository = app(AccountRepositoryInterface::class);
$type = TransactionType::where('type', TransactionTypeEnum::TRANSFER->value)->first();
$journals = TransactionJournal::where('transaction_type_id', $type->id)->get();
/** @var TransactionJournal $journal */
foreach ($journals as $journal) {
$repository->setUser($journal->user);
$native = Amount::getNativeCurrencyByUserGroup($journal->userGroup);
/** @var null|Transaction $source */
$source = $journal->transactions()->where('amount', '<', 0)->first();
/** @var null|Transaction $destination */
$destination = $journal->transactions()->where('amount', '>', 0)->first();
if (null === $source || null === $destination) {
continue;
}
if (null === $source->foreign_currency_id || null === $destination->foreign_currency_id) {
continue;
}
$sourceAccount = $source->account;
$destAccount = $destination->account;
if (null === $sourceAccount || null === $destAccount) {
continue;
}
$sourceCurrency = $repository->getAccountCurrency($sourceAccount) ?? $native;
$destCurrency = $repository->getAccountCurrency($destAccount) ?? $native;
if ($sourceCurrency->id === $destCurrency->id) {
Log::debug('Both accounts have the same currency. Removing foreign currency info.');
$source->foreign_currency_id = null;
$source->foreign_amount = null;
$source->save();
$destination->foreign_currency_id = null;
$destination->foreign_amount = null;
$destination->save();
continue;
}
// validate source
if ($destCurrency->id !== $source->foreign_currency_id) {
Log::debug(sprintf('Journal #%d: Transaction #%d refers to "%s" but should refer to "%s".', $journal->id, $source->id, $source->foreignCurrency->code, $destCurrency->code));
$source->foreign_currency_id = $destCurrency->id;
$source->save();
}
// validate destination:
if ($sourceCurrency->id !== $destination->foreign_currency_id) {
Log::debug(sprintf('Journal #%d: Transaction #%d refers to "%s" but should refer to "%s".', $journal->id, $destination->id, $destination->foreignCurrency->code, $sourceCurrency->code));
$destination->foreign_currency_id = $sourceCurrency->id;
$destination->save();
}
}
}
} }

View File

@@ -115,9 +115,7 @@ class CorrectsCurrencies extends Command
$found = array_values( $found = array_values(
array_filter( array_filter(
$found, $found,
static function (int $currencyId) { static fn (int $currencyId) => 0 !== $currencyId
return 0 !== $currencyId;
}
) )
); );

View File

@@ -26,6 +26,7 @@ namespace FireflyIII\Console\Commands\Correction;
use FireflyIII\Console\Commands\ShowsFriendlyMessages; use FireflyIII\Console\Commands\ShowsFriendlyMessages;
use Illuminate\Console\Command; use Illuminate\Console\Command;
use Illuminate\Support\Facades\Schema;
class CorrectsDatabase extends Command class CorrectsDatabase extends Command
{ {
@@ -40,7 +41,7 @@ class CorrectsDatabase extends Command
public function handle(): int public function handle(): int
{ {
// if table does not exist, return false // if table does not exist, return false
if (!\Schema::hasTable('users')) { if (!Schema::hasTable('users')) {
$this->friendlyError('No "users"-table, will not continue.'); $this->friendlyError('No "users"-table, will not continue.');
return 1; return 1;

View File

@@ -58,7 +58,8 @@ class CorrectsGroupAccounts extends Command
$handler = new UpdatedGroupEventHandler(); $handler = new UpdatedGroupEventHandler();
foreach ($groups as $groupId) { foreach ($groups as $groupId) {
$group = TransactionGroup::find($groupId); $group = TransactionGroup::find($groupId);
$event = new UpdatedTransactionGroup($group, true, true); // TODO in theory the "unifyAccounts" method could lead to the need for run recalculations.
$event = new UpdatedTransactionGroup($group, true, true, false);
$handler->unifyAccounts($event); $handler->unifyAccounts($event);
} }

View File

@@ -43,7 +43,7 @@ class CorrectsIbans extends Command
*/ */
public function handle(): int public function handle(): int
{ {
$accounts = Account::whereNotNull('iban')->get(); $accounts = Account::with('accountMeta')->get();
$this->filterIbans($accounts); $this->filterIbans($accounts);
$this->countAndCorrectIbans($accounts); $this->countAndCorrectIbans($accounts);
@@ -62,6 +62,18 @@ class CorrectsIbans extends Command
$this->friendlyInfo(sprintf('Removed spaces from IBAN of account #%d', $account->id)); $this->friendlyInfo(sprintf('Removed spaces from IBAN of account #%d', $account->id));
++$this->count; ++$this->count;
} }
// same for account number:
$accountNumber = $account->accountMeta->where('name', 'account_number')->first();
if (null !== $accountNumber) {
$number = (string) $accountNumber->value;
$newNumber = app('steam')->filterSpaces($number);
if ('' !== $number && $number !== $newNumber) {
$accountNumber->value = $newNumber;
$accountNumber->save();
$this->friendlyInfo(sprintf('Removed spaces from account number of account #%d', $account->id));
++$this->count;
}
}
} }
} }

View File

@@ -48,8 +48,8 @@ class CorrectsLongDescriptions extends Command
/** @var TransactionJournal $journal */ /** @var TransactionJournal $journal */
foreach ($journals as $journal) { foreach ($journals as $journal) {
if (strlen($journal->description) > self::MAX_LENGTH) { if (strlen((string) $journal->description) > self::MAX_LENGTH) {
$journal->description = substr($journal->description, 0, self::MAX_LENGTH); $journal->description = substr((string) $journal->description, 0, self::MAX_LENGTH);
$journal->save(); $journal->save();
$this->friendlyWarning(sprintf('Truncated description of transaction journal #%d', $journal->id)); $this->friendlyWarning(sprintf('Truncated description of transaction journal #%d', $journal->id));
++$count; ++$count;
@@ -61,7 +61,7 @@ class CorrectsLongDescriptions extends Command
/** @var TransactionGroup $group */ /** @var TransactionGroup $group */
foreach ($groups as $group) { foreach ($groups as $group) {
if (strlen((string) $group->title) > self::MAX_LENGTH) { if (strlen((string) $group->title) > self::MAX_LENGTH) {
$group->title = substr($group->title, 0, self::MAX_LENGTH); $group->title = substr((string) $group->title, 0, self::MAX_LENGTH);
$group->save(); $group->save();
$this->friendlyWarning(sprintf('Truncated description of transaction group #%d', $group->id)); $this->friendlyWarning(sprintf('Truncated description of transaction group #%d', $group->id));
++$count; ++$count;

View File

@@ -38,8 +38,8 @@ use FireflyIII\Models\PiggyBankEvent;
use FireflyIII\Models\Transaction; use FireflyIII\Models\Transaction;
use FireflyIII\Models\TransactionCurrency; use FireflyIII\Models\TransactionCurrency;
use FireflyIII\Models\UserGroup; use FireflyIII\Models\UserGroup;
use FireflyIII\Repositories\UserGroup\UserGroupRepositoryInterface;
use FireflyIII\Repositories\PiggyBank\PiggyBankRepositoryInterface; use FireflyIII\Repositories\PiggyBank\PiggyBankRepositoryInterface;
use FireflyIII\Repositories\UserGroup\UserGroupRepositoryInterface;
use FireflyIII\Support\Facades\Preferences; use FireflyIII\Support\Facades\Preferences;
use FireflyIII\Support\Http\Api\ExchangeRateConverter; use FireflyIII\Support\Http\Api\ExchangeRateConverter;
use Illuminate\Console\Command; use Illuminate\Console\Command;
@@ -128,9 +128,7 @@ class CorrectsNativeAmounts extends Command
$repository->setUserGroup($userGroup); $repository->setUserGroup($userGroup);
$set = $repository->getPiggyBanks(); $set = $repository->getPiggyBanks();
$set = $set->filter( $set = $set->filter(
static function (PiggyBank $piggyBank) use ($currency) { static fn (PiggyBank $piggyBank) => $currency->id !== $piggyBank->transaction_currency_id
return $currency->id !== $piggyBank->transaction_currency_id;
}
); );
foreach ($set as $piggyBank) { foreach ($set as $piggyBank) {
$piggyBank->encrypted = false; $piggyBank->encrypted = false;

View File

@@ -76,7 +76,7 @@ class CorrectsOpeningBalanceCurrencies extends Command
{ {
// get the asset account for this opening balance: // get the asset account for this opening balance:
$account = $this->getAccount($journal); $account = $this->getAccount($journal);
if (null === $account) { if (!$account instanceof Account) {
$message = sprintf('Transaction journal #%d has no valid account. Can\'t fix this line.', $journal->id); $message = sprintf('Transaction journal #%d has no valid account. Can\'t fix this line.', $journal->id);
app('log')->warning($message); app('log')->warning($message);
$this->friendlyError($message); $this->friendlyError($message);

View File

@@ -100,7 +100,7 @@ class CorrectsRecurringTransactions extends Command
$destination = $transaction->destinationAccount; $destination = $transaction->destinationAccount;
$type = $recurrence->transactionType; $type = $recurrence->transactionType;
$link = config(sprintf('firefly.account_to_transaction.%s.%s', $source->accountType->type, $destination->accountType->type)); $link = config(sprintf('firefly.account_to_transaction.%s.%s', $source->accountType->type, $destination->accountType->type));
if (null !== $link && strtolower($type->type) !== strtolower($link)) { if (null !== $link && strtolower((string) $type->type) !== strtolower($link)) {
$this->friendlyWarning( $this->friendlyWarning(
sprintf('Recurring transaction #%d should be a "%s" but is a "%s" and will be corrected.', $recurrence->id, $link, $type->type) sprintf('Recurring transaction #%d should be a "%s" but is a "%s" and will be corrected.', $recurrence->id, $link, $type->type)
); );

View File

@@ -115,9 +115,7 @@ class CorrectsTransactionTypes extends Command
private function getSourceAccount(TransactionJournal $journal): Account private function getSourceAccount(TransactionJournal $journal): Account
{ {
$collection = $journal->transactions->filter( $collection = $journal->transactions->filter(
static function (Transaction $transaction) { static fn (Transaction $transaction) => $transaction->amount < 0
return $transaction->amount < 0;
}
); );
if (0 === $collection->count()) { if (0 === $collection->count()) {
throw new FireflyException(sprintf('300001: Journal #%d has no source transaction.', $journal->id)); throw new FireflyException(sprintf('300001: Journal #%d has no source transaction.', $journal->id));
@@ -144,9 +142,7 @@ class CorrectsTransactionTypes extends Command
private function getDestinationAccount(TransactionJournal $journal): Account private function getDestinationAccount(TransactionJournal $journal): Account
{ {
$collection = $journal->transactions->filter( $collection = $journal->transactions->filter(
static function (Transaction $transaction) { static fn (Transaction $transaction) => $transaction->amount > 0
return $transaction->amount > 0;
}
); );
if (0 === $collection->count()) { if (0 === $collection->count()) {
throw new FireflyException(sprintf('300004: Journal #%d has no destination transaction.', $journal->id)); throw new FireflyException(sprintf('300004: Journal #%d has no destination transaction.', $journal->id));

View File

@@ -25,13 +25,17 @@ declare(strict_types=1);
namespace FireflyIII\Console\Commands\Correction; namespace FireflyIII\Console\Commands\Correction;
use FireflyIII\Console\Commands\ShowsFriendlyMessages; use FireflyIII\Console\Commands\ShowsFriendlyMessages;
use FireflyIII\Enums\AccountTypeEnum;
use FireflyIII\Enums\TransactionTypeEnum; use FireflyIII\Enums\TransactionTypeEnum;
use FireflyIII\Models\Transaction; use FireflyIII\Models\Transaction;
use FireflyIII\Models\TransactionJournal; use FireflyIII\Models\TransactionJournal;
use FireflyIII\Repositories\Account\AccountRepositoryInterface;
use FireflyIII\Support\Models\AccountBalanceCalculator; use FireflyIII\Support\Models\AccountBalanceCalculator;
use Illuminate\Console\Command; use Illuminate\Console\Command;
use Illuminate\Support\Facades\DB; use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log; use Illuminate\Support\Facades\Log;
use ValueError;
use stdClass;
class CorrectsUnevenAmount extends Command class CorrectsUnevenAmount extends Command
{ {
@@ -47,7 +51,12 @@ class CorrectsUnevenAmount extends Command
public function handle(): int public function handle(): int
{ {
$this->count = 0; $this->count = 0;
// convert transfers with foreign currency info where the amount is NOT uneven (it should be)
$this->convertOldStyleTransfers(); $this->convertOldStyleTransfers();
// convert old-style transactions between assets and liabilities.
$this->convertOldStyleTransactions();
$this->fixUnevenAmounts(); $this->fixUnevenAmounts();
$this->matchCurrencies(); $this->matchCurrencies();
if (true === config('firefly.feature_flags.running_balance_column')) { if (true === config('firefly.feature_flags.running_balance_column')) {
@@ -72,8 +81,6 @@ class CorrectsUnevenAmount extends Command
; ;
$count = 0; $count = 0;
Log::debug(sprintf('Found %d potential journal(s)', $transactions->count()));
/** @var Transaction $transaction */ /** @var Transaction $transaction */
foreach ($transactions as $transaction) { foreach ($transactions as $transaction) {
/** @var null|TransactionJournal $journal */ /** @var null|TransactionJournal $journal */
@@ -115,17 +122,22 @@ class CorrectsUnevenAmount extends Command
++$count; ++$count;
} }
} }
if (0 === $count) {
return;
}
$this->friendlyPositive(sprintf('Fixed %d transfer(s) with unbalanced amounts.', $count));
} }
private function fixUnevenAmounts(): void private function fixUnevenAmounts(): void
{ {
Log::debug('fixUnevenAmounts()');
$journals = DB::table('transactions') $journals = DB::table('transactions')
->groupBy('transaction_journal_id') ->groupBy('transaction_journal_id')
->whereNull('deleted_at') ->whereNull('deleted_at')
->get(['transaction_journal_id', DB::raw('SUM(amount) AS the_sum')]) ->get(['transaction_journal_id', DB::raw('SUM(amount) AS the_sum')])
; ;
/** @var \stdClass $entry */ /** @var stdClass $entry */
foreach ($journals as $entry) { foreach ($journals as $entry) {
$sum = (string) $entry->the_sum; $sum = (string) $entry->the_sum;
if (!is_numeric($sum) if (!is_numeric($sum)
@@ -147,13 +159,13 @@ class CorrectsUnevenAmount extends Command
try { try {
$res = bccomp($sum, '0'); $res = bccomp($sum, '0');
} catch (\ValueError $e) { } catch (ValueError $e) {
$this->friendlyError(sprintf('Could not bccomp("%s", "0").', $sum)); $this->friendlyError(sprintf('Could not bccomp("%s", "0").', $sum));
Log::error($e->getMessage()); Log::error($e->getMessage());
Log::error($e->getTraceAsString()); Log::error($e->getTraceAsString());
} }
if (0 !== $res) { if (0 !== $res) {
$this->fixJournal($entry->transaction_journal_id); $this->fixJournal((int) $entry->transaction_journal_id);
} }
} }
} }
@@ -184,7 +196,7 @@ class CorrectsUnevenAmount extends Command
return; return;
} }
$amount = bcmul('-1', $source->amount); $amount = bcmul('-1', (string) $source->amount);
// fix amount of destination: // fix amount of destination:
/** @var null|Transaction $destination */ /** @var null|Transaction $destination */
@@ -207,8 +219,8 @@ class CorrectsUnevenAmount extends Command
} }
// may still be able to salvage this journal if it is a transfer with foreign currency info // may still be able to salvage this journal if it is a transfer with foreign currency info
if ($this->isForeignCurrencyTransfer($journal)) { if ($this->isForeignCurrencyTransfer($journal) || $this->isBetweenAssetAndLiability($journal)) {
Log::debug(sprintf('Can skip foreign currency transfer #%d.', $journal->id)); Log::debug(sprintf('Can skip foreign currency transfer / asset+liability transaction #%d.', $journal->id));
return; return;
} }
@@ -249,9 +261,9 @@ class CorrectsUnevenAmount extends Command
// Log::debug(sprintf('[c] %s', var_export($source->transaction_currency_id === $destination->foreign_currency_id,true))); // Log::debug(sprintf('[c] %s', var_export($source->transaction_currency_id === $destination->foreign_currency_id,true)));
// Log::debug(sprintf('[d] %s', var_export((int) $destination->transaction_currency_id ===(int) $source->foreign_currency_id, true))); // Log::debug(sprintf('[d] %s', var_export((int) $destination->transaction_currency_id ===(int) $source->foreign_currency_id, true)));
if (0 === bccomp(app('steam')->positive($source->amount), app('steam')->positive($destination->foreign_amount)) if (0 === bccomp((string) app('steam')->positive($source->amount), (string) app('steam')->positive($destination->foreign_amount))
&& $source->transaction_currency_id === $destination->foreign_currency_id && $source->transaction_currency_id === $destination->foreign_currency_id
&& 0 === bccomp(app('steam')->positive($destination->amount), app('steam')->positive($source->foreign_amount)) && 0 === bccomp((string) app('steam')->positive($destination->amount), (string) app('steam')->positive($source->foreign_amount))
&& (int) $destination->transaction_currency_id === (int) $source->foreign_currency_id && (int) $destination->transaction_currency_id === (int) $source->foreign_currency_id
) { ) {
return true; return true;
@@ -271,13 +283,13 @@ class CorrectsUnevenAmount extends Command
/** @var TransactionJournal $journal */ /** @var TransactionJournal $journal */
foreach ($journals as $journal) { foreach ($journals as $journal) {
if (!$this->isForeignCurrencyTransfer($journal)) { if (!$this->isForeignCurrencyTransfer($journal) && !$this->isBetweenAssetAndLiability($journal)) {
Transaction::where('transaction_journal_id', $journal->id)->update(['transaction_currency_id' => $journal->transaction_currency_id]); Transaction::where('transaction_journal_id', $journal->id)->update(['transaction_currency_id' => $journal->transaction_currency_id]);
++$count; ++$count;
continue; continue;
} }
Log::debug(sprintf('Can skip foreign currency transfer #%d.', $journal->id)); Log::debug(sprintf('Can skip foreign currency transfer or transaction between asset and liability #%d.', $journal->id));
} }
if (0 === $count) { if (0 === $count) {
return; return;
@@ -285,4 +297,155 @@ class CorrectsUnevenAmount extends Command
$this->friendlyPositive(sprintf('Fixed %d journal(s) with mismatched currencies.', $journals->count())); $this->friendlyPositive(sprintf('Fixed %d journal(s) with mismatched currencies.', $journals->count()));
} }
private function isBetweenAssetAndLiability(TransactionJournal $journal): bool
{
/** @var Transaction $sourceTransaction */
$sourceTransaction = $journal->transactions()->where('amount', '<', 0)->first();
/** @var Transaction $destinationTransaction */
$destinationTransaction = $journal->transactions()->where('amount', '>', 0)->first();
if (null === $sourceTransaction || null === $destinationTransaction) {
Log::warning('Either transaction is false, stop.');
return false;
}
if (null === $sourceTransaction->foreign_amount || null === $destinationTransaction->foreign_amount) {
Log::warning('Either foreign amount is false, stop.');
return false;
}
$source = $sourceTransaction->account;
$destination = $destinationTransaction->account;
if (null === $source || null === $destination) {
Log::warning('Either is false, stop.');
return false;
}
$sourceTypes = [AccountTypeEnum::LOAN->value, AccountTypeEnum::DEBT->value, AccountTypeEnum::MORTGAGE->value];
// source is liability, destination is asset
if (in_array($source->accountType->type, $sourceTypes, true) && AccountTypeEnum::ASSET->value === $destination->accountType->type) {
Log::debug('Source is a liability account, destination is an asset account, return TRUE.');
return true;
}
// source is asset, destination is liability
if (in_array($destination->accountType->type, $sourceTypes, true) && AccountTypeEnum::ASSET->value === $source->accountType->type) {
Log::debug('Destination is a liability account, source is an asset account, return TRUE.');
return true;
}
return false;
}
private function convertOldStyleTransactions(): void
{
/** @var AccountRepositoryInterface $repository */
$repository = app(AccountRepositoryInterface::class);
Log::debug('convertOldStyleTransactions()');
$count = 0;
$transactions = Transaction::distinct()
->leftJoin('transaction_journals', 'transaction_journals.id', 'transactions.transaction_journal_id')
->leftJoin('transaction_types', 'transaction_types.id', 'transaction_journals.transaction_type_id')
->leftJoin('accounts', 'accounts.id', 'transactions.account_id')
->leftJoin('account_types', 'account_types.id', 'accounts.account_type_id')
->whereNot('transaction_types.type', TransactionTypeEnum::TRANSFER->value)
->whereNotNull('foreign_currency_id')
->whereNotNull('foreign_amount')
->whereIn('account_types.type', [AccountTypeEnum::ASSET->value, AccountTypeEnum::DEBT->value, AccountTypeEnum::MORTGAGE->value, AccountTypeEnum::LOAN->value])
->get(['transactions.transaction_journal_id'])
;
/** @var Transaction $transaction */
foreach ($transactions as $transaction) {
/** @var null|TransactionJournal $journal */
$journal = TransactionJournal::find($transaction->transaction_journal_id);
$repository->setUser($journal->user);
if (null === $journal) {
Log::debug('Found no journal, continue.');
continue;
}
if (!$this->isBetweenAssetAndLiability($journal)) {
Log::debug('Not between asset and liability, continue.');
continue;
}
$source = $journal->transactions()->where('amount', '<', 0)->first();
$destination = $journal->transactions()->where('amount', '>', 0)->first();
$sourceAccount = $source->account;
$destAccount = $destination->account;
$sourceCurrency = $repository->getAccountCurrency($sourceAccount);
$destCurrency = $repository->getAccountCurrency($destAccount);
if (null === $source || null === $destination) {
Log::debug('Either transaction is NULL, continue.');
continue;
}
if (0 === bccomp((string) $source->amount, (string) $source->foreign_amount) && 0 === bccomp((string) $source->foreign_amount, (string) $source->amount)) {
Log::debug('Already fixed, continue.');
continue;
}
// source transaction. Switch info when does not match.
if ((int) $source->transaction_currency_id !== (int) $sourceCurrency->id) {
Log::debug(sprintf('Ready to swap data in transaction #%d.', $source->id));
// swap amounts.
$amount = $source->amount;
$currency = $source->transaction_currency_id;
$source->amount = $source->foreign_amount;
$source->transaction_currency_id = $source->foreign_currency_id;
$source->foreign_amount = $amount;
$source->foreign_currency_id = $currency;
$source->saveQuietly();
$source->refresh();
// Log::debug(sprintf('source->amount = %s', $source->amount));
// Log::debug(sprintf('source->transaction_currency_id = %s', $source->transaction_currency_id));
// Log::debug(sprintf('source->foreign_amount = %s', $source->foreign_amount));
// Log::debug(sprintf('source->foreign_currency_id = %s', $source->foreign_currency_id));
++$count;
}
// same but for destination
if ((int) $destination->transaction_currency_id !== (int) $destCurrency->id) {
++$count;
Log::debug(sprintf('Ready to swap data in transaction #%d.', $destination->id));
// swap amounts.
$amount = $destination->amount;
$currency = $destination->transaction_currency_id;
$destination->amount = $destination->foreign_amount;
$destination->transaction_currency_id = $destination->foreign_currency_id;
$destination->foreign_amount = $amount;
$destination->foreign_currency_id = $currency;
$destination->balance_dirty = true;
$destination->saveQuietly();
$destination->refresh();
// Log::debug(sprintf('destination->amount = %s', $destination->amount));
// Log::debug(sprintf('destination->transaction_currency_id = %s', $destination->transaction_currency_id));
// Log::debug(sprintf('destination->foreign_amount = %s', $destination->foreign_amount));
// Log::debug(sprintf('destination->foreign_currency_id = %s', $destination->foreign_currency_id));
}
// // only fix the destination transaction
// $destination->foreign_currency_id = $source->transaction_currency_id;
// $destination->foreign_amount = app('steam')->positive($source->amount);
// $destination->transaction_currency_id = $source->foreign_currency_id;
// $destination->amount = app('steam')->positive($source->foreign_amount);
// $destination->balance_dirty = true;
// $source->balance_dirty = true;
// $destination->save();
// $source->save();
// $this->friendlyWarning(sprintf('Corrected foreign amounts of transaction #%d.', $journal->id));
}
if (0 === $count) {
return;
}
$this->friendlyPositive(sprintf('Fixed %d journal(s) with unbalanced amounts.', $count));
}
} }

View File

@@ -28,6 +28,7 @@ use FireflyIII\Console\Commands\ShowsFriendlyMessages;
use FireflyIII\Repositories\User\UserRepositoryInterface; use FireflyIII\Repositories\User\UserRepositoryInterface;
use FireflyIII\User; use FireflyIII\User;
use Illuminate\Console\Command; use Illuminate\Console\Command;
use Exception;
class CreatesAccessTokens extends Command class CreatesAccessTokens extends Command
{ {
@@ -40,7 +41,7 @@ class CreatesAccessTokens extends Command
/** /**
* Execute the console command. * Execute the console command.
* *
* @throws \Exception * @throws Exception
*/ */
public function handle(): int public function handle(): int
{ {

View File

@@ -27,6 +27,7 @@ namespace FireflyIII\Console\Commands\Correction;
use FireflyIII\Console\Commands\ShowsFriendlyMessages; use FireflyIII\Console\Commands\ShowsFriendlyMessages;
use FireflyIII\Models\TransactionGroup; use FireflyIII\Models\TransactionGroup;
use Illuminate\Console\Command; use Illuminate\Console\Command;
use Exception;
class RemovesEmptyGroups extends Command class RemovesEmptyGroups extends Command
{ {
@@ -38,7 +39,7 @@ class RemovesEmptyGroups extends Command
/** /**
* Execute the console command. * Execute the console command.
* *
* @throws \Exception * @throws Exception
*/ */
public function handle(): int public function handle(): int
{ {

View File

@@ -28,6 +28,8 @@ use FireflyIII\Console\Commands\ShowsFriendlyMessages;
use FireflyIII\Models\Transaction; use FireflyIII\Models\Transaction;
use FireflyIII\Models\TransactionJournal; use FireflyIII\Models\TransactionJournal;
use Illuminate\Console\Command; use Illuminate\Console\Command;
use Exception;
use stdClass;
/** /**
* Deletes transactions where the journal has been deleted. * Deletes transactions where the journal has been deleted.
@@ -43,7 +45,7 @@ class RemovesOrphanedTransactions extends Command
/** /**
* Execute the console command. * Execute the console command.
* *
* @throws \Exception * @throws Exception
*/ */
public function handle(): int public function handle(): int
{ {
@@ -85,7 +87,7 @@ class RemovesOrphanedTransactions extends Command
} }
/** /**
* @throws \Exception * @throws Exception
*/ */
private function deleteOrphanedTransactions(): void private function deleteOrphanedTransactions(): void
{ {
@@ -102,7 +104,7 @@ class RemovesOrphanedTransactions extends Command
) )
; ;
/** @var \stdClass $entry */ /** @var stdClass $entry */
foreach ($set as $entry) { foreach ($set as $entry) {
$transaction = Transaction::find((int) $entry->transaction_id); $transaction = Transaction::find((int) $entry->transaction_id);
if (null !== $transaction) { if (null !== $transaction) {

View File

@@ -24,6 +24,7 @@ declare(strict_types=1);
namespace FireflyIII\Console\Commands\Export; namespace FireflyIII\Console\Commands\Export;
use FireflyIII\Models\TransactionJournal;
use Carbon\Carbon; use Carbon\Carbon;
use FireflyIII\Console\Commands\ShowsFriendlyMessages; use FireflyIII\Console\Commands\ShowsFriendlyMessages;
use FireflyIII\Console\Commands\VerifiesAccessToken; use FireflyIII\Console\Commands\VerifiesAccessToken;
@@ -35,6 +36,10 @@ use FireflyIII\Repositories\Journal\JournalRepositoryInterface;
use FireflyIII\Support\Export\ExportDataGenerator; use FireflyIII\Support\Export\ExportDataGenerator;
use Illuminate\Console\Command; use Illuminate\Console\Command;
use Illuminate\Support\Collection; use Illuminate\Support\Collection;
use Exception;
use InvalidArgumentException;
use function Safe\file_put_contents;
class ExportsData extends Command class ExportsData extends Command
{ {
@@ -139,7 +144,7 @@ class ExportsData extends Command
/** /**
* @throws FireflyException * @throws FireflyException
* @throws \Exception * @throws Exception
*/ */
private function parseOptions(): array private function parseOptions(): array
{ {
@@ -169,7 +174,7 @@ class ExportsData extends Command
} }
/** /**
* @throws \Exception * @throws Exception
*/ */
private function getDateParameter(string $field): Carbon private function getDateParameter(string $field): Carbon
{ {
@@ -183,7 +188,7 @@ class ExportsData extends Command
if (is_string($this->option($field))) { if (is_string($this->option($field))) {
try { try {
$date = Carbon::createFromFormat('!Y-m-d', $this->option($field)); $date = Carbon::createFromFormat('!Y-m-d', $this->option($field));
} catch (\InvalidArgumentException $e) { } catch (InvalidArgumentException $e) {
app('log')->error($e->getMessage()); app('log')->error($e->getMessage());
$this->friendlyError(sprintf('%s date "%s" must be formatted YYYY-MM-DD. Field will be ignored.', $field, $this->option('start'))); $this->friendlyError(sprintf('%s date "%s" must be formatted YYYY-MM-DD. Field will be ignored.', $field, $this->option('start')));
$error = true; $error = true;
@@ -201,7 +206,7 @@ class ExportsData extends Command
if (true === $error && 'start' === $field) { if (true === $error && 'start' === $field) {
$journal = $this->journalRepository->firstNull(); $journal = $this->journalRepository->firstNull();
$date = null === $journal ? today(config('app.timezone'))->subYear() : $journal->date; $date = $journal instanceof TransactionJournal ? $journal->date : today(config('app.timezone'))->subYear();
$date->startOfDay(); $date->startOfDay();
return $date; return $date;
@@ -273,7 +278,7 @@ class ExportsData extends Command
*/ */
private function exportData(array $options, array $data): void private function exportData(array $options, array $data): void
{ {
$date = date('Y_m_d'); $date = Carbon::now()->format('Y_m_d');
foreach ($data as $key => $content) { foreach ($data as $key => $content) {
$file = sprintf('%s%s_%s.csv', $options['directory'], $date, $key); $file = sprintf('%s%s_%s.csv', $options['directory'], $date, $key);
if (false === $options['force'] && file_exists($file)) { if (false === $options['force'] && file_exists($file)) {

View File

@@ -30,6 +30,7 @@ use FireflyIII\Models\Budget;
use FireflyIII\Models\Category; use FireflyIII\Models\Category;
use FireflyIII\Models\Tag; use FireflyIII\Models\Tag;
use Illuminate\Console\Command; use Illuminate\Console\Command;
use stdClass;
class ReportsEmptyObjects extends Command class ReportsEmptyObjects extends Command
{ {
@@ -66,7 +67,7 @@ class ReportsEmptyObjects extends Command
->get(['budgets.id', 'budgets.name', 'budgets.user_id', 'users.email']) ->get(['budgets.id', 'budgets.name', 'budgets.user_id', 'users.email'])
; ;
/** @var \stdClass $entry */ /** @var stdClass $entry */
foreach ($set as $entry) { foreach ($set as $entry) {
$line = sprintf( $line = sprintf(
'User #%d (%s) has budget #%d ("%s") which has no transaction journals.', 'User #%d (%s) has budget #%d ("%s") which has no transaction journals.',
@@ -92,7 +93,7 @@ class ReportsEmptyObjects extends Command
->get(['categories.id', 'categories.name', 'categories.user_id', 'users.email']) ->get(['categories.id', 'categories.name', 'categories.user_id', 'users.email'])
; ;
/** @var \stdClass $entry */ /** @var stdClass $entry */
foreach ($set as $entry) { foreach ($set as $entry) {
$line = sprintf( $line = sprintf(
'User #%d (%s) has category #%d ("%s") which has no transaction journals.', 'User #%d (%s) has category #%d ("%s") which has no transaction journals.',
@@ -115,7 +116,7 @@ class ReportsEmptyObjects extends Command
->get(['tags.id', 'tags.tag', 'tags.user_id', 'users.email']) ->get(['tags.id', 'tags.tag', 'tags.user_id', 'users.email'])
; ;
/** @var \stdClass $entry */ /** @var stdClass $entry */
foreach ($set as $entry) { foreach ($set as $entry) {
$line = sprintf( $line = sprintf(
'User #%d (%s) has tag #%d ("%s") which has no transaction journals.', 'User #%d (%s) has tag #%d ("%s") which has no transaction journals.',
@@ -142,7 +143,7 @@ class ReportsEmptyObjects extends Command
) )
; ;
/** @var \stdClass $entry */ /** @var stdClass $entry */
foreach ($set as $entry) { foreach ($set as $entry) {
$line = 'User #%d (%s) has account #%d ("%s") which has no transactions.'; $line = 'User #%d (%s) has account #%d ("%s") which has no transactions.';
$line = sprintf($line, $entry->user_id, $entry->email, $entry->id, $entry->name); $line = sprintf($line, $entry->user_id, $entry->email, $entry->id, $entry->name);

View File

@@ -26,6 +26,7 @@ namespace FireflyIII\Console\Commands\Integrity;
use FireflyIII\Console\Commands\ShowsFriendlyMessages; use FireflyIII\Console\Commands\ShowsFriendlyMessages;
use Illuminate\Console\Command; use Illuminate\Console\Command;
use Illuminate\Support\Facades\Schema;
class ReportsIntegrity extends Command class ReportsIntegrity extends Command
{ {
@@ -41,7 +42,7 @@ class ReportsIntegrity extends Command
public function handle(): int public function handle(): int
{ {
// if table does not exist, return false // if table does not exist, return false
if (!\Schema::hasTable('users')) { if (!Schema::hasTable('users')) {
return 1; return 1;
} }
$commands = [ $commands = [

View File

@@ -30,13 +30,6 @@ class ValidatesEnvironmentVariables extends Command
{ {
use ShowsFriendlyMessages; use ShowsFriendlyMessages;
/**
* The name and signature of the console command.
*
* @var string
*/
protected $signature = 'integrity:validates-environment-variables';
/** /**
* The console command description. * The console command description.
* *
@@ -44,6 +37,13 @@ class ValidatesEnvironmentVariables extends Command
*/ */
protected $description = 'Makes sure you use the correct variables.'; protected $description = 'Makes sure you use the correct variables.';
/**
* The name and signature of the console command.
*
* @var string
*/
protected $signature = 'integrity:validates-environment-variables';
/** /**
* Execute the console command. * Execute the console command.
*/ */

View File

@@ -27,6 +27,7 @@ namespace FireflyIII\Console\Commands\System;
use FireflyIII\Console\Commands\ShowsFriendlyMessages; use FireflyIII\Console\Commands\ShowsFriendlyMessages;
use Illuminate\Console\Command; use Illuminate\Console\Command;
use PDO; use PDO;
use PDOException;
class CreatesDatabase extends Command class CreatesDatabase extends Command
{ {
@@ -53,15 +54,15 @@ class CreatesDatabase extends Command
$this->friendlyLine(sprintf('DSN is %s', $dsn)); $this->friendlyLine(sprintf('DSN is %s', $dsn));
$options = [ $options = [
\PDO::ATTR_ERRMODE => \PDO::ERRMODE_EXCEPTION, PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
\PDO::ATTR_DEFAULT_FETCH_MODE => \PDO::FETCH_ASSOC, PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
\PDO::ATTR_EMULATE_PREPARES => false, PDO::ATTR_EMULATE_PREPARES => false,
]; ];
// when it fails, display error // when it fails, display error
try { try {
$pdo = new \PDO($dsn, (string) env('DB_USERNAME'), (string) env('DB_PASSWORD'), $options); $pdo = new PDO($dsn, (string) env('DB_USERNAME'), (string) env('DB_PASSWORD'), $options);
} catch (\PDOException $e) { } catch (PDOException $e) {
$this->friendlyError(sprintf('Error when connecting to DB: %s', $e->getMessage())); $this->friendlyError(sprintf('Error when connecting to DB: %s', $e->getMessage()));
return 1; return 1;

View File

@@ -43,6 +43,9 @@ use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Collection; use Illuminate\Support\Collection;
use Illuminate\Support\Facades\DB; use Illuminate\Support\Facades\DB;
use function Safe\mb_regex_encoding;
use function Safe\json_encode;
/** /**
* This command was inspired by https://github.com/elliot-gh. It will check all amount fields * This command was inspired by https://github.com/elliot-gh. It will check all amount fields
* and their values and correct them to the correct number of decimal places. This fixes issues where * and their values and correct them to the correct number of decimal places. This fixes issues where

View File

@@ -24,6 +24,7 @@ declare(strict_types=1);
namespace FireflyIII\Console\Commands\System; namespace FireflyIII\Console\Commands\System;
use Carbon\Carbon;
use FireflyIII\Support\System\GeneratesInstallationId; use FireflyIII\Support\System\GeneratesInstallationId;
use Illuminate\Console\Command; use Illuminate\Console\Command;
@@ -111,8 +112,8 @@ class OutputsInstructions extends Command
*/ */
private function showLogo(): void private function showLogo(): void
{ {
$today = date('m-d'); $today = Carbon::now()->format('m-d');
$month = date('m'); $month = Carbon::now()->format('m');
// variation in colors and effects just because I can! // variation in colors and effects just because I can!
// default is Ukraine flag: // default is Ukraine flag:
$colors = ['blue', 'blue', 'blue', 'yellow', 'yellow', 'yellow', 'default', 'default']; $colors = ['blue', 'blue', 'blue', 'yellow', 'yellow', 'yellow', 'default', 'default'];
@@ -147,10 +148,7 @@ class OutputsInstructions extends Command
*/ */
private function showLine(): void private function showLine(): void
{ {
$line = '+'; $this->line(sprintf('+%s+', str_repeat('-', 78)));
$line .= str_repeat('-', 78);
$line .= '+';
$this->line($line);
} }
/** /**
@@ -175,6 +173,13 @@ class OutputsInstructions extends Command
} }
} }
private function donationText(): void
{
$this->boxed('Did you know you can support the development of Firefly III?');
$this->boxed('You can donate in many ways, like GitHub Sponsors or Patreon.');
$this->boxed('For more information, please visit https://bit.ly/donate-to-Firefly-III');
}
/** /**
* Render instructions. * Render instructions.
*/ */
@@ -228,11 +233,4 @@ class OutputsInstructions extends Command
$this->boxed(''); $this->boxed('');
$this->showLine(); $this->showLine();
} }
private function donationText(): void
{
$this->boxed('Did you know you can support the development of Firefly III?');
$this->boxed('You can donate in many ways, like GitHub Sponsors or Patreon.');
$this->boxed('For more information, please visit https://bit.ly/donate-to-Firefly-III');
}
} }

View File

@@ -31,13 +31,6 @@ class RecalculatesRunningBalance extends Command
{ {
use ShowsFriendlyMessages; use ShowsFriendlyMessages;
/**
* The name and signature of the console command.
*
* @var string
*/
protected $signature = 'firefly-iii:refresh-running-balance {--F|force : Force the execution of this command.}';
/** /**
* The console command description. * The console command description.
* *
@@ -45,6 +38,13 @@ class RecalculatesRunningBalance extends Command
*/ */
protected $description = 'Refreshes all running balances. May take a long time to run if forced.'; protected $description = 'Refreshes all running balances. May take a long time to run if forced.';
/**
* The name and signature of the console command.
*
* @var string
*/
protected $signature = 'firefly-iii:refresh-running-balance {--F|force : Force the execution of this command.}';
/** /**
* Execute the console command. * Execute the console command.
*/ */

Some files were not shown because too many files have changed in this diff Show More