Compare commits

...

274 Commits

Author SHA1 Message Date
James Cole
cc83268b2c Merge branch 'release/v6.0.11' 2023-05-27 07:12:26 +02:00
James Cole
8f23b47a78 Meta files for new release. 2023-05-27 07:12:04 +02:00
James Cole
529611170c Fix #7541 2023-05-27 06:42:10 +02:00
James Cole
c1114e889e Fix #7546 2023-05-27 06:40:23 +02:00
James Cole
d20e03a7b6 Merge pull request #7556 from firefly-iii/fix-7547
Fix 7547
2023-05-27 06:37:00 +02:00
James Cole
6303233bdf Fix #7547 2023-05-27 06:36:24 +02:00
James Cole
baa8c00144 Merge pull request #7555 from firefly-iii/fix-7549
Fix #7549
2023-05-27 05:56:07 +02:00
James Cole
e6daaa5b6d Fix #7549 2023-05-27 05:55:41 +02:00
James Cole
f711fcfd52 Merge pull request #7535 from ChrisWin22/withdraw-from-piggy-banks
Withdraw from piggy banks
2023-05-24 08:22:41 +02:00
Christian Desktop
74992e95f2 Withdrawal directly from Piggy Bank - Fixes #6631 2023-05-24 00:13:46 -06:00
James Cole
20c8c1043f Update languages and rephrase sentence. 2023-05-24 06:40:31 +02:00
James Cole
f00898afba Merge pull request #7533 from firefly-iii/dependabot/composer/develop/laravel/ui-4.2.2
Bump laravel/ui from 4.2.1 to 4.2.2
2023-05-22 06:25:51 +02:00
dependabot[bot]
95b431535e Bump laravel/ui from 4.2.1 to 4.2.2
Bumps [laravel/ui](https://github.com/laravel/ui) from 4.2.1 to 4.2.2.
- [Release notes](https://github.com/laravel/ui/releases)
- [Changelog](https://github.com/laravel/ui/blob/4.x/CHANGELOG.md)
- [Commits](https://github.com/laravel/ui/compare/v4.2.1...v4.2.2)

---
updated-dependencies:
- dependency-name: laravel/ui
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-05-22 04:18:35 +00:00
James Cole
cafd8a9674 Merge pull request #7534 from firefly-iii/dependabot/npm_and_yarn/develop/vue/compiler-sfc-3.3.4
Bump @vue/compiler-sfc from 3.3.2 to 3.3.4
2023-05-22 06:18:14 +02:00
James Cole
e1e7f914f9 Merge pull request #7532 from firefly-iii/dependabot/composer/develop/guzzlehttp/guzzle-7.7.0
Bump guzzlehttp/guzzle from 7.6.0 to 7.7.0
2023-05-22 06:18:02 +02:00
James Cole
19c2f7d2bf Merge pull request #7531 from firefly-iii/dependabot/composer/develop/fakerphp/faker-1.22.0
Bump fakerphp/faker from 1.21.0 to 1.22.0
2023-05-22 06:17:55 +02:00
James Cole
7daacd9b66 Merge pull request #7530 from firefly-iii/dependabot/composer/develop/laravel/framework-10.11.0
Bump laravel/framework from 10.10.1 to 10.11.0
2023-05-22 06:17:47 +02:00
dependabot[bot]
af715de566 Bump @vue/compiler-sfc from 3.3.2 to 3.3.4
Bumps [@vue/compiler-sfc](https://github.com/vuejs/core/tree/HEAD/packages/compiler-sfc) from 3.3.2 to 3.3.4.
- [Release notes](https://github.com/vuejs/core/releases)
- [Changelog](https://github.com/vuejs/core/blob/main/CHANGELOG.md)
- [Commits](https://github.com/vuejs/core/commits/v3.3.4/packages/compiler-sfc)

---
updated-dependencies:
- dependency-name: "@vue/compiler-sfc"
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-05-22 03:57:37 +00:00
dependabot[bot]
93e3c89f20 Bump guzzlehttp/guzzle from 7.6.0 to 7.7.0
Bumps [guzzlehttp/guzzle](https://github.com/guzzle/guzzle) from 7.6.0 to 7.7.0.
- [Release notes](https://github.com/guzzle/guzzle/releases)
- [Changelog](https://github.com/guzzle/guzzle/blob/7.7/CHANGELOG.md)
- [Commits](https://github.com/guzzle/guzzle/compare/7.6.0...7.7.0)

---
updated-dependencies:
- dependency-name: guzzlehttp/guzzle
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-05-22 03:56:53 +00:00
dependabot[bot]
b0456c5252 Bump fakerphp/faker from 1.21.0 to 1.22.0
Bumps [fakerphp/faker](https://github.com/FakerPHP/Faker) from 1.21.0 to 1.22.0.
- [Release notes](https://github.com/FakerPHP/Faker/releases)
- [Changelog](https://github.com/FakerPHP/Faker/blob/main/CHANGELOG.md)
- [Commits](https://github.com/FakerPHP/Faker/compare/v1.21.0...v1.22.0)

---
updated-dependencies:
- dependency-name: fakerphp/faker
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-05-22 03:56:46 +00:00
dependabot[bot]
f7fa03ddd8 Bump laravel/framework from 10.10.1 to 10.11.0
Bumps [laravel/framework](https://github.com/laravel/framework) from 10.10.1 to 10.11.0.
- [Release notes](https://github.com/laravel/framework/releases)
- [Changelog](https://github.com/laravel/framework/blob/10.x/CHANGELOG.md)
- [Commits](https://github.com/laravel/framework/compare/v10.10.1...v10.11.0)

---
updated-dependencies:
- dependency-name: laravel/framework
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-05-22 03:56:41 +00:00
James Cole
4c78e23a9c Merge pull request #7523 from firefly-iii/fix-7522
Fix 7522
2023-05-19 05:44:33 +02:00
James Cole
79c2065471 fix: Add relevant periods to addPeriod 2023-05-19 05:43:50 +02:00
James Cole
c19b89ac93 Fix: budget amounts 2023-05-19 05:39:21 +02:00
James Cole
62a1837d61 fix: debug would always report midnight. 2023-05-19 05:38:50 +02:00
James Cole
56b34aa624 Merge pull request #7517 from firefly-iii/fix-7516
Fix #7516
2023-05-18 05:38:42 +02:00
James Cole
e8392155f9 Fix #7516 2023-05-18 05:38:17 +02:00
James Cole
6d532470e6 Merge pull request #7515 from firefly-iii/fix-7514
Fix #7514
2023-05-17 15:20:09 +02:00
James Cole
15f683ef7e Fix #7514 2023-05-17 15:19:27 +02:00
James Cole
18ba2e563e Merge pull request #7513 from firefly-iii/fix-7505
Fix #7505
2023-05-17 07:02:39 +02:00
James Cole
63984f1c37 Fix #7505 2023-05-17 07:02:08 +02:00
James Cole
3c082dcf0e Restore cron options. 2023-05-16 21:04:06 +02:00
James Cole
090eb55226 Merge pull request #7502 from firefly-iii/dependabot/composer/develop/guzzlehttp/guzzle-7.6.0
Bump guzzlehttp/guzzle from 7.5.1 to 7.6.0
2023-05-15 06:35:17 +02:00
James Cole
4706cd44de Fix rounding issues. 2023-05-15 06:33:30 +02:00
James Cole
cf7c01e5d0 Merge pull request #7503 from firefly-iii/feat/adjusted-budget
feat: a budget type that will rollover but also incorporate overspend…
2023-05-15 06:18:23 +02:00
James Cole
0b5e0a268a feat: a budget type that will rollover but also incorporate overspending from the previous period (if any) 2023-05-15 06:18:02 +02:00
dependabot[bot]
9eea4497e5 Bump guzzlehttp/guzzle from 7.5.1 to 7.6.0
Bumps [guzzlehttp/guzzle](https://github.com/guzzle/guzzle) from 7.5.1 to 7.6.0.
- [Release notes](https://github.com/guzzle/guzzle/releases)
- [Changelog](https://github.com/guzzle/guzzle/blob/7.6/CHANGELOG.md)
- [Commits](https://github.com/guzzle/guzzle/compare/7.5.1...7.6.0)

---
updated-dependencies:
- dependency-name: guzzlehttp/guzzle
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-05-15 03:56:23 +00:00
James Cole
63fdc2487f Merge pull request #7499 from firefly-iii/remove-logging
Remove logging
2023-05-13 06:43:30 +02:00
James Cole
cf59da7e0c Remove logging 2023-05-13 06:43:07 +02:00
James Cole
e0621affb6 Merge tag 'v6.0.10' into develop
v6.0.10
2023-05-13 06:34:38 +02:00
James Cole
6d0906c37b Merge branch 'release/v6.0.10' 2023-05-13 06:34:37 +02:00
James Cole
a3ede0c6f6 Meta files for new release. 2023-05-13 06:34:12 +02:00
James Cole
72eab3c0eb Merge pull request #7498 from firefly-iii/fix-7478
Fix #7478
2023-05-13 06:17:44 +02:00
James Cole
c530961546 Fix #7478 2023-05-13 06:17:22 +02:00
James Cole
dd7aba0b51 Merge pull request #7497 from firefly-iii/fix-7448-2
Fix #7448
2023-05-13 06:09:24 +02:00
James Cole
7c54e17a30 Fix #7448 2023-05-13 06:09:04 +02:00
James Cole
342d72b0a6 Merge pull request #7495 from firefly-iii/expand-fix
Fix decimals command expanded.
2023-05-13 06:07:15 +02:00
James Cole
22ee504e52 Fix decimals command expanded. 2023-05-13 05:56:49 +02:00
James Cole
4880ee850e Merge pull request #7494 from firefly-iii/fix-7444
Fix 7444
2023-05-13 05:32:05 +02:00
James Cole
b45ce27817 Fix #7444 2023-05-13 05:31:41 +02:00
James Cole
dfad93d9ec Merge pull request #7473 from firefly-iii/dependabot/npm_and_yarn/develop/uiv-1.4.3
Bump uiv from 1.4.2 to 1.4.3
2023-05-08 06:16:02 +02:00
James Cole
52712c8cb2 Merge pull request #7472 from firefly-iii/dependabot/composer/develop/ergebnis/phpstan-rules-2.0.0
Bump ergebnis/phpstan-rules from 1.0.0 to 2.0.0
2023-05-08 06:15:52 +02:00
James Cole
740874e654 Merge pull request #7471 from firefly-iii/dependabot/composer/develop/spatie/laravel-ignition-2.1.1
Bump spatie/laravel-ignition from 2.1.0 to 2.1.1
2023-05-08 06:15:44 +02:00
James Cole
0f1f37a5df Merge pull request #7470 from firefly-iii/dependabot/composer/develop/laravel/sanctum-3.2.5
Bump laravel/sanctum from 3.2.4 to 3.2.5
2023-05-08 06:07:43 +02:00
dependabot[bot]
d609cbfb16 Bump uiv from 1.4.2 to 1.4.3
Bumps [uiv](https://github.com/uiv-lib/uiv) from 1.4.2 to 1.4.3.
- [Release notes](https://github.com/uiv-lib/uiv/releases)
- [Commits](https://github.com/uiv-lib/uiv/compare/v1.4.2...v1.4.3)

---
updated-dependencies:
- dependency-name: uiv
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-05-08 03:56:47 +00:00
dependabot[bot]
2375857c92 Bump ergebnis/phpstan-rules from 1.0.0 to 2.0.0
Bumps [ergebnis/phpstan-rules](https://github.com/ergebnis/phpstan-rules) from 1.0.0 to 2.0.0.
- [Release notes](https://github.com/ergebnis/phpstan-rules/releases)
- [Changelog](https://github.com/ergebnis/phpstan-rules/blob/main/CHANGELOG.md)
- [Commits](https://github.com/ergebnis/phpstan-rules/compare/1.0.0...2.0.0)

---
updated-dependencies:
- dependency-name: ergebnis/phpstan-rules
  dependency-type: direct:development
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-05-08 03:56:37 +00:00
dependabot[bot]
10275eb832 Bump spatie/laravel-ignition from 2.1.0 to 2.1.1
Bumps [spatie/laravel-ignition](https://github.com/spatie/laravel-ignition) from 2.1.0 to 2.1.1.
- [Release notes](https://github.com/spatie/laravel-ignition/releases)
- [Changelog](https://github.com/spatie/laravel-ignition/blob/main/CHANGELOG.md)
- [Commits](https://github.com/spatie/laravel-ignition/compare/2.1.0...2.1.1)

---
updated-dependencies:
- dependency-name: spatie/laravel-ignition
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-05-08 03:56:33 +00:00
dependabot[bot]
108867b2ef Bump laravel/sanctum from 3.2.4 to 3.2.5
Bumps [laravel/sanctum](https://github.com/laravel/sanctum) from 3.2.4 to 3.2.5.
- [Release notes](https://github.com/laravel/sanctum/releases)
- [Changelog](https://github.com/laravel/sanctum/blob/3.x/CHANGELOG.md)
- [Commits](https://github.com/laravel/sanctum/compare/v3.2.4...v3.2.5)

---
updated-dependencies:
- dependency-name: laravel/sanctum
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-05-08 03:56:26 +00:00
James Cole
e5a77a86f9 Fix a few commands. 2023-05-07 20:17:29 +02:00
James Cole
309d3e8e95 Fix missing account validation step. 2023-05-06 15:59:31 +02:00
James Cole
1ef9b83180 Merge pull request #7466 from firefly-iii/fix-7456
Fix #7456
2023-05-06 15:29:56 +02:00
James Cole
85757e1a20 Fix #7456 2023-05-06 15:29:29 +02:00
James Cole
e2a18e0e7c Merge pull request #7461 from eandersons/Focus-on-MFA-input-field
Focus on MFA input field on page load
2023-05-04 21:05:53 +02:00
Edgars
056af8fd8a Focus on MFA input field on page load 2023-05-04 15:13:47 +03:00
James Cole
c72a63f218 Merge pull request #7458 from firefly-iii/fix-7457
Fix #7457
2023-05-03 05:59:30 +02:00
James Cole
fb823ed422 Fix #7457 2023-05-03 05:59:10 +02:00
James Cole
3fae6c0cac Merge pull request #7451 from firefly-iii/dependabot/composer/develop/laravel/passport-11.8.7
Bump laravel/passport from 11.8.6 to 11.8.7
2023-05-02 08:21:36 +02:00
James Cole
55b1e22d37 Merge pull request #7452 from firefly-iii/dependabot/npm_and_yarn/develop/date-fns-2.30.0
Bump date-fns from 2.29.3 to 2.30.0
2023-05-02 08:21:27 +02:00
James Cole
e6b95c7894 Merge pull request #7450 from firefly-iii/dependabot/composer/develop/symfony/mailgun-mailer-6.2.10
Bump symfony/mailgun-mailer from 6.2.7 to 6.2.10
2023-05-01 10:42:30 +02:00
dependabot[bot]
ea2f9e4919 Bump symfony/mailgun-mailer from 6.2.7 to 6.2.10
Bumps [symfony/mailgun-mailer](https://github.com/symfony/mailgun-mailer) from 6.2.7 to 6.2.10.
- [Release notes](https://github.com/symfony/mailgun-mailer/releases)
- [Changelog](https://github.com/symfony/mailgun-mailer/blob/6.2/CHANGELOG.md)
- [Commits](https://github.com/symfony/mailgun-mailer/compare/v6.2.7...v6.2.10)

---
updated-dependencies:
- dependency-name: symfony/mailgun-mailer
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-05-01 07:46:51 +00:00
James Cole
08bd405e29 Merge pull request #7449 from firefly-iii/dependabot/composer/develop/symfony/http-client-6.2.10 2023-05-01 09:45:59 +02:00
dependabot[bot]
8294b2d526 Bump date-fns from 2.29.3 to 2.30.0
Bumps [date-fns](https://github.com/date-fns/date-fns) from 2.29.3 to 2.30.0.
- [Release notes](https://github.com/date-fns/date-fns/releases)
- [Changelog](https://github.com/date-fns/date-fns/blob/v2.30.0/CHANGELOG.md)
- [Commits](https://github.com/date-fns/date-fns/compare/v2.29.3...v2.30.0)

---
updated-dependencies:
- dependency-name: date-fns
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-05-01 03:57:00 +00:00
dependabot[bot]
b521fb8fae Bump laravel/passport from 11.8.6 to 11.8.7
Bumps [laravel/passport](https://github.com/laravel/passport) from 11.8.6 to 11.8.7.
- [Release notes](https://github.com/laravel/passport/releases)
- [Changelog](https://github.com/laravel/passport/blob/11.x/CHANGELOG.md)
- [Commits](https://github.com/laravel/passport/compare/v11.8.6...v11.8.7)

---
updated-dependencies:
- dependency-name: laravel/passport
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-05-01 03:56:45 +00:00
dependabot[bot]
3e9789d5e6 Bump symfony/http-client from 6.2.9 to 6.2.10
Bumps [symfony/http-client](https://github.com/symfony/http-client) from 6.2.9 to 6.2.10.
- [Release notes](https://github.com/symfony/http-client/releases)
- [Changelog](https://github.com/symfony/http-client/blob/6.2/CHANGELOG.md)
- [Commits](https://github.com/symfony/http-client/compare/v6.2.9...v6.2.10)

---
updated-dependencies:
- dependency-name: symfony/http-client
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-05-01 03:56:27 +00:00
James Cole
13b029d7f0 Merge pull request #7447 from firefly-iii/fix-7446
Fix #7446
2023-04-30 19:13:34 +02:00
James Cole
59427ba5c2 Fix #7446 2023-04-30 19:12:49 +02:00
James Cole
46bba9d799 Various optimizations in budget limit handling. 2023-04-30 06:45:25 +02:00
James Cole
0ef1d1834f Fix template 2023-04-29 19:19:53 +02:00
James Cole
e39b2f5355 Fix template 2023-04-29 17:39:01 +02:00
James Cole
03dae53714 Fix template 2023-04-29 14:40:12 +02:00
James Cole
6be6187532 Add base build info. 2023-04-29 11:15:30 +02:00
James Cole
4c26f613ee Merge pull request #7443 from firefly-iii/expand-health-check
Change health endpoint to include a DB check.
2023-04-29 07:44:56 +02:00
James Cole
765de2eeba Change health endpoint to include a DB check. 2023-04-29 07:44:37 +02:00
James Cole
49b1fef7ff Merge pull request #7442 from firefly-iii/fix-iban-check
Don't trigger on empty ibans.
2023-04-29 07:09:05 +02:00
James Cole
36157afc6a Don't trigger on empty ibans. 2023-04-29 07:08:11 +02:00
James Cole
c5c3638dbc Merge tag '6.0.9' into develop
v6.0.9
2023-04-28 09:27:43 +02:00
James Cole
926665a8f5 Merge branch 'release/6.0.9' 2023-04-28 09:27:42 +02:00
James Cole
e35743ff42 Update meta files for new release. 2023-04-28 09:27:14 +02:00
James Cole
321743dbf6 Merge pull request #7439 from firefly-iii/fix-7394
Fix 7394
2023-04-28 09:06:48 +02:00
James Cole
c2e1e25489 Fix #7394 2023-04-28 09:06:05 +02:00
James Cole
222387adba Merge pull request #7438 from firefly-iii/division-by-zero
Fix division by zero
2023-04-28 08:39:54 +02:00
James Cole
335414f25a Fix division by zero 2023-04-28 08:39:30 +02:00
James Cole
ea903c105d Merge pull request #7437 from mindlessroman/patch-1
Update the links to the installation documentation
2023-04-27 17:16:39 +02:00
Hannah K
aab29852b4 Merge branch 'develop' into patch-1
Signed-off-by: Hannah K <7254163+mindlessroman@users.noreply.github.com>
2023-04-27 11:12:43 -04:00
Hannah K
aa17ea0b68 Update the links to the installation documentation
Signed-off-by: Hannah K <7254163+mindlessroman@users.noreply.github.com>
2023-04-27 11:02:38 -04:00
James Cole
deeb5bf118 Merge pull request #7435 from firefly-iii/better-ab-mgt
Remove dangerous eternal loop
2023-04-26 12:13:22 +02:00
James Cole
47d5e8d169 Remove dangerous eternal loop 2023-04-26 12:12:23 +02:00
James Cole
033d61abbb Merge pull request #7434 from firefly-iii/better-ab-mgt
Better management and calculation of available budgets.
2023-04-26 11:32:18 +02:00
James Cole
28efc15820 Better management and calculation of available budgets. 2023-04-26 11:31:46 +02:00
James Cole
1c7988fad2 Fix #7389 2023-04-26 06:59:42 +02:00
James Cole
c8077762ba Merge pull request #7433 from firefly-iii/remove-debug
Remove debug logging.
2023-04-26 06:41:53 +02:00
James Cole
ea53b34cbb Remove debug logging. 2023-04-26 06:41:06 +02:00
James Cole
270ac87e65 Merge pull request #7432 from firefly-iii/max-values
Add sensible maximum values.
2023-04-26 06:17:50 +02:00
James Cole
0a60f63bf8 Add sensible maximum values. 2023-04-26 06:17:04 +02:00
James Cole
38ed70243e Merge pull request #7431 from firefly-iii/fix-validation
Add validation check.
2023-04-26 06:00:56 +02:00
James Cole
0f2a9a9b37 Add validation check. 2023-04-26 06:00:04 +02:00
James Cole
ec525849fc Merge pull request #7430 from firefly-iii/fix-validation
Fix length validation
2023-04-26 05:56:20 +02:00
James Cole
dee1e1a79d Fix length validation 2023-04-26 05:55:31 +02:00
James Cole
98b5ed9e5b Merge pull request #7429 from firefly-iii/error-rate-bills
Add rule for notes and better escaping in errors.
2023-04-26 05:30:06 +02:00
James Cole
d8eb084240 Add rule for notes and better escaping in errors. 2023-04-26 05:29:28 +02:00
James Cole
c2f5fbe7d3 Merge pull request #7428 from noxonad/patch-1
Fixed misleading documentation links in readme.md
2023-04-25 16:16:29 +02:00
noxonad
60f6542a1b Fixed misleading documentation links in readme.md
Signed-off-by: noxonad <130460440+noxonad@users.noreply.github.com>
2023-04-25 13:11:34 +03:00
James Cole
93c2edf76c Merge pull request #7424 from firefly-iii/dependabot/composer/develop/guzzlehttp/guzzle-7.5.1
Bump guzzlehttp/guzzle from 7.5.0 to 7.5.1
2023-04-24 06:19:07 +02:00
James Cole
f74f4c5719 Merge pull request #7425 from firefly-iii/dependabot/npm_and_yarn/develop/axios-1.3.6
Bump axios from 1.3.5 to 1.3.6
2023-04-24 06:18:57 +02:00
James Cole
8c67c347e1 Merge pull request #7423 from firefly-iii/dependabot/composer/develop/nunomaduro/larastan-2.6.0
Bump nunomaduro/larastan from 2.5.1 to 2.6.0
2023-04-24 06:18:46 +02:00
dependabot[bot]
fcbc341f03 Bump nunomaduro/larastan from 2.5.1 to 2.6.0
Bumps [nunomaduro/larastan](https://github.com/nunomaduro/larastan) from 2.5.1 to 2.6.0.
- [Release notes](https://github.com/nunomaduro/larastan/releases)
- [Changelog](https://github.com/nunomaduro/larastan/blob/master/RELEASE.md)
- [Commits](https://github.com/nunomaduro/larastan/compare/2.5.1...v2.6.0)

---
updated-dependencies:
- dependency-name: nunomaduro/larastan
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-04-24 04:18:39 +00:00
dependabot[bot]
2dbce10483 Bump guzzlehttp/guzzle from 7.5.0 to 7.5.1
Bumps [guzzlehttp/guzzle](https://github.com/guzzle/guzzle) from 7.5.0 to 7.5.1.
- [Release notes](https://github.com/guzzle/guzzle/releases)
- [Changelog](https://github.com/guzzle/guzzle/blob/7.5/CHANGELOG.md)
- [Commits](https://github.com/guzzle/guzzle/compare/7.5.0...7.5.1)

---
updated-dependencies:
- dependency-name: guzzlehttp/guzzle
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-04-24 04:18:36 +00:00
James Cole
8504b3e3a9 Merge pull request #7422 from firefly-iii/dependabot/npm_and_yarn/develop/postcss-8.4.23
Bump postcss from 8.4.22 to 8.4.23
2023-04-24 06:18:36 +02:00
James Cole
d4ab5dcefd Merge pull request #7421 from firefly-iii/dependabot/composer/develop/diglactic/laravel-breadcrumbs-8.1.1
Bump diglactic/laravel-breadcrumbs from 8.1.0 to 8.1.1
2023-04-24 06:17:55 +02:00
James Cole
5d11e285bc Merge pull request #7420 from firefly-iii/dependabot/composer/develop/laravel/framework-10.8.0
Bump laravel/framework from 10.7.1 to 10.8.0
2023-04-24 06:10:25 +02:00
James Cole
259e1350d5 Merge pull request #7419 from firefly-iii/dependabot/composer/develop/phpstan/phpstan-1.10.14
Bump phpstan/phpstan from 1.10.13 to 1.10.14
2023-04-24 06:08:16 +02:00
dependabot[bot]
dd54ec6122 Bump axios from 1.3.5 to 1.3.6
Bumps [axios](https://github.com/axios/axios) from 1.3.5 to 1.3.6.
- [Release notes](https://github.com/axios/axios/releases)
- [Changelog](https://github.com/axios/axios/blob/v1.x/CHANGELOG.md)
- [Commits](https://github.com/axios/axios/compare/v1.3.5...v1.3.6)

---
updated-dependencies:
- dependency-name: axios
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-04-24 03:57:31 +00:00
dependabot[bot]
c2b3791336 Bump postcss from 8.4.22 to 8.4.23
Bumps [postcss](https://github.com/postcss/postcss) from 8.4.22 to 8.4.23.
- [Release notes](https://github.com/postcss/postcss/releases)
- [Changelog](https://github.com/postcss/postcss/blob/main/CHANGELOG.md)
- [Commits](https://github.com/postcss/postcss/compare/8.4.22...8.4.23)

---
updated-dependencies:
- dependency-name: postcss
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-04-24 03:57:08 +00:00
dependabot[bot]
fc1f15cc14 Bump diglactic/laravel-breadcrumbs from 8.1.0 to 8.1.1
Bumps [diglactic/laravel-breadcrumbs](https://github.com/diglactic/laravel-breadcrumbs) from 8.1.0 to 8.1.1.
- [Release notes](https://github.com/diglactic/laravel-breadcrumbs/releases)
- [Commits](https://github.com/diglactic/laravel-breadcrumbs/compare/v8.1.0...v8.1.1)

---
updated-dependencies:
- dependency-name: diglactic/laravel-breadcrumbs
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-04-24 03:57:00 +00:00
dependabot[bot]
5d74979f50 Bump laravel/framework from 10.7.1 to 10.8.0
Bumps [laravel/framework](https://github.com/laravel/framework) from 10.7.1 to 10.8.0.
- [Release notes](https://github.com/laravel/framework/releases)
- [Changelog](https://github.com/laravel/framework/blob/10.x/CHANGELOG.md)
- [Commits](https://github.com/laravel/framework/compare/v10.7.1...v10.8.0)

---
updated-dependencies:
- dependency-name: laravel/framework
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-04-24 03:56:49 +00:00
dependabot[bot]
5dea7e5b41 Bump phpstan/phpstan from 1.10.13 to 1.10.14
Bumps [phpstan/phpstan](https://github.com/phpstan/phpstan) from 1.10.13 to 1.10.14.
- [Release notes](https://github.com/phpstan/phpstan/releases)
- [Changelog](https://github.com/phpstan/phpstan/blob/1.11.x/CHANGELOG.md)
- [Commits](https://github.com/phpstan/phpstan/compare/1.10.13...1.10.14)

---
updated-dependencies:
- dependency-name: phpstan/phpstan
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-04-24 03:56:31 +00:00
James Cole
a53a8a8529 Merge pull request #7417 from firefly-iii/fix-7410
Fix #7410
2023-04-23 18:24:20 +02:00
James Cole
aac7a2691d Fix #7410 2023-04-23 18:23:02 +02:00
James Cole
10e7be1729 Merge branch 'main' into develop 2023-04-22 06:43:09 +02:00
James Cole
9b1319f970 Fix bad math in page counter. 2023-04-22 06:42:26 +02:00
James Cole
a38f909919 Add some debug. 2023-04-22 06:17:46 +02:00
James Cole
d8c0192f54 Merge pull request #7413 from firefly-iii/dependabot/composer/nyholm/psr7-1.7.0
Bump nyholm/psr7 from 1.6.0 to 1.7.0
2023-04-22 05:55:33 +02:00
dependabot[bot]
1e8d294b8d Bump nyholm/psr7 from 1.6.0 to 1.7.0
Bumps [nyholm/psr7](https://github.com/Nyholm/psr7) from 1.6.0 to 1.7.0.
- [Release notes](https://github.com/Nyholm/psr7/releases)
- [Changelog](https://github.com/Nyholm/psr7/blob/master/CHANGELOG.md)
- [Commits](https://github.com/Nyholm/psr7/compare/1.6.0...1.7.0)

---
updated-dependencies:
- dependency-name: nyholm/psr7
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-04-21 20:52:03 +00:00
James Cole
d3be64114b Merge pull request #7403 from firefly-iii/dependabot/composer/guzzlehttp/psr7-2.5.0 2023-04-20 07:26:39 +02:00
dependabot[bot]
1bddd4da8e Bump guzzlehttp/psr7 from 2.4.4 to 2.5.0
Bumps [guzzlehttp/psr7](https://github.com/guzzle/psr7) from 2.4.4 to 2.5.0.
- [Release notes](https://github.com/guzzle/psr7/releases)
- [Changelog](https://github.com/guzzle/psr7/blob/2.5/CHANGELOG.md)
- [Commits](https://github.com/guzzle/psr7/compare/2.4.4...2.5.0)

---
updated-dependencies:
- dependency-name: guzzlehttp/psr7
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-04-19 21:07:24 +00:00
James Cole
6b5ff2680b Update lock.yml
Signed-off-by: James Cole <james@firefly-iii.org>
2023-04-19 10:12:51 +02:00
James Cole
efe17f638a Update lock.yml
Signed-off-by: James Cole <james@firefly-iii.org>
2023-04-19 06:43:31 +02:00
James Cole
3c1f4b7377 Update lock.yml
Signed-off-by: James Cole <james@firefly-iii.org>
2023-04-19 06:43:19 +02:00
James Cole
acfc214eb1 Update lock.yml
Signed-off-by: James Cole <james@firefly-iii.org>
2023-04-19 06:42:00 +02:00
James Cole
fe1c605c11 Update lock.yml
Wonder if this works.

Signed-off-by: James Cole <james@firefly-iii.org>
2023-04-19 06:38:09 +02:00
James Cole
891cd94031 Merge branch 'main' into develop 2023-04-17 06:17:42 +02:00
James Cole
c620d57f42 Update lock.yml
Signed-off-by: James Cole <james@firefly-iii.org>
2023-04-17 06:16:07 +02:00
James Cole
b076c92eb0 Update lock.yml
Signed-off-by: James Cole <james@firefly-iii.org>
2023-04-17 06:15:07 +02:00
James Cole
9e35216e98 Merge branch 'main' into develop 2023-04-17 06:09:33 +02:00
James Cole
3fa4734ba7 Merge pull request #7388 from firefly-iii/dependabot/npm_and_yarn/develop/postcss-8.4.22
Bump postcss from 8.4.21 to 8.4.22
2023-04-17 05:57:52 +02:00
dependabot[bot]
0144d09325 Bump postcss from 8.4.21 to 8.4.22
Bumps [postcss](https://github.com/postcss/postcss) from 8.4.21 to 8.4.22.
- [Release notes](https://github.com/postcss/postcss/releases)
- [Changelog](https://github.com/postcss/postcss/blob/main/CHANGELOG.md)
- [Commits](https://github.com/postcss/postcss/compare/8.4.21...8.4.22)

---
updated-dependencies:
- dependency-name: postcss
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-04-17 03:57:03 +00:00
James Cole
f28274aded Update stale.yml
Add epic

Signed-off-by: James Cole <james@firefly-iii.org>
2023-04-17 05:52:00 +02:00
James Cole
d5f5df82b6 Fix small commands 2023-04-16 08:01:40 +02:00
James Cole
49c27aff2d Merge pull request #7385 from firefly-iii/duplicate-commands
Remove duplicate commands.
2023-04-16 07:56:18 +02:00
James Cole
7b1b0cfef9 Remove duplicate commands. 2023-04-16 07:49:53 +02:00
James Cole
f728bdeb5a Merge pull request #7384 from firefly-iii/fix-commands
Fix method name
2023-04-16 07:39:47 +02:00
James Cole
4712a826d1 Fix method name 2023-04-16 07:38:54 +02:00
James Cole
d7335d71ea Merge pull request #7383 from firefly-iii/fix-commands
Fix start and upgrade commands
2023-04-16 07:33:37 +02:00
James Cole
e6a84ab387 Fix start and upgrade commands 2023-04-16 07:33:12 +02:00
James Cole
fd5269490d Merge pull request #7382 from firefly-iii/fix-7377
Another fix for #7377
2023-04-16 06:59:41 +02:00
James Cole
05e307136c Another fix for #7377 2023-04-16 06:59:19 +02:00
James Cole
2c41215e84 Merge pull request #7380 from firefly-iii/fix-7377
Fix #7377
2023-04-16 06:56:54 +02:00
James Cole
d9dc394e7f Fix #7377 2023-04-16 06:56:11 +02:00
James Cole
a63daf6166 Merge tag 'v6.0.8' into develop
v6.0.8
2023-04-15 10:46:24 +02:00
James Cole
f878af0d3b Merge branch 'release/v6.0.8' 2023-04-15 10:46:23 +02:00
James Cole
def0578421 Merge pull request #7371 from firefly-iii/release-608
Update meta-files for new release.
2023-04-15 10:45:36 +02:00
James Cole
a2e07b1518 Update meta-files for new release. 2023-04-15 10:44:58 +02:00
James Cole
dc26ce308d Add decrypt message. 2023-04-15 10:33:33 +02:00
James Cole
0189b91d3b Add deleted check to attachment filter 2023-04-15 10:19:54 +02:00
James Cole
fb6706648e Merge pull request #7370 from firefly-iii/fix-installer
Fix installer
2023-04-15 10:19:34 +02:00
James Cole
3c20fd7533 Fix installer 2023-04-15 10:14:14 +02:00
James Cole
82f89ef614 Merge pull request #7369 from firefly-iii/fix-date-fields
Fix date fields
2023-04-15 07:21:26 +02:00
James Cole
4d10ae91b7 Fix date fields 2023-04-15 07:21:06 +02:00
James Cole
aebb677c21 Add some debug info to transaction counter. 2023-04-15 07:17:48 +02:00
James Cole
abf9c65b21 Merge pull request #7358 from firefly-iii/fix-7355
Fix #7355
2023-04-12 19:58:19 +02:00
James Cole
524dcc7d97 Fix #7355 2023-04-12 06:18:05 +02:00
James Cole
0a4f6fd6b8 Merge pull request #7354 from firefly-iii/redirect
Redirect when unauthenticated.
2023-04-10 14:21:26 +02:00
James Cole
9c4beab0a7 Redirect when unauthenticated. 2023-04-10 14:21:10 +02:00
James Cole
b91e019416 Merge pull request #7353 from firefly-iii/migration-checks
Catch all possible migration errors
2023-04-10 08:29:49 +02:00
James Cole
ad97e33ec0 Catch all possible migration errors 2023-04-10 08:29:27 +02:00
James Cole
b1479b5dae Merge pull request #7352 from firefly-iii/force-commit
Add commit call to force the commands to go through.
2023-04-10 07:20:02 +02:00
James Cole
f1445b0132 Add commit call to force the commands to go through. 2023-04-10 07:19:10 +02:00
James Cole
456dbfd29d Merge pull request #7351 from firefly-iii/add-command
Add decimal command.
2023-04-09 20:29:57 +02:00
James Cole
0eea776b8b Add decimal command. 2023-04-09 20:29:35 +02:00
James Cole
853a97307b Merge pull request #7350 from firefly-iii/fix-7349
Fix 7349
2023-04-09 18:24:08 +02:00
James Cole
3b28b5d07a Fix #7349 2023-04-09 18:23:45 +02:00
James Cole
a7bfa503d9 Merge pull request #7348 from firefly-iii/fix-7347
Fix #7347
2023-04-09 13:45:22 +02:00
James Cole
a7c3d32370 Fix #7347 2023-04-09 13:45:01 +02:00
James Cole
c64ddbec1f Merge tag 'v6.0.7' into develop
v6.0.7
2023-04-08 08:58:40 +02:00
James Cole
6535f86001 Merge branch 'release/v6.0.7' 2023-04-08 08:58:39 +02:00
James Cole
531abc9f3d Merge pull request #7344 from firefly-iii/release-607
Meta for new release
2023-04-08 08:44:21 +02:00
James Cole
f7a02bdc2a Meta for new release 2023-04-08 08:43:41 +02:00
James Cole
af38f31147 Merge branch 'main' into develop 2023-04-08 06:57:40 +02:00
James Cole
4b4b5ef319 Merge pull request #7343 from firefly-iii/dark-mode-button
Dark mode button
2023-04-08 06:56:05 +02:00
James Cole
88fd76f0f1 Dark mode button 2023-04-08 06:55:38 +02:00
James Cole
3d1d064720 Merge pull request #7342 from firefly-iii/fix-7310
Fix #7310
2023-04-08 06:39:54 +02:00
James Cole
9ca8161588 Fix #7310 2023-04-08 06:39:25 +02:00
James Cole
5eb2b2fc5e Merge pull request #7341 from firefly-iii/fix-7311
Fix #7311
2023-04-08 06:29:10 +02:00
James Cole
d991df89c8 Fix #7311 2023-04-08 06:28:45 +02:00
James Cole
49339ea9b0 Merge pull request #7340 from firefly-iii/catch-errors
Catch errors
2023-04-08 06:28:22 +02:00
James Cole
561359b14f Add command to force migrations. 2023-04-07 20:54:15 +02:00
James Cole
79a4eec96e Catch DB errors 2023-04-07 19:33:19 +02:00
James Cole
dd11f98be7 Catch errors in database table create statements. 2023-04-07 18:21:12 +02:00
James Cole
40e2bf7cac Merge pull request #7335 from fengkaijia/patch-1
Fix upload attachment via API
2023-04-07 17:01:08 +02:00
James Cole
73e3a11be9 Merge pull request #7333 from firefly-iii/JC5-patch-1
Update cleanup.yml
2023-04-06 09:12:05 +02:00
James Cole
a180c37c58 Update cleanup.yml
Signed-off-by: James Cole <james@firefly-iii.org>
2023-04-06 09:11:55 +02:00
Kaijia Feng
aff802713e Fix upload attachment via API
Signed-off-by: Kaijia Feng <feng@kaijia.me>
2023-04-06 15:07:35 +08:00
James Cole
ebc7fad1fa Merge pull request #7331 from firefly-iii/error-catching
Various improved error catching.
2023-04-05 20:22:54 +02:00
James Cole
5068fc76c1 Various improved error catching. 2023-04-05 20:22:17 +02:00
James Cole
70b6e39cd7 Merge pull request #7323 from firefly-iii/dependabot/composer/develop/phpstan/phpstan-1.10.10
Bump phpstan/phpstan from 1.10.9 to 1.10.10
2023-04-03 08:51:15 +02:00
dependabot[bot]
31fc915b51 Bump phpstan/phpstan from 1.10.9 to 1.10.10
Bumps [phpstan/phpstan](https://github.com/phpstan/phpstan) from 1.10.9 to 1.10.10.
- [Release notes](https://github.com/phpstan/phpstan/releases)
- [Changelog](https://github.com/phpstan/phpstan/blob/1.10.x/CHANGELOG.md)
- [Commits](https://github.com/phpstan/phpstan/compare/1.10.9...1.10.10)

---
updated-dependencies:
- dependency-name: phpstan/phpstan
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-04-03 03:56:30 +00:00
James Cole
dfed56ed1b Merge pull request #7320 from firefly-iii/email-defaults
Better defaults for email.
2023-04-02 19:43:53 +02:00
James Cole
7f6d2877fb Better defaults for email. 2023-04-02 19:43:24 +02:00
James Cole
d9315dcbfe Merge pull request #7319 from firefly-iii/fix-7317
Fix #7317
2023-04-02 19:42:32 +02:00
James Cole
6fbf4ec6f1 Fix #7317 2023-04-02 19:42:06 +02:00
James Cole
2e32acc3c9 Merge pull request #7309 from firefly-iii/fix-7308
Fix https://github.com/firefly-iii/firefly-iii/issues/7308
2023-04-01 10:44:47 +02:00
James Cole
328216534b Fix https://github.com/firefly-iii/firefly-iii/issues/7308 2023-04-01 10:44:09 +02:00
James Cole
dea6e2c83f Merge tag 'v6.0.6' into develop
v6.0.6
2023-04-01 07:51:42 +02:00
James Cole
31f4f08e54 Merge branch 'release/v6.0.6' 2023-04-01 07:51:40 +02:00
James Cole
c4f2519b6f Update meta files for new release v6.0.6. 2023-04-01 07:50:53 +02:00
James Cole
0359a98681 Merge pull request #7307 from firefly-iii/fix-7248
Fix #7248
2023-04-01 07:11:53 +02:00
James Cole
c69b24c1d2 Fix #7248 2023-04-01 07:11:30 +02:00
James Cole
d50c560ed2 Merge pull request #7306 from firefly-iii/improve-contrast
Improved contrast for dark mode
2023-04-01 07:09:59 +02:00
James Cole
21ffd70523 Merge pull request #7305 from firefly-iii/fix-7261
Fix #7261
2023-04-01 07:09:34 +02:00
James Cole
664e9fe8da Fix #7261 2023-04-01 07:09:20 +02:00
James Cole
c948490eb6 Merge pull request #7304 from firefly-iii/use-facade
Use another facade
2023-04-01 07:05:21 +02:00
James Cole
5b3bcc7611 Merge pull request #7303 from firefly-iii/fox-expense
Fix issue with opposing account creation
2023-04-01 07:05:00 +02:00
James Cole
c7d9ca9a61 Use another facade 2023-04-01 07:04:42 +02:00
James Cole
259bad4487 Fix issue with opposing account creation 2023-04-01 07:02:51 +02:00
James Cole
73d3a82519 Merge pull request #7302 from firefly-iii/ac-accounts
Expand AC
2023-03-31 19:23:08 +02:00
James Cole
6f4ca53907 Merge pull request #7301 from firefly-iii/fix-7299
Fix #7299
2023-03-31 19:22:38 +02:00
James Cole
5111aaa123 Merge pull request #7300 from firefly-iii/mail-error
Mail error
2023-03-31 19:21:58 +02:00
James Cole
c903b82b7b Less dramatic mail error 2023-03-31 19:21:29 +02:00
James Cole
ed00d97ff9 Fix #7299 2023-03-31 19:21:09 +02:00
James Cole
9939ed0aaf Expand AC 2023-03-31 19:20:26 +02:00
James Cole
8ea32714f6 Merge pull request #7280 from firefly-iii/dependabot/composer/develop/phpstan/phpstan-1.10.8
Bump phpstan/phpstan from 1.10.7 to 1.10.8
2023-03-27 06:23:18 +02:00
James Cole
f9fb77690b Merge pull request #7281 from firefly-iii/dependabot/composer/develop/league/commonmark-2.4.0
Bump league/commonmark from 2.3.9 to 2.4.0
2023-03-27 06:23:08 +02:00
James Cole
98b28c75b7 Merge pull request #7279 from firefly-iii/fix-7278
Fix https://github.com/firefly-iii/firefly-iii/issues/7278
2023-03-27 06:22:42 +02:00
dependabot[bot]
405be07ba8 Bump league/commonmark from 2.3.9 to 2.4.0
Bumps [league/commonmark](https://github.com/thephpleague/commonmark) from 2.3.9 to 2.4.0.
- [Release notes](https://github.com/thephpleague/commonmark/releases)
- [Changelog](https://github.com/thephpleague/commonmark/blob/2.4/CHANGELOG.md)
- [Commits](https://github.com/thephpleague/commonmark/compare/2.3.9...2.4.0)

---
updated-dependencies:
- dependency-name: league/commonmark
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-03-27 03:56:35 +00:00
dependabot[bot]
5a84e222fd Bump phpstan/phpstan from 1.10.7 to 1.10.8
Bumps [phpstan/phpstan](https://github.com/phpstan/phpstan) from 1.10.7 to 1.10.8.
- [Release notes](https://github.com/phpstan/phpstan/releases)
- [Changelog](https://github.com/phpstan/phpstan/blob/1.10.x/CHANGELOG.md)
- [Commits](https://github.com/phpstan/phpstan/compare/1.10.7...1.10.8)

---
updated-dependencies:
- dependency-name: phpstan/phpstan
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-03-27 03:56:28 +00:00
James Cole
36b0cf04ba Fix https://github.com/firefly-iii/firefly-iii/issues/7278 2023-03-26 19:19:10 +02:00
James Cole
70c11d6634 Merge pull request #7274 from firefly-iii/fix-bad-rule-action
Fix bad rule action
2023-03-25 13:43:20 +01:00
James Cole
eebfb0cb40 Fixes issue where rule actions would find the wrong account. 2023-03-25 13:42:26 +01:00
James Cole
2500cc55e2 Merge pull request #7273 from firefly-iii/ac-accounts
Ac accounts
2023-03-25 13:18:29 +01:00
James Cole
c3b99c322d Function autocomplete button 2023-03-25 13:18:05 +01:00
James Cole
976128a435 Rule action will create revenue account instead of search for liability 2023-03-25 11:34:29 +01:00
James Cole
3be55adaeb Fix route 2023-03-25 11:34:02 +01:00
James Cole
141a828947 Improved contrast for dark mode 2023-03-25 11:33:42 +01:00
James Cole
0386d5e09f Partial implementation of administration aware account auto complete 2023-03-25 11:32:33 +01:00
James Cole
17d308cfde Merge pull request #7257 from firefly-iii/dependabot/composer/develop/phpstan/phpstan-deprecation-rules-1.1.3 2023-03-20 07:16:58 +01:00
James Cole
c540e3ff71 Merge pull request #7256 from firefly-iii/dependabot/composer/develop/laravel/framework-10.4.1 2023-03-20 06:33:30 +01:00
dependabot[bot]
8641cbd619 Bump phpstan/phpstan-deprecation-rules from 1.1.2 to 1.1.3
Bumps [phpstan/phpstan-deprecation-rules](https://github.com/phpstan/phpstan-deprecation-rules) from 1.1.2 to 1.1.3.
- [Release notes](https://github.com/phpstan/phpstan-deprecation-rules/releases)
- [Commits](https://github.com/phpstan/phpstan-deprecation-rules/compare/1.1.2...1.1.3)

---
updated-dependencies:
- dependency-name: phpstan/phpstan-deprecation-rules
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-03-20 05:09:25 +00:00
James Cole
70f76cd538 Merge pull request #7255 from firefly-iii/dependabot/composer/develop/phpstan/phpstan-1.10.7 2023-03-20 06:04:50 +01:00
dependabot[bot]
420a765295 Bump laravel/framework from 10.3.3 to 10.4.1
Bumps [laravel/framework](https://github.com/laravel/framework) from 10.3.3 to 10.4.1.
- [Release notes](https://github.com/laravel/framework/releases)
- [Changelog](https://github.com/laravel/framework/blob/10.x/CHANGELOG.md)
- [Commits](https://github.com/laravel/framework/compare/v10.3.3...v10.4.1)

---
updated-dependencies:
- dependency-name: laravel/framework
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-03-20 03:56:46 +00:00
dependabot[bot]
c926d85c8b Bump phpstan/phpstan from 1.10.6 to 1.10.7
Bumps [phpstan/phpstan](https://github.com/phpstan/phpstan) from 1.10.6 to 1.10.7.
- [Release notes](https://github.com/phpstan/phpstan/releases)
- [Changelog](https://github.com/phpstan/phpstan/blob/1.10.x/CHANGELOG.md)
- [Commits](https://github.com/phpstan/phpstan/compare/1.10.6...1.10.7)

---
updated-dependencies:
- dependency-name: phpstan/phpstan
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-03-20 03:56:27 +00:00
James Cole
7668a854f7 Merge pull request #7251 from firefly-iii/accuracy-fix
Better accuracy for database. Does not affect current users.
2023-03-19 10:39:57 +01:00
James Cole
c30e1c1973 Better accuracy for database. Does not affect current users. 2023-03-19 10:39:40 +01:00
James Cole
bd556f1934 Merge branch 'release/v6.0.5' 2023-03-18 14:49:05 +01:00
James Cole
9530e928d5 Merge tag 'v6.0.5' into develop
v6.0.5
2023-03-18 14:49:05 +01:00
James Cole
ae367aa736 Merge pull request #7246 from firefly-iii/v605
Meta files for v6.0.5
2023-03-18 14:47:52 +01:00
James Cole
3ccff2969b Meta files for v6.0.5 2023-03-18 14:47:35 +01:00
James Cole
530abb1da6 Merge pull request #7245 from firefly-iii/drop-bc-scale
Drop bc scale
2023-03-18 14:36:26 +01:00
James Cole
9fe70fb8d8 Drop BCscale significantly. This breaks support for long crypto currencies. 2023-03-18 14:35:08 +01:00
James Cole
b0215a23fb Merge branch 'main' into develop 2023-03-15 05:45:15 +01:00
James Cole
48735b1a5b Merge pull request #7233 from firefly-iii/dependabot/npm_and_yarn/frontend/webpack-5.76.1
Bump webpack from 5.72.0 to 5.76.1 in /frontend
2023-03-15 05:44:25 +01:00
dependabot[bot]
3c0b802667 Bump webpack from 5.72.0 to 5.76.1 in /frontend
Bumps [webpack](https://github.com/webpack/webpack) from 5.72.0 to 5.76.1.
- [Release notes](https://github.com/webpack/webpack/releases)
- [Commits](https://github.com/webpack/webpack/compare/v5.72.0...v5.76.1)

---
updated-dependencies:
- dependency-name: webpack
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-03-14 23:54:24 +00:00
James Cole
9bfad07f8c Merge pull request #7232 from firefly-iii/fix-7227
Fix https://github.com/firefly-iii/firefly-iii/issues/7227
2023-03-14 18:31:51 +01:00
James Cole
5c91da80e1 Merge pull request #7231 from firefly-iii/fix-7221
Fix https://github.com/firefly-iii/firefly-iii/issues/7221
2023-03-14 18:31:32 +01:00
James Cole
e465c93ffc Fix https://github.com/firefly-iii/firefly-iii/issues/7227 2023-03-14 18:30:59 +01:00
James Cole
8e56fa4ef8 Fix https://github.com/firefly-iii/firefly-iii/issues/7221 2023-03-14 18:09:44 +01:00
James Cole
f56de6e719 Merge pull request #7218 from firefly-iii/develop
Release v6.0.4
2023-03-12 18:25:25 +01:00
James Cole
86ba1d151a Merge pull request #7217 from firefly-iii/v604
v604 into develop
2023-03-12 18:24:40 +01:00
James Cole
8d24db14e9 Update packages. 2023-03-12 18:23:18 +01:00
James Cole
cead122d96 Meta files for new release 2023-03-12 18:22:56 +01:00
James Cole
b7dd335fb7 Meta files for release v6.0.4 2023-03-12 18:18:02 +01:00
James Cole
20a7092fe3 Merge pull request #7213 from marcoil/catalan_name
Update Catalan description
2023-03-12 16:09:24 +01:00
James Cole
1d3da33e1d Merge pull request #7216 from firefly-iii/fix-7214
Possible fix for #7214
2023-03-12 16:06:31 +01:00
James Cole
e36675e232 Possible fix for #7214 2023-03-12 16:06:12 +01:00
Marc Ordinas i Llopis
aa8588758a Update Catalan description
Signed-off-by: Marc Ordinas i Llopis <mail@marcoil.org>
2023-03-12 13:48:06 +01:00
716 changed files with 18119 additions and 12325 deletions

View File

@@ -22,12 +22,12 @@
$current = __DIR__;
$paths = [
$current . '/../../app',
$current . '/../../config',
$current . '/../../database',
$current . '/../../routes',
$current . '/../../tests',
$current . '/../../resources/lang',
$current.'/../../app',
$current.'/../../config',
$current.'/../../database',
$current.'/../../routes',
$current.'/../../tests',
$current.'/../../resources/lang',
];
$finder = PhpCsFixer\Finder::create()
@@ -36,9 +36,9 @@ $finder = PhpCsFixer\Finder::create()
$config = new PhpCsFixer\Config();
return $config->setRules([
'@PSR12' => true,
'strict_param' => true,
'array_syntax' => ['syntax' => 'short'],
'@PSR12' => true,
'declare_strict_types' => true,
'strict_param' => true,
'array_syntax' => ['syntax' => 'short'],
])
->setFinder($finder)
;
->setFinder($finder);

View File

@@ -379,16 +379,16 @@
},
{
"name": "friendsofphp/php-cs-fixer",
"version": "v3.14.4",
"version": "v3.17.0",
"source": {
"type": "git",
"url": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer.git",
"reference": "1b3d9dba63d93b8a202c31e824748218781eae6b"
"reference": "3f0ed862f22386c55a767461ef5083bddceeed79"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/PHP-CS-Fixer/PHP-CS-Fixer/zipball/1b3d9dba63d93b8a202c31e824748218781eae6b",
"reference": "1b3d9dba63d93b8a202c31e824748218781eae6b",
"url": "https://api.github.com/repos/PHP-CS-Fixer/PHP-CS-Fixer/zipball/3f0ed862f22386c55a767461ef5083bddceeed79",
"reference": "3f0ed862f22386c55a767461ef5083bddceeed79",
"shasum": ""
},
"require": {
@@ -455,9 +455,15 @@
}
],
"description": "A tool to automatically fix PHP code style",
"keywords": [
"Static code analysis",
"fixer",
"standards",
"static analysis"
],
"support": {
"issues": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/issues",
"source": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/tree/v3.14.4"
"source": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/tree/v3.17.0"
},
"funding": [
{
@@ -465,7 +471,7 @@
"type": "github"
}
],
"time": "2023-02-09T21:49:13+00:00"
"time": "2023-05-22T19:59:32+00:00"
},
{
"name": "psr/cache",
@@ -671,16 +677,16 @@
},
{
"name": "sebastian/diff",
"version": "5.0.0",
"version": "5.0.3",
"source": {
"type": "git",
"url": "https://github.com/sebastianbergmann/diff.git",
"reference": "70dd1b20bc198da394ad542e988381b44e64e39f"
"reference": "912dc2fbe3e3c1e7873313cc801b100b6c68c87b"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/70dd1b20bc198da394ad542e988381b44e64e39f",
"reference": "70dd1b20bc198da394ad542e988381b44e64e39f",
"url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/912dc2fbe3e3c1e7873313cc801b100b6c68c87b",
"reference": "912dc2fbe3e3c1e7873313cc801b100b6c68c87b",
"shasum": ""
},
"require": {
@@ -725,7 +731,8 @@
],
"support": {
"issues": "https://github.com/sebastianbergmann/diff/issues",
"source": "https://github.com/sebastianbergmann/diff/tree/5.0.0"
"security": "https://github.com/sebastianbergmann/diff/security/policy",
"source": "https://github.com/sebastianbergmann/diff/tree/5.0.3"
},
"funding": [
{
@@ -733,20 +740,20 @@
"type": "github"
}
],
"time": "2023-02-03T07:00:31+00:00"
"time": "2023-05-01T07:48:21+00:00"
},
{
"name": "symfony/console",
"version": "v6.2.7",
"version": "v6.2.10",
"source": {
"type": "git",
"url": "https://github.com/symfony/console.git",
"reference": "cbad09eb8925b6ad4fb721c7a179344dc4a19d45"
"reference": "12288d9f4500f84a4d02254d4aa968b15488476f"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/console/zipball/cbad09eb8925b6ad4fb721c7a179344dc4a19d45",
"reference": "cbad09eb8925b6ad4fb721c7a179344dc4a19d45",
"url": "https://api.github.com/repos/symfony/console/zipball/12288d9f4500f84a4d02254d4aa968b15488476f",
"reference": "12288d9f4500f84a4d02254d4aa968b15488476f",
"shasum": ""
},
"require": {
@@ -808,12 +815,12 @@
"homepage": "https://symfony.com",
"keywords": [
"cli",
"command line",
"command-line",
"console",
"terminal"
],
"support": {
"source": "https://github.com/symfony/console/tree/v6.2.7"
"source": "https://github.com/symfony/console/tree/v6.2.10"
},
"funding": [
{
@@ -829,7 +836,7 @@
"type": "tidelift"
}
],
"time": "2023-02-25T17:00:03+00:00"
"time": "2023-04-28T13:37:43+00:00"
},
{
"name": "symfony/deprecation-contracts",
@@ -900,16 +907,16 @@
},
{
"name": "symfony/event-dispatcher",
"version": "v6.2.7",
"version": "v6.2.8",
"source": {
"type": "git",
"url": "https://github.com/symfony/event-dispatcher.git",
"reference": "404b307de426c1c488e5afad64403e5f145e82a5"
"reference": "04046f35fd7d72f9646e721fc2ecb8f9c67d3339"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/404b307de426c1c488e5afad64403e5f145e82a5",
"reference": "404b307de426c1c488e5afad64403e5f145e82a5",
"url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/04046f35fd7d72f9646e721fc2ecb8f9c67d3339",
"reference": "04046f35fd7d72f9646e721fc2ecb8f9c67d3339",
"shasum": ""
},
"require": {
@@ -963,7 +970,7 @@
"description": "Provides tools that allow your application components to communicate with each other by dispatching events and listening to them",
"homepage": "https://symfony.com",
"support": {
"source": "https://github.com/symfony/event-dispatcher/tree/v6.2.7"
"source": "https://github.com/symfony/event-dispatcher/tree/v6.2.8"
},
"funding": [
{
@@ -979,7 +986,7 @@
"type": "tidelift"
}
],
"time": "2023-02-14T08:44:56+00:00"
"time": "2023-03-20T16:06:02+00:00"
},
{
"name": "symfony/event-dispatcher-contracts",
@@ -1062,16 +1069,16 @@
},
{
"name": "symfony/filesystem",
"version": "v6.2.7",
"version": "v6.2.10",
"source": {
"type": "git",
"url": "https://github.com/symfony/filesystem.git",
"reference": "82b6c62b959f642d000456f08c6d219d749215b3"
"reference": "fd588debf7d1bc16a2c84b4b3b71145d9946b894"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/filesystem/zipball/82b6c62b959f642d000456f08c6d219d749215b3",
"reference": "82b6c62b959f642d000456f08c6d219d749215b3",
"url": "https://api.github.com/repos/symfony/filesystem/zipball/fd588debf7d1bc16a2c84b4b3b71145d9946b894",
"reference": "fd588debf7d1bc16a2c84b4b3b71145d9946b894",
"shasum": ""
},
"require": {
@@ -1105,7 +1112,7 @@
"description": "Provides basic utilities for the filesystem",
"homepage": "https://symfony.com",
"support": {
"source": "https://github.com/symfony/filesystem/tree/v6.2.7"
"source": "https://github.com/symfony/filesystem/tree/v6.2.10"
},
"funding": [
{
@@ -1121,7 +1128,7 @@
"type": "tidelift"
}
],
"time": "2023-02-14T08:44:56+00:00"
"time": "2023-04-18T13:46:08+00:00"
},
{
"name": "symfony/finder",
@@ -1748,16 +1755,16 @@
},
{
"name": "symfony/process",
"version": "v6.2.7",
"version": "v6.2.10",
"source": {
"type": "git",
"url": "https://github.com/symfony/process.git",
"reference": "680e8a2ea6b3f87aecc07a6a65a203ae573d1902"
"reference": "b34cdbc9c5e75d45a3703e63a48ad07aafa8bf2e"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/process/zipball/680e8a2ea6b3f87aecc07a6a65a203ae573d1902",
"reference": "680e8a2ea6b3f87aecc07a6a65a203ae573d1902",
"url": "https://api.github.com/repos/symfony/process/zipball/b34cdbc9c5e75d45a3703e63a48ad07aafa8bf2e",
"reference": "b34cdbc9c5e75d45a3703e63a48ad07aafa8bf2e",
"shasum": ""
},
"require": {
@@ -1789,7 +1796,7 @@
"description": "Executes commands in sub-processes",
"homepage": "https://symfony.com",
"support": {
"source": "https://github.com/symfony/process/tree/v6.2.7"
"source": "https://github.com/symfony/process/tree/v6.2.10"
},
"funding": [
{
@@ -1805,7 +1812,7 @@
"type": "tidelift"
}
],
"time": "2023-02-24T10:42:00+00:00"
"time": "2023-04-18T13:56:57+00:00"
},
{
"name": "symfony/service-contracts",
@@ -1956,16 +1963,16 @@
},
{
"name": "symfony/string",
"version": "v6.2.7",
"version": "v6.2.8",
"source": {
"type": "git",
"url": "https://github.com/symfony/string.git",
"reference": "67b8c1eec78296b85dc1c7d9743830160218993d"
"reference": "193e83bbd6617d6b2151c37fff10fa7168ebddef"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/string/zipball/67b8c1eec78296b85dc1c7d9743830160218993d",
"reference": "67b8c1eec78296b85dc1c7d9743830160218993d",
"url": "https://api.github.com/repos/symfony/string/zipball/193e83bbd6617d6b2151c37fff10fa7168ebddef",
"reference": "193e83bbd6617d6b2151c37fff10fa7168ebddef",
"shasum": ""
},
"require": {
@@ -2022,7 +2029,7 @@
"utf8"
],
"support": {
"source": "https://github.com/symfony/string/tree/v6.2.7"
"source": "https://github.com/symfony/string/tree/v6.2.8"
},
"funding": [
{
@@ -2038,7 +2045,7 @@
"type": "tidelift"
}
],
"time": "2023-02-24T10:42:00+00:00"
"time": "2023-03-20T16:06:02+00:00"
}
],
"packages-dev": [],

View File

@@ -31,6 +31,7 @@ SCRIPT_DIR="$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )
# clean up php code
cd $SCRIPT_DIR/php-cs-fixer
composer update
rm -f .php-cs-fixer.cache
PHP_CS_FIXER_IGNORE_ENV=true ./vendor/bin/php-cs-fixer fix --config $SCRIPT_DIR/php-cs-fixer/.php-cs-fixer.php --allow-risky=yes
cd $SCRIPT_DIR/..

View File

@@ -13,6 +13,7 @@ hu_HU
id_ID
it_IT
ja_JP
ko_KR
nb_NO
nl_NL
pl_PL

View File

@@ -1,16 +0,0 @@
name: Sonarcloud CI
on:
workflow_dispatch:
jobs:
sonarcloud:
name: SonarCloud
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
with:
fetch-depth: 0 # Shallow clones should be disabled for a better relevancy of analysis
- name: SonarCloud Scan
uses: SonarSource/sonarcloud-github-action@master
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} # Needed to get PR information, if any
SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}

View File

@@ -55,7 +55,6 @@ jobs:
// because we track the duration of runs over time
const workflows = [
'build.yml',
'cleanup.yml',
'depsreview.yaml',
'laravel.yml',

View File

@@ -5,26 +5,15 @@ on:
schedule:
- cron: '0 0 * * *'
permissions:
contents: read
jobs:
lock:
permissions:
issues: write # for dessant/lock-threads to lock issues
pull-requests: write # for dessant/lock-threads to lock PRs
issues: write
pull-requests: write
runs-on: ubuntu-latest
steps:
- uses: dessant/lock-threads@v4
- uses: JC5/lock-threads@main
with:
github-token: ${{ github.token }}
issue-lock-inactive-days: '90'
issue-comment: >
Hi there! This is an automatic reply. `Share and enjoy`
This issue is now `locked` :lock:.
- If you feel there is more to be said about this specific issue, please feel free to open a new issue. Please refer to this issue for clarity.
- Follow-up questions and comments can also be posted in a new [discussion](https://github.com/firefly-iii/firefly-iii/discussions/)
Thank you for your consideration.
issue-inactive-days: 90
pr-inactive-days: 90

View File

@@ -31,4 +31,4 @@ jobs:
Thank you for your contributions.
days-before-stale: 14
days-before-close: 7
exempt-issue-labels: 'enhancement,feature,bug,announcement,layout-v3'
exempt-issue-labels: 'enhancement,feature,bug,announcement,epic'

View File

@@ -85,12 +85,11 @@ abstract class Controller extends BaseController
{
$bag = new ParameterBag();
$page = (int)request()->get('page');
if ($page < 1) {
$page = 1;
}
if ($page > (2 ^ 16)) {
$page = (2 ^ 16);
if ($page > pow(2, 16)) {
$page = pow(2, 16);
}
$bag->set('page', $page);

View File

@@ -30,7 +30,7 @@ use FireflyIII\Repositories\Account\AccountRepositoryInterface;
use FireflyIII\Transformers\AccountTransformer;
use Illuminate\Http\JsonResponse;
use League\Fractal\Resource\Item;
use Log;
use Illuminate\Support\Facades\Log;
use Preferences;
/**

View File

@@ -35,7 +35,7 @@ use FireflyIII\User;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use League\Fractal\Resource\Item;
use Log;
use Illuminate\Support\Facades\Log;
/**
* Class StoreController

View File

@@ -24,7 +24,7 @@ declare(strict_types=1);
namespace FireflyIII\Api\V1\Controllers\Models\BudgetLimit;
use FireflyIII\Api\V1\Controllers\Controller;
use FireflyIII\Api\V1\Requests\Data\DateRequest;
use FireflyIII\Api\V1\Requests\Data\SameDateRequest;
use FireflyIII\Exceptions\FireflyException;
use FireflyIII\Models\Budget;
use FireflyIII\Models\BudgetLimit;
@@ -108,12 +108,12 @@ class ShowController extends Controller
*
* Display a listing of the budget limits for this budget.
*
* @param DateRequest $request
* @param SameDateRequest $request
*
* @return JsonResponse
* @throws FireflyException
*/
public function indexAll(DateRequest $request): JsonResponse
public function indexAll(SameDateRequest $request): JsonResponse
{
$manager = $this->getManager();
$manager->parseIncludes('budget');

View File

@@ -33,7 +33,7 @@ use FireflyIII\Repositories\Journal\JournalRepositoryInterface;
use FireflyIII\Repositories\TransactionGroup\TransactionGroupRepository;
use FireflyIII\User;
use Illuminate\Http\JsonResponse;
use Log;
use Illuminate\Support\Facades\Log;
/**
* Class DestroyController

View File

@@ -37,7 +37,7 @@ use FireflyIII\User;
use Illuminate\Http\JsonResponse;
use Illuminate\Validation\ValidationException;
use League\Fractal\Resource\Item;
use Log;
use Illuminate\Support\Facades\Log;
use Validator;
/**

View File

@@ -33,7 +33,7 @@ use FireflyIII\Transformers\TransactionGroupTransformer;
use FireflyIII\User;
use Illuminate\Http\JsonResponse;
use League\Fractal\Resource\Item;
use Log;
use Illuminate\Support\Facades\Log;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
/**

View File

@@ -35,7 +35,7 @@ use Illuminate\Pagination\LengthAwarePaginator;
use JsonException;
use League\Fractal\Pagination\IlluminatePaginatorAdapter;
use League\Fractal\Resource\Collection as FractalCollection;
use Log;
use Illuminate\Support\Facades\Log;
/**
* Class AccountController

View File

@@ -71,6 +71,8 @@ class TransactionController extends Controller
$resource = new Collection($transactions, $transformer, 'transactions');
$resource->setPaginator(new IlluminatePaginatorAdapter($groups));
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', self::CONTENT_TYPE);
$array = $manager->createData($resource)->toArray();
return response()->json($array)->header('Content-Type', self::CONTENT_TYPE);
}
}

View File

@@ -29,7 +29,7 @@ use FireflyIII\Exceptions\FireflyException;
use FireflyIII\Repositories\User\UserRepositoryInterface;
use FireflyIII\Support\Binder\EitherConfigKey;
use Illuminate\Http\JsonResponse;
use Log;
use Illuminate\Support\Facades\Log;
use Psr\Container\ContainerExceptionInterface;
use Psr\Container\NotFoundExceptionInterface;
use Validator;

View File

@@ -27,7 +27,7 @@ use FireflyIII\Api\V1\Controllers\Controller;
use FireflyIII\Api\V1\Requests\System\CronRequest;
use FireflyIII\Support\Http\Controllers\CronRunner;
use Illuminate\Http\JsonResponse;
use Log;
use Illuminate\Support\Facades\Log;
/**
* Class CronController
@@ -54,6 +54,10 @@ class CronController extends Controller
$return = [];
$return['recurring_transactions'] = $this->runRecurring($config['force'], $config['date']);
$return['auto_budgets'] = $this->runAutoBudget($config['force'], $config['date']);
if (true === config('cer.enabled')) {
$return['exchange_rates'] = $this->exchangeRatesCronJob($config['force'], $config['date']);
}
$return['bill_warnings'] = $this->billWarningCronJob($config['force'], $config['date']);
return response()->json($return);
}

View File

@@ -32,7 +32,7 @@ use FireflyIII\Validation\Api\Data\Bulk\ValidatesBulkTransactionQuery;
use Illuminate\Foundation\Http\FormRequest;
use Illuminate\Validation\Validator;
use JsonException;
use Log;
use Illuminate\Support\Facades\Log;
/**
* Class TransactionRequest

View File

@@ -57,7 +57,7 @@ class DestroyRequest extends FormRequest
',not_assets_liabilities';
return [
'objects' => sprintf('required|min:1|string|in:%s', $valid),
'objects' => sprintf('required|max:255|min:1|string|in:%s', $valid),
'unused' => 'in:true,false',
];
}

View File

@@ -73,7 +73,7 @@ class ExportRequest extends FormRequest
{
return [
'type' => 'in:csv',
'accounts' => 'min:1',
'accounts' => 'min:1|max:65536',
'start' => 'date|before:end',
'end' => 'date|after:start',
];

View File

@@ -0,0 +1,66 @@
<?php
/*
* DateRequest.php
* Copyright (c) 2021 james@firefly-iii.org
*
* This file is part of Firefly III (https://github.com/firefly-iii).
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
declare(strict_types=1);
namespace FireflyIII\Api\V1\Requests\Data;
use FireflyIII\Support\Request\ChecksLogin;
use FireflyIII\Support\Request\ConvertsDataTypes;
use Illuminate\Foundation\Http\FormRequest;
/**
* Request class for end points that require date parameters.
*
* Class SameDateRequest
*/
class SameDateRequest extends FormRequest
{
use ConvertsDataTypes;
use ChecksLogin;
/**
* Get all data from the request.
*
* @return array
*/
public function getAll(): array
{
return [
'start' => $this->getCarbonDate('start'),
'end' => $this->getCarbonDate('end'),
];
}
/**
* The rules that the incoming request must be matched against.
*
* @return array
*/
public function rules(): array
{
return [
'start' => 'required|date',
'end' => 'required|date|after_or_equal:start',
];
}
}

View File

@@ -103,8 +103,8 @@ class StoreRequest extends FormRequest
$ccPaymentTypes = implode(',', array_keys(config('firefly.ccTypes')));
$type = $this->convertString('type');
$rules = [
'name' => 'required|min:1|uniqueAccountForUser',
'type' => 'required|min:1|'.sprintf('in:%s', $types),
'name' => 'required|max:1024|min:1|uniqueAccountForUser',
'type' => 'required|max:1024|min:1|'.sprintf('in:%s', $types),
'iban' => ['iban', 'nullable', new UniqueIban(null, $type)],
'bic' => 'bic|nullable',
'account_number' => ['between:1,255', 'nullable', new UniqueAccountNumber(null, $type)],
@@ -120,7 +120,7 @@ class StoreRequest extends FormRequest
'credit_card_type' => sprintf('nullable|in:%s|required_if:account_role,ccAsset', $ccPaymentTypes),
'monthly_payment_date' => 'nullable|date|required_if:account_role,ccAsset|required_if:credit_card_type,monthlyFull',
'liability_type' => 'nullable|required_if:type,liability|required_if:type,liabilities|in:loan,debt,mortgage',
'liability_amount' => 'required_with:liability_start_date|min:0|numeric',
'liability_amount' => 'required_with:liability_start_date|min:0|numeric|max:1000000000',
'liability_start_date' => 'required_with:liability_amount|date',
'liability_direction' => 'nullable|required_if:type,liability|required_if:type,liabilities|in:credit,debit',
'interest' => 'between:0,100|numeric',

View File

@@ -33,7 +33,7 @@ use FireflyIII\Support\Request\AppendsLocationData;
use FireflyIII\Support\Request\ChecksLogin;
use FireflyIII\Support\Request\ConvertsDataTypes;
use Illuminate\Foundation\Http\FormRequest;
use Log;
use Illuminate\Support\Facades\Log;
/**
* Class UpdateRequest
@@ -63,9 +63,9 @@ class UpdateRequest extends FormRequest
'account_role' => ['account_role', 'convertString'],
'liability_type' => ['liability_type', 'convertString'],
'opening_balance' => ['opening_balance', 'convertString'],
'opening_balance_date' => ['opening_balance_date', 'date'],
'opening_balance_date' => ['opening_balance_date', 'convertDateTime'],
'cc_type' => ['credit_card_type', 'convertString'],
'cc_monthly_payment_date' => ['monthly_payment_date', 'convertString'],
'cc_monthly_payment_date' => ['monthly_payment_date', 'convertDateTime'],
'notes' => ['notes', 'stringWithNewlines'],
'interest' => ['interest', 'convertString'],
'interest_period' => ['interest_period', 'convertString'],
@@ -94,7 +94,7 @@ class UpdateRequest extends FormRequest
$ccPaymentTypes = implode(',', array_keys(config('firefly.ccTypes')));
$rules = [
'name' => sprintf('min:1|uniqueAccountForUser:%d', $account->id),
'name' => sprintf('min:1|max:1024|uniqueAccountForUser:%d', $account->id),
'type' => sprintf('in:%s', $types),
'iban' => ['iban', 'nullable', new UniqueIban($account, $this->convertString('type'))],
'bic' => 'bic|nullable',
@@ -104,7 +104,7 @@ class UpdateRequest extends FormRequest
'virtual_balance' => 'numeric|nullable',
'order' => 'numeric|nullable',
'currency_id' => 'numeric|exists:transaction_currencies,id',
'currency_code' => 'min:3|max:3|exists:transaction_currencies,code',
'currency_code' => 'min:3|max:51|exists:transaction_currencies,code',
'active' => [new IsBoolean()],
'include_net_worth' => [new IsBoolean()],
'account_role' => sprintf('in:%s|nullable|required_if:type,asset', $accountRoles),

View File

@@ -67,7 +67,7 @@ class Request extends FormRequest
{
return [
'currency_id' => 'numeric|exists:transaction_currencies,id',
'currency_code' => 'min:3|max:3|exists:transaction_currencies,code',
'currency_code' => 'min:3|max:51|exists:transaction_currencies,code',
'amount' => 'numeric|gt:0',
'start' => 'date',
'end' => 'date',

View File

@@ -29,7 +29,7 @@ use FireflyIII\Support\Request\ChecksLogin;
use FireflyIII\Support\Request\ConvertsDataTypes;
use Illuminate\Foundation\Http\FormRequest;
use Illuminate\Validation\Validator;
use Log;
use Illuminate\Support\Facades\Log;
/**
* Class StoreRequest
@@ -82,7 +82,7 @@ class StoreRequest extends FormRequest
'amount_min' => 'numeric|gt:0|required',
'amount_max' => 'numeric|gt:0|required',
'currency_id' => 'numeric|exists:transaction_currencies,id',
'currency_code' => 'min:3|max:3|exists:transaction_currencies,code',
'currency_code' => 'min:3|max:51|exists:transaction_currencies,code',
'date' => 'date|required',
'end_date' => 'date|after:date',
'extension_date' => 'date|after:date',
@@ -105,8 +105,8 @@ class StoreRequest extends FormRequest
$validator->after(
static function (Validator $validator) {
$data = $validator->getData();
$min = $data['amount_min'] ?? '0';
$max = $data['amount_max'] ?? '0';
$min = (string) ($data['amount_min'] ?? '0');
$max = (string) ($data['amount_max'] ?? '0');
if (1 === bccomp($min, $max)) {
$validator->errors()->add('amount_min', (string)trans('validation.amount_min_over_max'));

View File

@@ -84,7 +84,7 @@ class UpdateRequest extends FormRequest
'amount_min' => 'numeric|gt:0',
'amount_max' => 'numeric|gt:0',
'currency_id' => 'numeric|exists:transaction_currencies,id',
'currency_code' => 'min:3|max:3|exists:transaction_currencies,code',
'currency_code' => 'min:3|max:51|exists:transaction_currencies,code',
'date' => 'date',
'end_date' => 'date|after:date',
'extension_date' => 'date|after:date',

View File

@@ -79,9 +79,9 @@ class StoreRequest extends FormRequest
'currency_code' => 'exists:transaction_currencies,code',
'notes' => 'nullable|between:1,65536',
// auto budget info
'auto_budget_type' => 'in:reset,rollover,none',
'auto_budget_amount' => 'numeric|min:0|max:1000000000|required_if:auto_budget_type,reset|required_if:auto_budget_type,rollover',
'auto_budget_period' => 'in:daily,weekly,monthly,quarterly,half_year,yearly|required_if:auto_budget_type,reset|required_if:auto_budget_type,rollover',
'auto_budget_type' => 'in:reset,rollover,adjusted,none',
'auto_budget_amount' => 'numeric|min:0|max:1000000000|required_if:auto_budget_type,reset|required_if:auto_budget_type,rollover|required_if:auto_budget_type,adjusted',
'auto_budget_period' => 'in:daily,weekly,monthly,quarterly,half_year,yearly|required_if:auto_budget_type,reset|required_if:auto_budget_type,rollover|required_if:auto_budget_type,adjusted',
];
}

View File

@@ -67,6 +67,7 @@ class UpdateRequest extends FormRequest
'none' => 0,
'reset' => 1,
'rollover' => 2,
'adjusted' => 3,
];
$allData['auto_budget_type'] = $types[$allData['auto_budget_type']] ?? 0;
}
@@ -88,7 +89,7 @@ class UpdateRequest extends FormRequest
'name' => sprintf('between:1,100|uniqueObjectForUser:budgets,name,%d', $budget->id),
'active' => [new IsBoolean()],
'notes' => 'nullable|between:1,65536',
'auto_budget_type' => 'in:reset,rollover,none',
'auto_budget_type' => 'in:reset,rollover,adjusted,none',
'auto_budget_currency_id' => 'exists:transaction_currencies,id',
'auto_budget_currency_code' => 'exists:transaction_currencies,code',
'auto_budget_amount' => 'min:0|max:1000000000',

View File

@@ -65,7 +65,7 @@ class StoreRequest extends FormRequest
'end' => 'required|after:start|date',
'amount' => 'required|gt:0',
'currency_id' => 'numeric|exists:transaction_currencies,id',
'currency_code' => 'min:3|max:3|exists:transaction_currencies,code',
'currency_code' => 'min:3|max:51|exists:transaction_currencies,code',
];
}
}

View File

@@ -69,7 +69,7 @@ class UpdateRequest extends FormRequest
'end' => 'date',
'amount' => 'gt:0',
'currency_id' => 'numeric|exists:transaction_currencies,id',
'currency_code' => 'min:3|max:3|exists:transaction_currencies,code',
'currency_code' => 'min:3|max:51|exists:transaction_currencies,code',
];
}

View File

@@ -63,7 +63,7 @@ class UpdateRequest extends FormRequest
$objectGroup = $this->route()->parameter('objectGroup');
return [
'title' => sprintf('min:1|uniqueObjectGroup:%d', $objectGroup->id),
'title' => sprintf('max:1024|min:1|uniqueObjectGroup:%d', $objectGroup->id),
'order' => 'numeric',
];
}

View File

@@ -52,8 +52,8 @@ class UpdateRequest extends FormRequest
'account_id' => ['account_id', 'convertInteger'],
'targetamount' => ['target_amount', 'convertString'],
'current_amount' => ['current_amount', 'convertString'],
'startdate' => ['start_date', 'date'],
'targetdate' => ['target_date', 'convertString'],
'startdate' => ['start_date', 'convertDateTime'],
'targetdate' => ['target_date', 'convertDateTime'],
'notes' => ['notes', 'stringWithNewlines'],
'order' => ['order', 'convertInteger'],
'object_group_title' => ['object_group_title', 'convertString'],
@@ -76,7 +76,7 @@ class UpdateRequest extends FormRequest
return [
'name' => 'between:1,255|uniquePiggyBankForUser:'.$piggyBank->id,
'current_amount' => ['numeric', 'gte:0', new LessThanPiggyTarget()],
'target_amount' => 'numeric|gt:0',
'target_amount' => 'numeric|gte:0',
'start_date' => 'date|nullable',
'target_date' => 'date|nullable|after:start_date',
'notes' => 'max:65000',

View File

@@ -57,8 +57,8 @@ class StoreRequest extends FormRequest
'type' => ['type', 'convertString'],
'title' => ['title', 'convertString'],
'description' => ['description', 'convertString'],
'first_date' => ['first_date', 'date'],
'repeat_until' => ['repeat_until', 'date'],
'first_date' => ['first_date', 'convertDateTime'],
'repeat_until' => ['repeat_until', 'convertDateTime'],
'nr_of_repetitions' => ['nr_of_repetitions', 'convertInteger'],
'apply_rules' => ['apply_rules', 'boolean'],
'active' => ['active', 'boolean'],
@@ -158,9 +158,9 @@ class StoreRequest extends FormRequest
'transactions.*.amount' => 'required|numeric|gt:0',
'transactions.*.foreign_amount' => 'nullable|numeric|gt:0',
'transactions.*.currency_id' => 'nullable|numeric|exists:transaction_currencies,id',
'transactions.*.currency_code' => 'nullable|min:3|max:3|exists:transaction_currencies,code',
'transactions.*.currency_code' => 'nullable|min:3|max:51|exists:transaction_currencies,code',
'transactions.*.foreign_currency_id' => 'nullable|numeric|exists:transaction_currencies,id',
'transactions.*.foreign_currency_code' => 'nullable|min:3|max:3|exists:transaction_currencies,code',
'transactions.*.foreign_currency_code' => 'nullable|min:3|max:51|exists:transaction_currencies,code',
'transactions.*.source_id' => ['numeric', 'nullable', new BelongsUser()],
'transactions.*.source_name' => 'between:1,255|nullable',
'transactions.*.destination_id' => ['numeric', 'nullable', new BelongsUser()],

View File

@@ -58,8 +58,8 @@ class UpdateRequest extends FormRequest
$fields = [
'title' => ['title', 'convertString'],
'description' => ['description', 'convertString'],
'first_date' => ['first_date', 'date'],
'repeat_until' => ['repeat_until', 'date'],
'first_date' => ['first_date', 'convertDateTime'],
'repeat_until' => ['repeat_until', 'convertDateTime'],
'nr_of_repetitions' => ['nr_of_repetitions', 'convertInteger'],
'apply_rules' => ['apply_rules', 'boolean'],
'active' => ['active', 'boolean'],
@@ -172,9 +172,9 @@ class UpdateRequest extends FormRequest
'transactions.*.amount' => 'numeric|gt:0',
'transactions.*.foreign_amount' => 'nullable|numeric|gt:0',
'transactions.*.currency_id' => 'nullable|numeric|exists:transaction_currencies,id',
'transactions.*.currency_code' => 'nullable|min:3|max:3|exists:transaction_currencies,code',
'transactions.*.currency_code' => 'nullable|min:3|max:51|exists:transaction_currencies,code',
'transactions.*.foreign_currency_id' => 'nullable|numeric|exists:transaction_currencies,id',
'transactions.*.foreign_currency_code' => 'nullable|min:3|max:3|exists:transaction_currencies,code',
'transactions.*.foreign_currency_code' => 'nullable|min:3|max:51|exists:transaction_currencies,code',
'transactions.*.source_id' => ['numeric', 'nullable', new BelongsUser()],
'transactions.*.source_name' => 'between:1,255|nullable',
'transactions.*.destination_id' => ['numeric', 'nullable', new BelongsUser()],

View File

@@ -79,7 +79,7 @@ class StoreRequest extends FormRequest
$return[] = [
'type' => $trigger['type'],
'value' => $trigger['value'],
'active' => $this->convertBoolean((string)($trigger['active'] ?? 'false')),
'active' => $this->convertBoolean((string)($trigger['active'] ?? 'true')),
'stop_processing' => $this->convertBoolean((string)($trigger['stop_processing'] ?? 'false')),
];
}
@@ -100,7 +100,7 @@ class StoreRequest extends FormRequest
$return[] = [
'type' => $action['type'],
'value' => $action['value'],
'active' => $this->convertBoolean((string)($action['active'] ?? 'false')),
'active' => $this->convertBoolean((string)($action['active'] ?? 'true')),
'stop_processing' => $this->convertBoolean((string)($action['stop_processing'] ?? 'false')),
];
}
@@ -130,7 +130,7 @@ class StoreRequest extends FormRequest
'rule_group_title' => 'nullable|between:1,255|required_without:rule_group_id|belongsToUser:rule_groups,title',
'trigger' => 'required|in:store-journal,update-journal',
'triggers.*.type' => 'required|in:'.implode(',', $validTriggers),
'triggers.*.value' => 'required_if:actions.*.type,'.$contextTriggers.'|min:1|ruleTriggerValue',
'triggers.*.value' => 'required_if:actions.*.type,'.$contextTriggers.'|min:1|ruleTriggerValue|max:1024',
'triggers.*.stop_processing' => [new IsBoolean()],
'triggers.*.active' => [new IsBoolean()],
'actions.*.type' => 'required|in:'.implode(',', $validActions),

View File

@@ -147,7 +147,7 @@ class UpdateRequest extends FormRequest
'rule_group_title' => 'nullable|between:1,255|belongsToUser:rule_groups,title',
'trigger' => 'in:store-journal,update-journal',
'triggers.*.type' => 'required|in:'.implode(',', $validTriggers),
'triggers.*.value' => 'required_if:actions.*.type,'.$contextTriggers.'|min:1|ruleTriggerValue',
'triggers.*.value' => 'required_if:actions.*.type,'.$contextTriggers.'|min:1|ruleTriggerValue|max:1024',
'triggers.*.stop_processing' => [new IsBoolean()],
'triggers.*.active' => [new IsBoolean()],
'actions.*.type' => 'required|in:'.implode(',', $validActions),

View File

@@ -65,8 +65,8 @@ class StoreRequest extends FormRequest
public function rules(): array
{
$rules = [
'tag' => 'required|min:1|uniqueObjectForUser:tags,tag',
'description' => 'min:1|nullable',
'tag' => 'required|min:1|uniqueObjectForUser:tags,tag|max:1024',
'description' => 'min:1|nullable|max:65536',
'date' => 'date|nullable',
];

View File

@@ -71,8 +71,8 @@ class UpdateRequest extends FormRequest
$tag = $this->route()->parameter('tagOrId');
// TODO check if uniqueObjectForUser is obsolete
$rules = [
'tag' => 'min:1|uniqueObjectForUser:tags,tag,'.$tag->id,
'description' => 'min:1|nullable',
'tag' => 'min:1|max:1024|uniqueObjectForUser:tags,tag,'.$tag->id,
'description' => 'min:1|nullable|max:65536',
'date' => 'date|nullable',
];

View File

@@ -36,7 +36,7 @@ use FireflyIII\Validation\GroupValidation;
use FireflyIII\Validation\TransactionValidation;
use Illuminate\Foundation\Http\FormRequest;
use Illuminate\Validation\Validator;
use Log;
use Illuminate\Support\Facades\Log;
/**
* Class StoreRequest
@@ -188,9 +188,9 @@ class StoreRequest extends FormRequest
// currency info
'transactions.*.currency_id' => 'numeric|exists:transaction_currencies,id|nullable',
'transactions.*.currency_code' => 'min:3|max:3|exists:transaction_currencies,code|nullable',
'transactions.*.currency_code' => 'min:3|max:51|exists:transaction_currencies,code|nullable',
'transactions.*.foreign_currency_id' => 'numeric|exists:transaction_currencies,id|nullable',
'transactions.*.foreign_currency_code' => 'min:3|max:3|exists:transaction_currencies,code|nullable',
'transactions.*.foreign_currency_code' => 'min:3|max:51|exists:transaction_currencies,code|nullable',
// amount
'transactions.*.amount' => 'required|numeric|gt:0',
@@ -225,25 +225,25 @@ class StoreRequest extends FormRequest
// other interesting fields
'transactions.*.reconciled' => [new IsBoolean()],
'transactions.*.notes' => 'min:1,max:50000|nullable',
'transactions.*.notes' => 'min:1|max:50000|nullable',
'transactions.*.tags' => 'between:0,255',
// meta info fields
'transactions.*.internal_reference' => 'min:1,max:255|nullable',
'transactions.*.external_id' => 'min:1,max:255|nullable',
'transactions.*.recurrence_id' => 'min:1,max:255|nullable',
'transactions.*.bunq_payment_id' => 'min:1,max:255|nullable',
'transactions.*.external_url' => 'min:1,max:255|nullable|url',
'transactions.*.internal_reference' => 'min:1|max:255|nullable',
'transactions.*.external_id' => 'min:1|max:255|nullable',
'transactions.*.recurrence_id' => 'min:1|max:255|nullable',
'transactions.*.bunq_payment_id' => 'min:1|max:255|nullable',
'transactions.*.external_url' => 'min:1|max:255|nullable|url',
// SEPA fields:
'transactions.*.sepa_cc' => 'min:1,max:255|nullable',
'transactions.*.sepa_ct_op' => 'min:1,max:255|nullable',
'transactions.*.sepa_ct_id' => 'min:1,max:255|nullable',
'transactions.*.sepa_db' => 'min:1,max:255|nullable',
'transactions.*.sepa_country' => 'min:1,max:255|nullable',
'transactions.*.sepa_ep' => 'min:1,max:255|nullable',
'transactions.*.sepa_ci' => 'min:1,max:255|nullable',
'transactions.*.sepa_batch_id' => 'min:1,max:255|nullable',
'transactions.*.sepa_cc' => 'min:1|max:255|nullable',
'transactions.*.sepa_ct_op' => 'min:1|max:255|nullable',
'transactions.*.sepa_ct_id' => 'min:1|max:255|nullable',
'transactions.*.sepa_db' => 'min:1|max:255|nullable',
'transactions.*.sepa_country' => 'min:1|max:255|nullable',
'transactions.*.sepa_ep' => 'min:1|max:255|nullable',
'transactions.*.sepa_ci' => 'min:1|max:255|nullable',
'transactions.*.sepa_batch_id' => 'min:1|max:255|nullable',
// dates
'transactions.*.interest_date' => 'date|nullable',
@@ -270,7 +270,9 @@ class StoreRequest extends FormRequest
$this->validateTransactionArray($validator);
// must submit at least one transaction.
Log::debug('Now going to validateOneTransaction');
$this->validateOneTransaction($validator);
Log::debug('Now done with validateOneTransaction');
// all journals must have a description
$this->validateDescriptions($validator);

View File

@@ -24,6 +24,7 @@ declare(strict_types=1);
namespace FireflyIII\Api\V1\Requests\Models\Transaction;
use FireflyIII\Exceptions\FireflyException;
use FireflyIII\Models\TransactionGroup;
use FireflyIII\Rules\BelongsUser;
use FireflyIII\Rules\IsBoolean;
@@ -61,6 +62,7 @@ class UpdateRequest extends FormRequest
*/
public function getAll(): array
{
Log::debug(sprintf('Now in %s', __METHOD__));
$this->integerFields = [
'order',
@@ -163,6 +165,9 @@ class UpdateRequest extends FormRequest
/** @var array $transaction */
foreach ($this->get('transactions') as $transaction) {
if(!is_array($transaction)) {
throw new FireflyException('Invalid data submitted: transaction is not array.');
}
// default response is to update nothing in the transaction:
$current = [];
$current = $this->getIntegerData($current, $transaction);
@@ -295,7 +300,7 @@ class UpdateRequest extends FormRequest
if (array_key_exists($fieldName, $transaction)) {
$value = $transaction[$fieldName];
if (is_float($value)) {
$current[$fieldName] = sprintf('%.24f', $value);
$current[$fieldName] = sprintf('%.12f', $value);
}
if (!is_float($value)) {
$current[$fieldName] = (string)$value;
@@ -330,9 +335,9 @@ class UpdateRequest extends FormRequest
// currency info
'transactions.*.currency_id' => 'numeric|exists:transaction_currencies,id',
'transactions.*.currency_code' => 'min:3|max:3|exists:transaction_currencies,code',
'transactions.*.currency_code' => 'min:3|max:51|exists:transaction_currencies,code',
'transactions.*.foreign_currency_id' => 'nullable|numeric|exists:transaction_currencies,id',
'transactions.*.foreign_currency_code' => 'nullable|min:3|max:3|exists:transaction_currencies,code',
'transactions.*.foreign_currency_code' => 'nullable|min:3|max:51|exists:transaction_currencies,code',
// amount
'transactions.*.amount' => 'numeric|gt:0|max:100000000000',
@@ -359,25 +364,25 @@ class UpdateRequest extends FormRequest
// other interesting fields
'transactions.*.reconciled' => [new IsBoolean()],
'transactions.*.notes' => 'min:1,max:50000|nullable',
'transactions.*.notes' => 'min:1|max:50000|nullable',
'transactions.*.tags' => 'between:0,255',
// meta info fields
'transactions.*.internal_reference' => 'min:1,max:255|nullable',
'transactions.*.external_id' => 'min:1,max:255|nullable',
'transactions.*.recurrence_id' => 'min:1,max:255|nullable',
'transactions.*.bunq_payment_id' => 'min:1,max:255|nullable',
'transactions.*.external_url' => 'min:1,max:255|nullable|url',
'transactions.*.internal_reference' => 'min:1|max:255|nullable',
'transactions.*.external_id' => 'min:1|max:255|nullable',
'transactions.*.recurrence_id' => 'min:1|max:255|nullable',
'transactions.*.bunq_payment_id' => 'min:1|max:255|nullable',
'transactions.*.external_url' => 'min:1|max:255|nullable|url',
// SEPA fields:
'transactions.*.sepa_cc' => 'min:1,max:255|nullable',
'transactions.*.sepa_ct_op' => 'min:1,max:255|nullable',
'transactions.*.sepa_ct_id' => 'min:1,max:255|nullable',
'transactions.*.sepa_db' => 'min:1,max:255|nullable',
'transactions.*.sepa_country' => 'min:1,max:255|nullable',
'transactions.*.sepa_ep' => 'min:1,max:255|nullable',
'transactions.*.sepa_ci' => 'min:1,max:255|nullable',
'transactions.*.sepa_batch_id' => 'min:1,max:255|nullable',
'transactions.*.sepa_cc' => 'min:1|max:255|nullable',
'transactions.*.sepa_ct_op' => 'min:1|max:255|nullable',
'transactions.*.sepa_ct_id' => 'min:1|max:255|nullable',
'transactions.*.sepa_db' => 'min:1|max:255|nullable',
'transactions.*.sepa_country' => 'min:1|max:255|nullable',
'transactions.*.sepa_ep' => 'min:1|max:255|nullable',
'transactions.*.sepa_ci' => 'min:1|max:255|nullable',
'transactions.*.sepa_batch_id' => 'min:1|max:255|nullable',
// dates
'transactions.*.interest_date' => 'date|nullable',
@@ -398,6 +403,7 @@ class UpdateRequest extends FormRequest
*/
public function withValidator(Validator $validator): void
{
Log::debug('Now in withValidator');
/** @var TransactionGroup $transactionGroup */
$transactionGroup = $this->route()->parameter('transactionGroup');
$validator->after(

View File

@@ -75,7 +75,7 @@ class StoreRequest extends FormRequest
'name' => 'required|between:1,255|unique:transaction_currencies,name',
'code' => 'required|between:3,51|unique:transaction_currencies,code',
'symbol' => 'required|between:1,51|unique:transaction_currencies,symbol',
'decimal_places' => 'between:0,20|numeric|min:0|max:20',
'decimal_places' => 'between:0,20|numeric|min:0|max:12',
'enabled' => [new IsBoolean()],
'default' => [new IsBoolean()],

View File

@@ -74,7 +74,7 @@ class UpdateRequest extends FormRequest
'name' => sprintf('between:1,255|unique:transaction_currencies,name,%d', $currency->id),
'code' => sprintf('between:3,51|unique:transaction_currencies,code,%d', $currency->id),
'symbol' => sprintf('between:1,51|unique:transaction_currencies,symbol,%d', $currency->id),
'decimal_places' => 'between:0,20|numeric|min:0|max:20',
'decimal_places' => 'between:0,20|numeric|min:0|max:12',
'enabled' => [new IsBoolean()],
'default' => [new IsBoolean()],
];

View File

@@ -59,9 +59,9 @@ class StoreRequest extends FormRequest
public function rules(): array
{
return [
'name' => 'required|unique:link_types,name|min:1',
'outward' => 'required|unique:link_types,outward|min:1|different:inward',
'inward' => 'required|unique:link_types,inward|min:1|different:outward',
'name' => 'required|unique:link_types,name|min:1|max:1024',
'outward' => 'required|unique:link_types,outward|min:1|different:inward|max:1024',
'inward' => 'required|unique:link_types,inward|min:1|different:outward|max:1024',
];
}
}

View File

@@ -64,9 +64,9 @@ class UpdateRequest extends FormRequest
$linkType = $this->route()->parameter('linkType');
return [
'name' => [Rule::unique('link_types', 'name')->ignore($linkType->id), 'min:1'],
'outward' => ['different:inward', Rule::unique('link_types', 'outward')->ignore($linkType->id), 'min:1'],
'inward' => ['different:outward', Rule::unique('link_types', 'inward')->ignore($linkType->id), 'min:1'],
'name' => [Rule::unique('link_types', 'name')->ignore($linkType->id), 'min:1','max:1024'],
'outward' => ['different:inward', Rule::unique('link_types', 'outward')->ignore($linkType->id), 'min:1','max:1024'],
'inward' => ['different:outward', Rule::unique('link_types', 'inward')->ignore($linkType->id), 'min:1','max:1024'],
];
}
}

View File

@@ -25,10 +25,105 @@ declare(strict_types=1);
namespace FireflyIII\Api\V2\Controllers\Autocomplete;
use FireflyIII\Api\V2\Controllers\Controller;
use FireflyIII\Api\V2\Request\Autocomplete\AutocompleteRequest;
use FireflyIII\Exceptions\FireflyException;
use FireflyIII\Models\Account;
use FireflyIII\Models\AccountType;
use FireflyIII\Repositories\Administration\Account\AccountRepositoryInterface as AdminAccountRepositoryInterface;
use FireflyIII\Repositories\Account\AccountRepositoryInterface;
use FireflyIII\Support\Http\Api\AccountFilter;
use FireflyIII\User;
use Illuminate\Http\JsonResponse;
use JsonException;
/**
* Class AccountController
*/
class AccountController extends Controller
{
use AccountFilter;
private array $balanceTypes;
private AdminAccountRepositoryInterface $adminRepository;
private AccountRepositoryInterface $repository;
/**
* AccountController constructor.
*/
public function __construct()
{
parent::__construct();
$this->middleware(
function ($request, $next) {
/** @var User $user */
$user = auth()->user();
$this->repository = app(AccountRepositoryInterface::class);
$this->adminRepository = app(AdminAccountRepositoryInterface::class);
return $next($request);
}
);
$this->balanceTypes = [AccountType::ASSET, AccountType::LOAN, AccountType::DEBT, AccountType::MORTGAGE,];
}
/**
* Documentation for this endpoint:
* TODO endpoint is not documented.
*
* @param AutocompleteRequest $request
*
* @return JsonResponse
* @throws JsonException
* @throws FireflyException
* @throws FireflyException
*/
public function accounts(AutocompleteRequest $request): JsonResponse
{
$data = $request->getData();
$types = $data['types'];
$query = $data['query'];
$date = $data['date'] ?? today(config('app.timezone'));
$this->adminRepository->setAdministrationId($data['administration_id']);
$return = [];
$result = $this->adminRepository->searchAccount((string)$query, $types, $data['limit']);
$defaultCurrency = app('amount')->getDefaultCurrency();
/** @var Account $account */
foreach ($result as $account) {
$nameWithBalance = $account->name;
$currency = $this->repository->getAccountCurrency($account) ?? $defaultCurrency;
if (in_array($account->accountType->type, $this->balanceTypes, true)) {
$balance = app('steam')->balance($account, $date);
$nameWithBalance = sprintf('%s (%s)', $account->name, app('amount')->formatAnything($currency, $balance, false));
}
$return[] = [
'id' => (string)$account->id,
'name' => $account->name,
'name_with_balance' => $nameWithBalance,
'type' => $account->accountType->type,
'currency_id' => $currency->id,
'currency_name' => $currency->name,
'currency_code' => $currency->code,
'currency_symbol' => $currency->symbol,
'currency_decimal_places' => $currency->decimal_places,
];
}
// custom order.
$order = [AccountType::ASSET, AccountType::REVENUE, AccountType::EXPENSE];
usort(
$return,
function ($a, $b) use ($order) {
$pos_a = array_search($a['type'], $order, true);
$pos_b = array_search($b['type'], $order, true);
return $pos_a - $pos_b;
}
);
return response()->json($return);
}
}

View File

@@ -79,7 +79,7 @@ class Controller extends BaseController
$page = 1;
}
$integers = ['limit'];
$integers = ['limit', 'administration'];
$dates = ['start', 'end', 'date'];
if ($page < 1) {

View File

@@ -0,0 +1,98 @@
<?php
/*
* AutocompleteRequest.php
* Copyright (c) 2023 james@firefly-iii.org
*
* This file is part of Firefly III (https://github.com/firefly-iii).
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
declare(strict_types=1);
namespace FireflyIII\Api\V2\Request\Autocomplete;
use FireflyIII\Exceptions\FireflyException;
use FireflyIII\Models\AccountType;
use FireflyIII\Models\UserRole;
use FireflyIII\Support\Request\ChecksLogin;
use FireflyIII\Support\Request\ConvertsDataTypes;
use FireflyIII\User;
use FireflyIII\Validation\Administration\ValidatesAdministrationAccess;
use Illuminate\Foundation\Http\FormRequest;
use Illuminate\Validation\Validator;
/**
* Class AutocompleteRequest
*/
class AutocompleteRequest extends FormRequest
{
use ConvertsDataTypes;
use ChecksLogin;
use ValidatesAdministrationAccess;
/**
* @return array
* @throws FireflyException
*/
public function getData(): array
{
$types = $this->convertString('types');
$array = [];
if ('' !== $types) {
$array = explode(',', $types);
}
$limit = $this->convertInteger('limit');
$limit = 0 === $limit ? 10 : $limit;
// remove 'initial balance' and another from allowed types. its internal
$array = array_diff($array, [AccountType::INITIAL_BALANCE, AccountType::RECONCILIATION]);
/** @var User $user */
$user = auth()->user();
return [
'types' => $array,
'query' => $this->convertString('query'),
'date' => $this->getCarbonDate('date'),
'limit' => $limit,
'administration_id' => (int)($this->get('administration_id', null) ?? $user->getAdministrationId()),
];
}
/**
* @return array
*/
public function rules(): array
{
return [
'limit' => 'min:0|max:1337',
];
}
/**
* Configure the validator instance with special rules for after the basic validation rules.
*
* @param Validator $validator
*
* @return void
*/
public function withValidator(Validator $validator): void
{
$validator->after(
function (Validator $validator) {
// validate if the account can access this administration
$this->validateAdministration($validator, [UserRole::CHANGE_TRANSACTIONS]);
}
);
}
}

View File

@@ -0,0 +1,263 @@
<?php
/*
* CorrectAmounts.php
* Copyright (c) 2023 james@firefly-iii.org
*
* This file is part of Firefly III (https://github.com/firefly-iii).
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
declare(strict_types=1);
namespace FireflyIII\Console\Commands\Correction;
use FireflyIII\Models\AutoBudget;
use FireflyIII\Models\AvailableBudget;
use FireflyIII\Models\Bill;
use FireflyIII\Models\BudgetLimit;
use FireflyIII\Models\CurrencyExchangeRate;
use FireflyIII\Models\PiggyBank;
use FireflyIII\Models\PiggyBankRepetition;
use FireflyIII\Models\RecurrenceTransaction;
use FireflyIII\Models\RuleTrigger;
use Illuminate\Console\Command;
/**
* Class ReportSkeleton
*/
class CorrectAmounts extends Command
{
/**
* The console command description.
*
* @var string
*/
protected $description = 'This command makes sure positive and negative amounts are recorded correctly.';
/**
* The name and signature of the console command.
*
* @var string
*/
protected $signature = 'firefly-iii:fix-amount-pos-neg';
/**
* Execute the console command.
*
* @return int
*/
public function handle(): int
{
// auto budgets must be positive
$this->fixAutoBudgets();
// available budgets must be positive
$this->fixAvailableBudgets();
// bills must be positive (both amounts)
$this->fixBills();
// budget limits must be positive
$this->fixBudgetLimits();
// currency_exchange_rates must be positive
$this->fixExchangeRates();
// piggy_bank_repetitions must be positive
$this->fixRepetitions();
// piggy_banks must be positive
$this->fixPiggyBanks();
// recurrences_transactions amount must be positive
$this->fixRecurrences();
// rule_triggers must be positive or zero (amount_less, amount_more, amount_is)
$this->fixRuleTriggers();
return 0;
}
/**
* @return void
*/
private function fixAutoBudgets(): void
{
$set = AutoBudget::where('amount', '<', 0)->get();
$count = $set->count();
if (0 === $count) {
$this->info('Correct: All auto budget amounts are positive.');
return;
}
/** @var AutoBudget $item */
foreach ($set as $item) {
$item->amount = app('steam')->positive((string)$item->amount);
$item->save();
}
$this->line(sprintf('Corrected %d auto budget amount(s).', $count));
}
/**
* @return void
*/
private function fixAvailableBudgets(): void
{
$set = AvailableBudget::where('amount', '<', 0)->get();
$count = $set->count();
if (0 === $count) {
$this->info('Correct: All available budget amounts are positive.');
return;
}
/** @var AvailableBudget $item */
foreach ($set as $item) {
$item->amount = app('steam')->positive((string)$item->amount);
$item->save();
}
$this->line(sprintf('Corrected %d available budget amount(s).', $count));
}
/**
* @return void
*/
private function fixBills(): void
{
$set = Bill::where('amount_min', '<', 0)->orWhere('amount_max', '<', 0)->get();
$count = $set->count();
if (0 === $count) {
$this->info('Correct: All bill amounts are positive.');
return;
}
/** @var Bill $item */
foreach ($set as $item) {
$item->amount_min = app('steam')->positive((string)$item->amount_min);
$item->amount_max = app('steam')->positive((string)$item->amount_max);
$item->save();
}
}
/**
* @return void
*/
private function fixBudgetLimits(): void
{
$set = BudgetLimit::where('amount', '<', 0)->get();
$count = $set->count();
if (0 === $count) {
$this->info('Correct: All budget limit amounts are positive.');
return;
}
/** @var BudgetLimit $item */
foreach ($set as $item) {
$item->amount = app('steam')->positive((string)$item->amount);
$item->save();
}
$this->line(sprintf('Corrected %d budget limit amount(s).', $count));
}
/**
* @return void
*/
private function fixExchangeRates(): void
{
$set = CurrencyExchangeRate::where('rate', '<', 0)->get();
$count = $set->count();
if (0 === $count) {
$this->info('Correct: All currency exchange rates are positive.');
return;
}
/** @var BudgetLimit $item */
foreach ($set as $item) {
$item->rate = app('steam')->positive((string)$item->rate);
$item->save();
}
$this->line(sprintf('Corrected %d currency exchange rate(s).', $count));
}
/**
* @return void
*/
private function fixPiggyBanks(): void
{
$set = PiggyBank::where('targetamount', '<', 0)->get();
$count = $set->count();
if (0 === $count) {
$this->info('Correct: All piggy bank amounts are positive.');
return;
}
/** @var PiggyBankRepetition $item */
foreach ($set as $item) {
$item->targetamount = app('steam')->positive((string)$item->targetamount);
$item->save();
}
$this->line(sprintf('Corrected %d piggy bank amount(s).', $count));
}
/**
* @return void
*/
private function fixRecurrences(): void
{
$set = RecurrenceTransaction::where('amount', '<', 0)
->orWhere('foreign_amount', '<', 0)
->get();
$count = $set->count();
if (0 === $count) {
$this->info('Correct: All recurring transaction amounts are positive.');
return;
}
/** @var PiggyBankRepetition $item */
foreach ($set as $item) {
$item->amount = app('steam')->positive((string)$item->amount);
$item->foreign_amount = app('steam')->positive((string)$item->foreign_amount);
$item->save();
}
$this->line(sprintf('Corrected %d recurring transaction amount(s).', $count));
}
/**
* @return void
*/
private function fixRepetitions(): void
{
$set = PiggyBankRepetition::where('currentamount', '<', 0)->get();
$count = $set->count();
if (0 === $count) {
$this->info('Correct: All piggy bank repetition amounts are positive.');
return;
}
/** @var PiggyBankRepetition $item */
foreach ($set as $item) {
$item->currentamount = app('steam')->positive((string)$item->currentamount);
$item->save();
}
$this->line(sprintf('Corrected %d piggy bank repetition amount(s).', $count));
}
/**
* @return void
*/
private function fixRuleTriggers(): void
{
$set = RuleTrigger::whereIn('trigger_type', ['amount_less', 'amount_more', 'amount_is'])->get();
$fixed = 0;
/** @var RuleTrigger $item */
foreach ($set as $item) {
// basic check:
if (-1 === bccomp((string)$item->trigger_value, '0')) {
$fixed++;
$item->trigger_value = app('steam')->positive((string)$item->trigger_value);
$item->save();
}
}
if (0 === $fixed) {
$this->info('Correct: All rule trigger amounts are positive.');
return;
}
$this->line(sprintf('Corrected %d rule trigger amount(s).', $fixed));
}
}

View File

@@ -52,8 +52,10 @@ class CorrectDatabase extends Command
*/
public function handle(): int
{
$this->line('Handle Firefly III database correction commands.');
// if table does not exist, return false
if (!Schema::hasTable('users')) {
$this->error('No "users"-table, will not continue.');
return 1;
}
$commands = [
@@ -61,7 +63,7 @@ class CorrectDatabase extends Command
'firefly-iii:create-link-types',
'firefly-iii:create-access-tokens',
'firefly-iii:remove-bills',
'firefly-iii:fix-negative-limits',
'firefly-iii:fix-amount-pos-neg',
'firefly-iii:enable-currencies',
'firefly-iii:fix-transfer-budgets',
'firefly-iii:fix-uneven-amount',
@@ -76,16 +78,16 @@ class CorrectDatabase extends Command
'firefly-iii:fix-ob-currencies',
'firefly-iii:fix-long-descriptions',
'firefly-iii:fix-recurring-transactions',
'firefly-iii:restore-oauth-keys',
'firefly-iii:upgrade-group-information',
'firefly-iii:fix-transaction-types',
'firefly-iii:fix-frontpage-accounts',
// new!
'firefly-iii:unify-group-accounts',
'firefly-iii:trigger-credit-recalculation',
];
foreach ($commands as $command) {
$this->line(sprintf('Now executing %s', $command));
Artisan::call($command);
$result = Artisan::output();
echo $result;
$this->line(sprintf('Now executing command "%s"', $command));
$this->call($command);
}
return 0;

View File

@@ -33,8 +33,8 @@ use FireflyIII\Models\TransactionJournal;
use FireflyIII\Models\TransactionType;
use FireflyIII\Repositories\Account\AccountRepositoryInterface;
use Illuminate\Console\Command;
use Illuminate\Support\Facades\Log;
use JsonException;
use Log;
/**
* Class CorrectOpeningBalanceCurrencies

View File

@@ -26,7 +26,7 @@ namespace FireflyIII\Console\Commands\Correction;
use Exception;
use FireflyIII\Models\TransactionGroup;
use Illuminate\Console\Command;
use Log;
use Illuminate\Support\Facades\Log;
/**
* Class DeleteEmptyGroups

View File

@@ -28,7 +28,7 @@ use FireflyIII\Models\Transaction;
use FireflyIII\Models\TransactionJournal;
use Illuminate\Console\Command;
use Illuminate\Database\QueryException;
use Log;
use Illuminate\Support\Facades\Log;
/**
* Class DeleteEmptyJournals
@@ -61,6 +61,33 @@ class DeleteEmptyJournals extends Command
return 0;
}
private function deleteEmptyJournals(): void
{
$start = microtime(true);
$count = 0;
$set = TransactionJournal::leftJoin('transactions', 'transactions.transaction_journal_id', '=', 'transaction_journals.id')
->groupBy('transaction_journals.id')
->whereNull('transactions.transaction_journal_id')
->get(['transaction_journals.id']);
foreach ($set as $entry) {
try {
TransactionJournal::find($entry->id)->delete();
} catch (QueryException $e) {
Log::info(sprintf('Could not delete entry: %s', $e->getMessage()));
}
$this->info(sprintf('Deleted empty transaction journal #%d', $entry->id));
++$count;
}
if (0 === $count) {
$this->info('No empty transaction journals.');
}
$end = round(microtime(true) - $start, 2);
$this->info(sprintf('Verified empty journals in %s seconds', $end));
}
/**
* Delete transactions and their journals if they have an uneven number of transactions.
*/
@@ -91,31 +118,4 @@ class DeleteEmptyJournals extends Command
$this->info('No uneven transaction journals.');
}
}
private function deleteEmptyJournals(): void
{
$start = microtime(true);
$count = 0;
$set = TransactionJournal::leftJoin('transactions', 'transactions.transaction_journal_id', '=', 'transaction_journals.id')
->groupBy('transaction_journals.id')
->whereNull('transactions.transaction_journal_id')
->get(['transaction_journals.id']);
foreach ($set as $entry) {
try {
TransactionJournal::find($entry->id)->delete();
} catch (QueryException $e) {
Log::info(sprintf('Could not delete entry: %s', $e->getMessage()));
}
$this->info(sprintf('Deleted empty transaction journal #%d', $entry->id));
++$count;
}
if (0 === $count) {
$this->info('No empty transaction journals.');
}
$end = round(microtime(true) - $start, 2);
$this->info(sprintf('Verified empty journals in %s seconds', $end));
}
}

View File

@@ -27,7 +27,6 @@ use Exception;
use FireflyIII\Models\Transaction;
use FireflyIII\Models\TransactionJournal;
use Illuminate\Console\Command;
use Log;
use stdClass;
/**
@@ -66,6 +65,38 @@ class DeleteOrphanedTransactions extends Command
return 0;
}
/**
*
*/
private function deleteFromOrphanedAccounts(): void
{
$set
= Transaction::leftJoin('accounts', 'transactions.account_id', '=', 'accounts.id')
->whereNotNull('accounts.deleted_at')
->get(['transactions.*']);
$count = 0;
/** @var Transaction $transaction */
foreach ($set as $transaction) {
// delete journals
$journal = TransactionJournal::find((int)$transaction->transaction_journal_id);
if ($journal) {
$journal->delete();
}
Transaction::where('transaction_journal_id', (int)$transaction->transaction_journal_id)->delete();
$this->line(
sprintf(
'Deleted transaction journal #%d because account #%d was already deleted.',
$transaction->transaction_journal_id,
$transaction->account_id
)
);
$count++;
}
if (0 === $count) {
$this->info('No orphaned accounts.');
}
}
private function deleteOrphanedJournals(): void
{
$set = TransactionJournal::leftJoin('transaction_groups', 'transaction_journals.transaction_group_id', 'transaction_groups.id')
@@ -129,36 +160,4 @@ class DeleteOrphanedTransactions extends Command
$this->info('No orphaned transactions.');
}
}
/**
*
*/
private function deleteFromOrphanedAccounts(): void
{
$set
= Transaction::leftJoin('accounts', 'transactions.account_id', '=', 'accounts.id')
->whereNotNull('accounts.deleted_at')
->get(['transactions.*']);
$count = 0;
/** @var Transaction $transaction */
foreach ($set as $transaction) {
// delete journals
$journal = TransactionJournal::find((int)$transaction->transaction_journal_id);
if ($journal) {
$journal->delete();
}
Transaction::where('transaction_journal_id', (int)$transaction->transaction_journal_id)->delete();
$this->line(
sprintf(
'Deleted transaction journal #%d because account #%d was already deleted.',
$transaction->transaction_journal_id,
$transaction->account_id
)
);
$count++;
}
if (0 === $count) {
$this->info('No orphaned accounts.');
}
}
}

View File

@@ -30,7 +30,7 @@ use FireflyIII\Models\TransactionCurrency;
use FireflyIII\Models\TransactionJournal;
use Illuminate\Console\Command;
use Illuminate\Support\Collection;
use Log;
use Illuminate\Support\Facades\Log;
/**
* Class EnableCurrencies

View File

@@ -31,7 +31,7 @@ use FireflyIII\Models\TransactionJournal;
use FireflyIII\Models\TransactionType;
use Illuminate\Console\Command;
use JsonException;
use Log;
use Illuminate\Support\Facades\Log;
/**
* Class FixAccountTypes

View File

@@ -1,67 +0,0 @@
<?php
/*
* FixBudgetLimits.php
* Copyright (c) 2022 james@firefly-iii.org
*
* This file is part of Firefly III (https://github.com/firefly-iii).
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
declare(strict_types=1);
namespace FireflyIII\Console\Commands\Correction;
use DB;
use FireflyIII\Models\BudgetLimit;
use Illuminate\Console\Command;
/**
* Class CorrectionSkeleton
*/
class FixBudgetLimits extends Command
{
/**
* The console command description.
*
* @var string
*/
protected $description = 'Fixes negative budget limits';
/**
* The name and signature of the console command.
*
* @var string
*/
protected $signature = 'firefly-iii:fix-negative-limits';
/**
* Execute the console command.
*
* @return int
*/
public function handle(): int
{
$set = BudgetLimit::where('amount', '<', '0')->get();
if (0 === $set->count()) {
$this->info('All budget limits are OK.');
return 0;
}
$count = BudgetLimit::where('amount', '<', '0')->update(['amount' => DB::raw('amount * -1')]);
$this->info(sprintf('Fixed %d budget limit(s)', $count));
return 0;
}
}

View File

@@ -25,7 +25,9 @@ declare(strict_types=1);
namespace FireflyIII\Console\Commands\Correction;
use FireflyIII\Models\Account;
use FireflyIII\Models\AccountType;
use Illuminate\Console\Command;
use Illuminate\Support\Collection;
/**
* Class FixIbans
@@ -53,6 +55,63 @@ class FixIbans extends Command
public function handle(): int
{
$accounts = Account::whereNotNull('iban')->get();
$this->filterIbans($accounts);
$this->countAndCorrectIbans($accounts);
return 0;
}
/**
* @param Collection $accounts
* @return void
*/
private function countAndCorrectIbans(Collection $accounts): void
{
$set = [];
/** @var Account $account */
foreach ($accounts as $account) {
$userId = (int)$account->user_id;
$set[$userId] = $set[$userId] ?? [];
$iban = (string)$account->iban;
if ('' === $iban) {
continue;
}
$type = $account->accountType->type;
if (in_array($type, [AccountType::LOAN, AccountType::DEBT, AccountType::MORTGAGE], true)) {
$type = 'liabilities';
}
if (array_key_exists($iban, $set[$userId])) {
// iban already in use! two exceptions exist:
if (
!(AccountType::EXPENSE === $set[$userId][$iban] && AccountType::REVENUE === $type) && // allowed combination
!(AccountType::REVENUE === $set[$userId][$iban] && AccountType::EXPENSE === $type) // also allowed combination.
) {
$this->line(
sprintf(
'IBAN "%s" is used more than once and will be removed from %s #%d ("%s")',
$iban,
$account->accountType->type,
$account->id,
$account->name
)
);
$account->iban = null;
$account->save();
}
}
if (!array_key_exists($iban, $set[$userId])) {
$set[$userId][$iban] = $type;
}
}
}
/**
* @param Collection $accounts
* @return void
*/
private function filterIbans(Collection $accounts): void
{
/** @var Account $account */
foreach ($accounts as $account) {
$iban = $account->iban;
@@ -65,7 +124,5 @@ class FixIbans extends Command
}
}
}
return 0;
}
}

View File

@@ -25,11 +25,10 @@ namespace FireflyIII\Console\Commands\Correction;
use FireflyIII\Models\PiggyBankEvent;
use FireflyIII\Models\TransactionJournal;
use FireflyIII\Models\TransactionType;
use Illuminate\Console\Command;
/**
* Report (and fix) piggy banks. Make sure there are only transfers linked to piggy bank events.
* Report (and fix) piggy banks.
*
* Class FixPiggies
*/
@@ -57,7 +56,7 @@ class FixPiggies extends Command
{
$count = 0;
$start = microtime(true);
$set = PiggyBankEvent::with(['PiggyBank', 'TransactionJournal', 'TransactionJournal.TransactionType'])->get();
$set = PiggyBankEvent::with(['PiggyBank', 'TransactionJournal'])->get();
/** @var PiggyBankEvent $event */
foreach ($set as $event) {
@@ -73,15 +72,6 @@ class FixPiggies extends Command
$count++;
continue;
}
$type = $journal->transactionType->type;
if (TransactionType::TRANSFER !== $type) {
$event->transaction_journal_id = null;
$event->save();
$this->line(sprintf('Piggy bank #%d was referenced by an invalid event. This has been fixed.', $event->piggy_bank_id));
$count++;
}
}
if (0 === $count) {
$this->line('All piggy bank events are correct.');

View File

@@ -70,19 +70,6 @@ class FixRecurringTransactions extends Command
return 0;
}
/**
* Laravel will execute ALL __construct() methods for ALL commands whenever a SINGLE command is
* executed. This leads to noticeable slow-downs and class calls. To prevent this, this method should
* be called from the handle method instead of using the constructor to initialize the command.
*
*/
private function stupidLaravel(): void
{
$this->recurringRepos = app(RecurringRepositoryInterface::class);
$this->userRepos = app(UserRepositoryInterface::class);
}
/**
*
*/
@@ -95,19 +82,6 @@ class FixRecurringTransactions extends Command
}
}
/**
* @param User $user
*/
private function processUser(User $user): void
{
$this->recurringRepos->setUser($user);
$recurrences = $this->recurringRepos->get();
/** @var Recurrence $recurrence */
foreach ($recurrences as $recurrence) {
$this->processRecurrence($recurrence);
}
}
/**
* @param Recurrence $recurrence
*/
@@ -140,4 +114,30 @@ class FixRecurringTransactions extends Command
}
}
}
/**
* @param User $user
*/
private function processUser(User $user): void
{
$this->recurringRepos->setUser($user);
$recurrences = $this->recurringRepos->get();
/** @var Recurrence $recurrence */
foreach ($recurrences as $recurrence) {
$this->processRecurrence($recurrence);
}
}
/**
* Laravel will execute ALL __construct() methods for ALL commands whenever a SINGLE command is
* executed. This leads to noticeable slow-downs and class calls. To prevent this, this method should
* be called from the handle method instead of using the constructor to initialize the command.
*
*/
private function stupidLaravel(): void
{
$this->recurringRepos = app(RecurringRepositoryInterface::class);
$this->userRepos = app(UserRepositoryInterface::class);
}
}

View File

@@ -78,6 +78,19 @@ class FixTransactionTypes extends Command
return 0;
}
/**
* @param TransactionJournal $journal
* @param string $expectedType
*/
private function changeJournal(TransactionJournal $journal, string $expectedType): void
{
$type = TransactionType::whereType($expectedType)->first();
if (null !== $type) {
$journal->transaction_type_id = $type->id;
$journal->save();
}
}
/**
* Collect all transaction journals.
*
@@ -125,36 +138,6 @@ class FixTransactionTypes extends Command
return false;
}
/**
* @param TransactionJournal $journal
*
* @return Account
* @throws FireflyException
*/
private function getSourceAccount(TransactionJournal $journal): Account
{
$collection = $journal->transactions->filter(
static function (Transaction $transaction) {
return $transaction->amount < 0;
}
);
if (0 === $collection->count()) {
throw new FireflyException(sprintf('300001: Journal #%d has no source transaction.', $journal->id));
}
if (1 !== $collection->count()) {
throw new FireflyException(sprintf('300002: Journal #%d has multiple source transactions.', $journal->id));
}
/** @var Transaction $transaction */
$transaction = $collection->first();
/** @var Account|null $account */
$account = $transaction->account;
if (null === $account) {
throw new FireflyException(sprintf('300003: Journal #%d, transaction #%d has no source account.', $journal->id, $transaction->id));
}
return $account;
}
/**
* @param TransactionJournal $journal
*
@@ -187,14 +170,31 @@ class FixTransactionTypes extends Command
/**
* @param TransactionJournal $journal
* @param string $expectedType
*
* @return Account
* @throws FireflyException
*/
private function changeJournal(TransactionJournal $journal, string $expectedType): void
private function getSourceAccount(TransactionJournal $journal): Account
{
$type = TransactionType::whereType($expectedType)->first();
if (null !== $type) {
$journal->transaction_type_id = $type->id;
$journal->save();
$collection = $journal->transactions->filter(
static function (Transaction $transaction) {
return $transaction->amount < 0;
}
);
if (0 === $collection->count()) {
throw new FireflyException(sprintf('300001: Journal #%d has no source transaction.', $journal->id));
}
if (1 !== $collection->count()) {
throw new FireflyException(sprintf('300002: Journal #%d has multiple source transactions.', $journal->id));
}
/** @var Transaction $transaction */
$transaction = $collection->first();
/** @var Account|null $account */
$account = $transaction->account;
if (null === $account) {
throw new FireflyException(sprintf('300003: Journal #%d, transaction #%d has no source account.', $journal->id, $transaction->id));
}
return $account;
}
}

View File

@@ -27,7 +27,7 @@ use DB;
use FireflyIII\Models\Transaction;
use FireflyIII\Models\TransactionJournal;
use Illuminate\Console\Command;
use Log;
use Illuminate\Support\Facades\Log;
use stdClass;
/**

View File

@@ -26,7 +26,7 @@ namespace FireflyIII\Console\Commands\Correction;
use FireflyIII\Models\TransactionJournal;
use FireflyIII\Models\TransactionType;
use Illuminate\Console\Command;
use Log;
use Illuminate\Support\Facades\Log;
/**
* Class TransferBudgets

View File

@@ -39,17 +39,6 @@ class TriggerCreditCalculation extends Command
return 0;
}
private function processAccounts(): void
{
$accounts = Account::leftJoin('account_types', 'accounts.account_type_id', 'account_types.id')
->whereIn('account_types.type', config('firefly.valid_liabilities'))
->get(['accounts.*']);
foreach ($accounts as $account) {
Log::debug(sprintf('Processing account #%d ("%s")', $account->id, $account->name));
$this->processAccount($account);
}
}
/**
* @param Account $account
* @return void
@@ -61,4 +50,15 @@ class TriggerCreditCalculation extends Command
$object->setAccount($account);
$object->recalculate();
}
private function processAccounts(): void
{
$accounts = Account::leftJoin('account_types', 'accounts.account_type_id', 'account_types.id')
->whereIn('account_types.type', config('firefly.valid_liabilities'))
->get(['accounts.*']);
foreach ($accounts as $account) {
Log::debug(sprintf('Processing account #%d ("%s")', $account->id, $account->name));
$this->processAccount($account);
}
}
}

View File

@@ -36,7 +36,7 @@ use FireflyIII\Support\Export\ExportDataGenerator;
use Illuminate\Console\Command;
use Illuminate\Support\Collection;
use InvalidArgumentException;
use Log;
use Illuminate\Support\Facades\Log;
/**
* Class ExportData

View File

@@ -30,7 +30,7 @@ use FireflyIII\Models\UserGroup;
use FireflyIII\Models\UserRole;
use FireflyIII\User;
use Illuminate\Console\Command;
use Log;
use Illuminate\Support\Facades\Log;
/**
* Class CreateGroupMemberships
@@ -52,44 +52,12 @@ class CreateGroupMemberships extends Command
protected $signature = 'firefly-iii:create-group-memberships';
/**
* Execute the console command.
*
* @return int
* @throws FireflyException
*/
public function handle(): int
{
$start = microtime(true);
$this->createGroupMemberships();
$end = round(microtime(true) - $start, 2);
$this->info(sprintf('Validated group memberships in %s seconds.', $end));
return 0;
}
/**
*
* @throws FireflyException
*/
private function createGroupMemberships(): void
{
$users = User::get();
/** @var User $user */
foreach ($users as $user) {
Log::debug(sprintf('Manage group memberships for user #%d', $user->id));
$this->createGroupMembership($user);
Log::debug(sprintf('Done with user #%d', $user->id));
}
}
/**
* TODO move to helper.
* @param User $user
*
* @throws FireflyException
*/
private function createGroupMembership(User $user): void
public static function createGroupMembership(User $user): void
{
// check if membership exists
$userGroup = UserGroup::where('title', $user->email)->first();
@@ -124,4 +92,37 @@ class CreateGroupMemberships extends Command
Log::debug(sprintf('User #%d now has main group.', $user->id));
}
/**
* Execute the console command.
*
* @return int
* @throws FireflyException
*/
public function handle(): int
{
$start = microtime(true);
$this->createGroupMemberships();
$end = round(microtime(true) - $start, 2);
$this->info(sprintf('Validated group memberships in %s seconds.', $end));
return 0;
}
/**
*
* @throws FireflyException
*/
private function createGroupMemberships(): void
{
$users = User::get();
/** @var User $user */
foreach ($users as $user) {
Log::debug(sprintf('Manage group memberships for user #%d', $user->id));
self::createGroupMembership($user);
Log::debug(sprintf('Done with user #%d', $user->id));
}
}
}

View File

@@ -67,6 +67,51 @@ class ReportEmptyObjects extends Command
return 0;
}
/**
* Reports on accounts with no transactions.
*/
private function reportAccounts(): void
{
$set = Account::leftJoin('transactions', 'transactions.account_id', '=', 'accounts.id')
->leftJoin('users', 'accounts.user_id', '=', 'users.id')
->groupBy(['accounts.id', 'accounts.encrypted', 'accounts.name', 'accounts.user_id', 'users.email'])
->whereNull('transactions.account_id')
->get(
['accounts.id', 'accounts.encrypted', 'accounts.name', 'accounts.user_id', 'users.email']
);
/** @var stdClass $entry */
foreach ($set as $entry) {
$line = 'User #%d (%s) has account #%d ("%s") which has no transactions.';
$line = sprintf($line, $entry->user_id, $entry->email, $entry->id, $entry->name);
$this->line($line);
}
}
/**
* Reports on budgets with no budget limits (which makes them pointless).
*/
private function reportBudgetLimits(): void
{
$set = Budget::leftJoin('budget_limits', 'budget_limits.budget_id', '=', 'budgets.id')
->leftJoin('users', 'budgets.user_id', '=', 'users.id')
->groupBy(['budgets.id', 'budgets.name', 'budgets.encrypted', 'budgets.user_id', 'users.email'])
->whereNull('budget_limits.id')
->get(['budgets.id', 'budgets.name', 'budgets.user_id', 'budgets.encrypted', 'users.email']);
/** @var Budget $entry */
foreach ($set as $entry) {
$line = sprintf(
'User #%d (%s) has budget #%d ("%s") which has no budget limits.',
$entry->user_id,
$entry->email,
$entry->id,
$entry->name
);
$this->line($line);
}
}
/**
* Report on budgets with no transactions or journals.
*/
@@ -141,49 +186,4 @@ class ReportEmptyObjects extends Command
$this->line($line);
}
}
/**
* Reports on accounts with no transactions.
*/
private function reportAccounts(): void
{
$set = Account::leftJoin('transactions', 'transactions.account_id', '=', 'accounts.id')
->leftJoin('users', 'accounts.user_id', '=', 'users.id')
->groupBy(['accounts.id', 'accounts.encrypted', 'accounts.name', 'accounts.user_id', 'users.email'])
->whereNull('transactions.account_id')
->get(
['accounts.id', 'accounts.encrypted', 'accounts.name', 'accounts.user_id', 'users.email']
);
/** @var stdClass $entry */
foreach ($set as $entry) {
$line = 'User #%d (%s) has account #%d ("%s") which has no transactions.';
$line = sprintf($line, $entry->user_id, $entry->email, $entry->id, $entry->name);
$this->line($line);
}
}
/**
* Reports on budgets with no budget limits (which makes them pointless).
*/
private function reportBudgetLimits(): void
{
$set = Budget::leftJoin('budget_limits', 'budget_limits.budget_id', '=', 'budgets.id')
->leftJoin('users', 'budgets.user_id', '=', 'users.id')
->groupBy(['budgets.id', 'budgets.name', 'budgets.encrypted', 'budgets.user_id', 'users.email'])
->whereNull('budget_limits.id')
->get(['budgets.id', 'budgets.name', 'budgets.user_id', 'budgets.encrypted', 'users.email']);
/** @var Budget $entry */
foreach ($set as $entry) {
$line = sprintf(
'User #%d (%s) has budget #%d ("%s") which has no budget limits.',
$entry->user_id,
$entry->email,
$entry->id,
$entry->name
);
$this->line($line);
}
}
}

View File

@@ -57,14 +57,15 @@ class ReportIntegrity extends Command
return 1;
}
$commands = [
'firefly-iii:create-group-memberships',
'firefly-iii:report-empty-objects',
'firefly-iii:report-sum',
'firefly-iii:restore-oauth-keys',
'firefly-iii:upgrade-group-information',
];
foreach ($commands as $command) {
$this->line(sprintf('Now executing %s', $command));
Artisan::call($command);
$result = Artisan::output();
echo $result;
$this->call($command);
}
return 0;

View File

@@ -26,7 +26,7 @@ namespace FireflyIII\Console\Commands\Integrity;
use FireflyIII\Support\System\OAuthKeys;
use Illuminate\Console\Command;
use Log;
use Illuminate\Support\Facades\Log;
/**
* Class RestoreOAuthKeys
@@ -58,6 +58,38 @@ class RestoreOAuthKeys extends Command
return 0;
}
/**
*
*/
private function generateKeys(): void
{
OAuthKeys::generateKeys();
}
/**
* @return bool
*/
private function keysInDatabase(): bool
{
return OAuthKeys::keysInDatabase();
}
/**
* @return bool
*/
private function keysOnDrive(): bool
{
return OAuthKeys::hasKeyFiles();
}
/**
*
*/
private function restoreKeysFromDB(): bool
{
return OAuthKeys::restoreKeysFromDB();
}
/**
*
*/
@@ -97,30 +129,6 @@ class RestoreOAuthKeys extends Command
$this->line('OAuth keys are OK');
}
/**
* @return bool
*/
private function keysInDatabase(): bool
{
return OAuthKeys::keysInDatabase();
}
/**
* @return bool
*/
private function keysOnDrive(): bool
{
return OAuthKeys::hasKeyFiles();
}
/**
*
*/
private function generateKeys(): void
{
OAuthKeys::generateKeys();
}
/**
*
*/
@@ -128,12 +136,4 @@ class RestoreOAuthKeys extends Command
{
OAuthKeys::storeKeysInDB();
}
/**
*
*/
private function restoreKeysFromDB(): bool
{
return OAuthKeys::restoreKeysFromDB();
}
}

View File

@@ -1,8 +1,8 @@
<?php
/**
/*
* CreateDatabase.php
* Copyright (c) 2020 james@firefly-iii.org
* Copyright (c) 2023 james@firefly-iii.org
*
* This file is part of Firefly III (https://github.com/firefly-iii).
*
@@ -22,7 +22,7 @@
declare(strict_types=1);
namespace FireflyIII\Console\Commands;
namespace FireflyIII\Console\Commands\System;
use Illuminate\Console\Command;
use PDO;

View File

@@ -2,7 +2,7 @@
/*
* CreateFirstUser.php
* Copyright (c) 2021 james@firefly-iii.org
* Copyright (c) 2023 james@firefly-iii.org
*
* This file is part of Firefly III (https://github.com/firefly-iii).
*
@@ -22,7 +22,7 @@
declare(strict_types=1);
namespace FireflyIII\Console\Commands;
namespace FireflyIII\Console\Commands\System;
use FireflyIII\Repositories\User\UserRepositoryInterface;
use Illuminate\Console\Command;

View File

@@ -0,0 +1,551 @@
<?php
/*
* ForceDecimalSize.php
* Copyright (c) 2023 james@firefly-iii.org
*
* This file is part of Firefly III (https://github.com/firefly-iii).
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
declare(strict_types=1);
namespace FireflyIII\Console\Commands\System;
use FireflyIII\Exceptions\FireflyException;
use FireflyIII\Models\Account;
use FireflyIII\Models\AutoBudget;
use FireflyIII\Models\AvailableBudget;
use FireflyIII\Models\Bill;
use FireflyIII\Models\BudgetLimit;
use FireflyIII\Models\PiggyBank;
use FireflyIII\Models\PiggyBankEvent;
use FireflyIII\Models\PiggyBankRepetition;
use FireflyIII\Models\RecurrenceTransaction;
use FireflyIII\Models\Transaction;
use FireflyIII\Models\TransactionCurrency;
use Illuminate\Console\Command;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Collection;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;
/**
* Class ForceDecimalSize
*
* 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
* Firefly III would store 0.01 as 0.01000000000000000020816681711721685132943093776702880859375.
*/
class ForceDecimalSize extends Command
{
protected $description = 'This command resizes DECIMAL columns in MySQL or PostgreSQL and correct amounts (only MySQL).';
protected $signature = 'firefly-iii:force-decimal-size';
private string $cast;
private array $classes = [
'accounts' => Account::class,
'auto_budgets' => AutoBudget::class,
'available_budgets' => AvailableBudget::class,
'bills' => Bill::class,
'budget_limits' => BudgetLimit::class,
'piggy_bank_events' => PiggyBankEvent::class,
'piggy_bank_repetitions' => PiggyBankRepetition::class,
'piggy_banks' => PiggyBank::class,
'recurrences_transactions' => RecurrenceTransaction::class,
'transactions' => Transaction::class,
];
private string $operator;
private string $regularExpression;
private array $tables = [
'accounts' => ['virtual_balance'],
'auto_budgets' => ['amount'],
'available_budgets' => ['amount'],
'bills' => ['amount_min', 'amount_max'],
'budget_limits' => ['amount'],
'currency_exchange_rates' => ['rate', 'user_rate'],
'limit_repetitions' => ['amount'],
'piggy_bank_events' => ['amount'],
'piggy_bank_repetitions' => ['currentamount'],
'piggy_banks' => ['targetamount'],
'recurrences_transactions' => ['amount', 'foreign_amount'],
'transactions' => ['amount', 'foreign_amount'],
];
/**
* Execute the console command.
*
* @throws FireflyException
*/
public function handle(): int
{
Log::debug('Now in ForceDecimalSize::handle()');
$this->determineDatabaseType();
$this->error('Running this command is dangerous and can cause data loss.');
$this->error('Please do not continue.');
$question = $this->confirm('Do you want to continue?');
if (true === $question) {
$this->correctAmounts();
$this->updateDecimals();
}
$this->line('Done!');
return 0;
}
/**
* This method loops over all accounts and validates the amounts.
*
* @param TransactionCurrency $currency
* @param array $fields
* @return void
*/
private function correctAccountAmounts(TransactionCurrency $currency, array $fields): void
{
$operator = $this->operator;
$cast = $this->cast;
$regularExpression = $this->regularExpression;
/** @var Builder $query */
$query = Account::leftJoin('account_meta', 'accounts.id', '=', 'account_meta.account_id')
->where('account_meta.name', 'currency_id')
->where('account_meta.data', json_encode((string)$currency->id));
$query->where(static function (Builder $q) use ($fields, $currency, $operator, $cast, $regularExpression) {
foreach ($fields as $field) {
$q->orWhere(
DB::raw(sprintf('CAST(accounts.%s AS %s)', $field, $cast)),
$operator,
DB::raw(sprintf($regularExpression, $currency->decimal_places))
);
}
});
$result = $query->get(['accounts.*']);
if (0 === $result->count()) {
$this->line(sprintf('Correct: All accounts in %s', $currency->code));
return;
}
/** @var Account $account */
foreach ($result as $account) {
foreach ($fields as $field) {
$value = $account->$field;
if (null === $value) {
continue;
}
// fix $field by rounding it down correctly.
$pow = pow(10, (int)$currency->decimal_places);
$correct = bcdiv((string)round($value * $pow), (string)$pow, 12);
$this->line(sprintf('Account #%d has %s with value "%s", this has been corrected to "%s".', $account->id, $field, $value, $correct));
Account::find($account->id)->update([$field => $correct]);
}
}
}
/**
* This method checks if a basic check can be done or if it needs to be complicated.
*
* @return void
*/
private function correctAmounts(): void
{
// if sqlite, add function?
if ('sqlite' === (string)config('database.default')) {
DB::connection()->getPdo()->sqliteCreateFunction('REGEXP', function ($pattern, $value) {
mb_regex_encoding('UTF-8');
$pattern = trim($pattern, '"');
return (false !== mb_ereg($pattern, (string) $value)) ? 1 : 0;
});
}
if (!in_array((string)config('database.default'), ['mysql', 'pgsql', 'sqlite'], true)) {
$this->line(sprintf('Skip correcting amounts, does not support "%s"...', (string)config('database.default')));
return;
}
$this->correctAmountsByCurrency();
}
/**
* This method loops all enabled currencies and then calls the method that will fix all objects in this currency.
*
* @return void
*/
private function correctAmountsByCurrency(): void
{
$this->line('Going to correct amounts.');
/** @var Collection $enabled */
$enabled = TransactionCurrency::whereEnabled(1)->get();
/** @var TransactionCurrency $currency */
foreach ($enabled as $currency) {
$this->correctByCurrency($currency);
}
}
/**
* This method loops the available tables that may need fixing, and calls for the right method that can fix them.
*
* @param TransactionCurrency $currency
* @return void
* @throws FireflyException
*/
private function correctByCurrency(TransactionCurrency $currency): void
{
$this->line(sprintf('Going to correct amounts in currency %s ("%s").', $currency->code, $currency->name));
/**
* @var string $name
* @var array $fields
*/
foreach ($this->tables as $name => $fields) {
switch ($name) {
default:
$message = sprintf('Cannot handle table "%s"', $name);
$this->line($message);
throw new FireflyException($message);
case 'accounts':
$this->correctAccountAmounts($currency, $fields);
break;
case 'auto_budgets':
case 'available_budgets':
case 'bills':
case 'budget_limits':
case 'recurrences_transactions':
$this->correctGeneric($currency, $name);
break;
case 'currency_exchange_rates':
case 'limit_repetitions':
// do nothing
break;
case 'piggy_bank_events':
$this->correctPiggyEventAmounts($currency, $fields);
break;
case 'piggy_bank_repetitions':
$this->correctPiggyRepetitionAmounts($currency, $fields);
break;
case 'piggy_banks':
$this->correctPiggyAmounts($currency, $fields);
break;
case 'transactions':
$this->correctTransactionAmounts($currency);
break;
}
}
}
/**
* This method fixes all auto budgets in currency $currency.
* @param TransactionCurrency $currency
* @param string $table
* @return void
*/
private function correctGeneric(TransactionCurrency $currency, string $table): void
{
$class = $this->classes[$table];
$fields = $this->tables[$table];
$operator = $this->operator;
$cast = $this->cast;
$regularExpression = $this->regularExpression;
/** @var Builder $query */
$query = $class::where('transaction_currency_id', $currency->id)->where(
static function (Builder $q) use ($fields, $currency, $operator, $cast, $regularExpression) {
foreach ($fields as $field) {
$q->orWhere(
DB::raw(sprintf('CAST(%s AS %s)', $field, $cast)),
$operator,
DB::raw(sprintf($regularExpression, $currency->decimal_places))
);
}
}
);
$result = $query->get(['*']);
if (0 === $result->count()) {
$this->line(sprintf('Correct: All %s in %s', $table, $currency->code));
return;
}
/** @var Model $item */
foreach ($result as $item) {
foreach ($fields as $field) {
$value = $item->$field;
if (null === $value) {
continue;
}
// fix $field by rounding it down correctly.
$pow = pow(10, (int)$currency->decimal_places);
$correct = bcdiv((string)round($value * $pow), (string)$pow, 12);
$this->line(sprintf('%s #%d has %s with value "%s", this has been corrected to "%s".', $table, $item->id, $field, $value, $correct));
$class::find($item->id)->update([$field => $correct]);
}
}
}
/**
* This method fixes all piggy banks in currency $currency.
*
* @param TransactionCurrency $currency
* @param array $fields
* @return void
*/
private function correctPiggyAmounts(TransactionCurrency $currency, array $fields): void
{
$operator = $this->operator;
$cast = $this->cast;
$regularExpression = $this->regularExpression;
/** @var Builder $query */
$query = PiggyBank::leftJoin('accounts', 'piggy_banks.account_id', '=', 'accounts.id')
->leftJoin('account_meta', 'accounts.id', '=', 'account_meta.account_id')
->where('account_meta.name', 'currency_id')
->where('account_meta.data', json_encode((string)$currency->id))
->where(static function (Builder $q) use ($fields, $currency, $operator, $cast, $regularExpression) {
foreach ($fields as $field) {
$q->orWhere(
DB::raw(sprintf('CAST(piggy_banks.%s AS %s)', $field, $cast)),
$operator,
DB::raw(sprintf($regularExpression, $currency->decimal_places))
);
}
});
$result = $query->get(['piggy_banks.*']);
if (0 === $result->count()) {
$this->line(sprintf('Correct: All piggy banks in %s', $currency->code));
return;
}
/** @var PiggyBank $item */
foreach ($result as $item) {
foreach ($fields as $field) {
$value = $item->$field;
if (null === $value) {
continue;
}
// fix $field by rounding it down correctly.
$pow = pow(10, (int)$currency->decimal_places);
$correct = bcdiv((string)round($value * $pow), (string)$pow, 12);
$this->line(sprintf('Piggy bank #%d has %s with value "%s", this has been corrected to "%s".', $item->id, $field, $value, $correct));
PiggyBank::find($item->id)->update([$field => $correct]);
}
}
}
/**
* This method fixes all piggy bank events in currency $currency.
* @param TransactionCurrency $currency
* @param array $fields
* @return void
*/
private function correctPiggyEventAmounts(TransactionCurrency $currency, array $fields): void
{
$operator = $this->operator;
$cast = $this->cast;
$regularExpression = $this->regularExpression;
/** @var Builder $query */
$query = PiggyBankEvent::leftJoin('piggy_banks', 'piggy_bank_events.piggy_bank_id', '=', 'piggy_banks.id')
->leftJoin('accounts', 'piggy_banks.account_id', '=', 'accounts.id')
->leftJoin('account_meta', 'accounts.id', '=', 'account_meta.account_id')
->where('account_meta.name', 'currency_id')
->where('account_meta.data', json_encode((string)$currency->id))
->where(static function (Builder $q) use ($fields, $currency, $cast, $operator, $regularExpression) {
foreach ($fields as $field) {
$q->orWhere(
DB::raw(sprintf('CAST(piggy_bank_events.%s AS %s)', $field, $cast)),
$operator,
DB::raw(sprintf($regularExpression, $currency->decimal_places))
);
}
});
$result = $query->get(['piggy_bank_events.*']);
if (0 === $result->count()) {
$this->line(sprintf('Correct: All piggy bank events in %s', $currency->code));
return;
}
/** @var PiggyBankEvent $item */
foreach ($result as $item) {
foreach ($fields as $field) {
$value = $item->$field;
if (null === $value) {
continue;
}
// fix $field by rounding it down correctly.
$pow = pow(10, (int)$currency->decimal_places);
$correct = bcdiv((string)round($value * $pow), (string)$pow, 12);
$this->line(sprintf('Piggy bank event #%d has %s with value "%s", this has been corrected to "%s".', $item->id, $field, $value, $correct));
PiggyBankEvent::find($item->id)->update([$field => $correct]);
}
}
}
/**
* This method fixes all piggy bank repetitions in currency $currency.
*
* @param TransactionCurrency $currency
* @param array $fields
* @return void
*/
private function correctPiggyRepetitionAmounts(TransactionCurrency $currency, array $fields)
{
$operator = $this->operator;
$cast = $this->cast;
$regularExpression = $this->regularExpression;
// select all piggy bank repetitions with this currency and issue.
/** @var Builder $query */
$query = PiggyBankRepetition::leftJoin('piggy_banks', 'piggy_bank_repetitions.piggy_bank_id', '=', 'piggy_banks.id')
->leftJoin('accounts', 'piggy_banks.account_id', '=', 'accounts.id')
->leftJoin('account_meta', 'accounts.id', '=', 'account_meta.account_id')
->where('account_meta.name', 'currency_id')
->where('account_meta.data', json_encode((string)$currency->id))
->where(static function (Builder $q) use ($fields, $currency, $operator, $cast, $regularExpression) {
foreach ($fields as $field) {
$q->orWhere(
DB::raw(sprintf('CAST(piggy_bank_repetitions.%s AS %s)', $field, $cast)),
$operator,
DB::raw(sprintf($regularExpression, $currency->decimal_places))
);
}
});
$result = $query->get(['piggy_bank_repetitions.*']);
if (0 === $result->count()) {
$this->line(sprintf('Correct: All piggy bank repetitions in %s', $currency->code));
return;
}
/** @var PiggyBankRepetition $item */
foreach ($result as $item) {
foreach ($fields as $field) {
$value = $item->$field;
if (null === $value) {
continue;
}
// fix $field by rounding it down correctly.
$pow = pow(10, (int)$currency->decimal_places);
$correct = bcdiv((string)round($value * $pow), (string)$pow, 12);
$this->line(sprintf('Piggy bank repetition #%d has %s with value "%s", this has been corrected to "%s".', $item->id, $field, $value, $correct));
PiggyBankRepetition::find($item->id)->update([$field => $correct]);
}
}
}
/**
* This method fixes all transactions in currency $currency.
*
* @param TransactionCurrency $currency
* @return void
*/
private function correctTransactionAmounts(TransactionCurrency $currency): void
{
// select all transactions with this currency and issue.
/** @var Builder $query */
$query = Transaction::where('transaction_currency_id', $currency->id)->where(
DB::raw(sprintf('CAST(amount as %s)', $this->cast)),
$this->operator,
DB::raw(sprintf($this->regularExpression, $currency->decimal_places))
);
$result = $query->get(['transactions.*']);
if (0 === $result->count()) {
$this->line(sprintf('Correct: All transactions in %s', $currency->code));
}
/** @var Transaction $item */
foreach ($result as $item) {
$value = $item->amount;
if (null === $value) {
continue;
}
// fix $field by rounding it down correctly.
$pow = pow(10, (int)$currency->decimal_places);
$correct = bcdiv((string)round($value * $pow), (string)$pow, 12);
$this->line(sprintf('Transaction #%d has amount with value "%s", this has been corrected to "%s".', $item->id, $value, $correct));
Transaction::find($item->id)->update(['amount' => $correct]);
}
// select all transactions with this FOREIGN currency and issue.
/** @var Builder $query */
$query = Transaction::where('foreign_currency_id', $currency->id)->where(
DB::raw(sprintf('CAST(foreign_amount as %s)', $this->cast)),
$this->operator,
DB::raw(sprintf($this->regularExpression, $currency->decimal_places))
);
$result = $query->get(['*']);
if (0 === $result->count()) {
$this->line(sprintf('Correct: All transactions in foreign currency %s', $currency->code));
return;
}
/** @var Transaction $item */
foreach ($result as $item) {
$value = $item->foreign_amount;
if (null === $value) {
continue;
}
// fix $field by rounding it down correctly.
$pow = pow(10, (int)$currency->decimal_places);
$correct = bcdiv((string)round($value * $pow), (string)$pow, 12);
$this->line(sprintf('Transaction #%d has foreign amount with value "%s", this has been corrected to "%s".', $item->id, $value, $correct));
Transaction::find($item->id)->update(['foreign_amount' => $correct]);
}
}
private function determineDatabaseType(): void
{
// switch stuff based on database connection:
$this->operator = 'REGEXP';
$this->regularExpression = '\'\\\\.[\\\\d]{%d}[1-9]+\'';
$this->cast = 'CHAR';
if ('pgsql' === config('database.default')) {
$this->operator = 'SIMILAR TO';
$this->regularExpression = '\'%%\.[\d]{%d}[1-9]+%%\'';
$this->cast = 'TEXT';
}
if ('sqlite' === config('database.default')) {
$this->regularExpression = '"\\.[\d]{%d}[1-9]+"';
}
}
/**
* @return void
*/
private function updateDecimals(): void
{
$this->info('Going to force the size of DECIMAL columns. Please hold.');
$type = (string)config('database.default');
/**
* @var string $name
* @var array $fields
*/
foreach ($this->tables as $name => $fields) {
/** @var string $field */
foreach ($fields as $field) {
$this->line(sprintf('Updating table "%s", field "%s"...', $name, $field));
switch ($type) {
default:
$this->error(sprintf('Cannot handle database type "%s".', $type));
return;
case 'pgsql':
$query = sprintf('ALTER TABLE %s ALTER COLUMN %s TYPE DECIMAL(32,12);', $name, $field);
break;
case 'mysql':
$query = sprintf('ALTER TABLE %s CHANGE COLUMN %s %s DECIMAL(32, 12);', $name, $field, $field);
break;
}
DB::select($query);
sleep(1);
}
}
}
}

View File

@@ -0,0 +1,94 @@
<?php
/*
* ForceMigration.php
* Copyright (c) 2023 james@firefly-iii.org
*
* This file is part of Firefly III (https://github.com/firefly-iii).
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
declare(strict_types=1);
namespace FireflyIII\Console\Commands\System;
use FireflyIII\Console\Commands\VerifiesAccessToken;
use FireflyIII\Exceptions\FireflyException;
use Illuminate\Console\Command;
use Illuminate\Support\Facades\Artisan;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Schema;
class ForceMigration extends Command
{
use VerifiesAccessToken;
/**
* The console command description.
*
* @var string
*/
protected $description = 'This command will force-run all database migrations.';
/**
* The name and signature of the console command.
*
* @var string
*/
protected $signature = 'firefly-iii:force-migrations
{--user=1 : The user ID.}
{--token= : The user\'s access token.}';
/**
* Execute the console command.
* @throws FireflyException
*/
public function handle(): int
{
if (!$this->verifyAccessToken()) {
$this->error('Invalid access token.');
return 1;
}
$this->error('Running this command is dangerous and can cause data loss.');
$this->error('Please do not continue.');
$question = $this->confirm('Do you want to continue?');
if (true === $question) {
$user = $this->getUser();
Log::channel('audit')->info(sprintf('User #%d ("%s") forced migrations.', $user->id, $user->email));
$this->forceMigration();
return 0;
}
return 0;
}
private function forceMigration(): void
{
DB::commit();
$this->line('Dropping "migrations" table...');
sleep(2);
Schema::dropIfExists('migrations');
$this->line('Done!');
$this->line('Re-run all migrations...');
Artisan::call('migrate', ['--seed' => true]);
sleep(2);
$this->line('');
$this->info('Done!');
$this->line('There is a good chance you just saw a lot of error messages.');
$this->line('No need to panic yet. First try to access Firefly III (again).');
$this->line('The issue, whatever it was, may have been solved now.');
$this->line('');
}
}

View File

@@ -1,7 +1,7 @@
<?php
/**
/*
* ScanAttachments.php
* Copyright (c) 2020 james@firefly-iii.org
* Copyright (c) 2023 james@firefly-iii.org
*
* This file is part of Firefly III (https://github.com/firefly-iii).
*
@@ -21,13 +21,13 @@
declare(strict_types=1);
namespace FireflyIII\Console\Commands;
namespace FireflyIII\Console\Commands\System;
use Crypt;
use FireflyIII\Models\Attachment;
use Illuminate\Console\Command;
use Illuminate\Contracts\Encryption\DecryptException;
use Log;
use Illuminate\Support\Facades\Log;
use Storage;
/**
@@ -42,7 +42,7 @@ class ScanAttachments extends Command
*
* @var string
*/
protected $description = 'Rescan all attachments and re-set the MD5 hash and mime.';
protected $description = 'Rescan all attachments and re-set the correct MD5 hash and mime.';
/**
* The name and signature of the console command.

View File

@@ -1,8 +1,8 @@
<?php
/**
/*
* SetLatestVersion.php
* Copyright (c) 2020 james@firefly-iii.org
* Copyright (c) 2023 james@firefly-iii.org
*
* This file is part of Firefly III (https://github.com/firefly-iii).
*
@@ -22,7 +22,7 @@
declare(strict_types=1);
namespace FireflyIII\Console\Commands;
namespace FireflyIII\Console\Commands\System;
use Illuminate\Console\Command;

View File

@@ -1,7 +1,7 @@
<?php
/**
/*
* UpgradeFireflyInstructions.php
* Copyright (c) 2020 james@firefly-iii.org
* Copyright (c) 2023 james@firefly-iii.org
*
* This file is part of Firefly III (https://github.com/firefly-iii).
*
@@ -21,11 +21,13 @@
declare(strict_types=1);
namespace FireflyIII\Console\Commands;
namespace FireflyIII\Console\Commands\System;
use FireflyIII\Support\System\GeneratesInstallationId;
use Illuminate\Console\Command;
use function FireflyIII\Console\Commands\str_starts_with;
/**
* Class UpgradeFireflyInstructions.
*
@@ -64,51 +66,6 @@ class UpgradeFireflyInstructions extends Command
return 0;
}
/**
* Render upgrade instructions.
*/
private function updateInstructions(): void
{
/** @var string $version */
$version = config('firefly.version');
$config = config('upgrade.text.upgrade');
$text = '';
foreach (array_keys($config) as $compare) {
// if string starts with:
if (str_starts_with($version, $compare)) {
$text = $config[$compare];
}
}
$this->showLine();
$this->boxed('');
if (null === $text) {
$this->boxed(sprintf('Thank you for updating to Firefly III, v%s', $version));
$this->boxedInfo('There are no extra upgrade instructions.');
$this->boxed('Firefly III should be ready for use.');
$this->boxed('');
$this->showLine();
return;
}
$this->boxed(sprintf('Thank you for updating to Firefly III, v%s!', $version));
$this->boxedInfo($text);
$this->boxed('');
$this->showLine();
}
/**
* Show a line.
*/
private function showLine(): void
{
$line = '+';
$line .= str_repeat('-', 78);
$line .= '+';
$this->line($line);
}
/**
* Show a nice box.
*
@@ -146,13 +103,13 @@ class UpgradeFireflyInstructions extends Command
$text = '';
foreach (array_keys($config) as $compare) {
// if string starts with:
if (str_starts_with($version, $compare)) {
if (\str_starts_with($version, $compare)) {
$text = $config[$compare];
}
}
$this->showLine();
$this->boxed('');
if (null === $text) {
if (null === $text || '' === $text) {
$this->boxed(sprintf('Thank you for installing Firefly III, v%s!', $version));
$this->boxedInfo('There are no extra installation instructions.');
$this->boxed('Firefly III should be ready for use.');
@@ -167,4 +124,49 @@ class UpgradeFireflyInstructions extends Command
$this->boxed('');
$this->showLine();
}
/**
* Show a line.
*/
private function showLine(): void
{
$line = '+';
$line .= str_repeat('-', 78);
$line .= '+';
$this->line($line);
}
/**
* Render upgrade instructions.
*/
private function updateInstructions(): void
{
/** @var string $version */
$version = config('firefly.version');
$config = config('upgrade.text.upgrade');
$text = '';
foreach (array_keys($config) as $compare) {
// if string starts with:
if (\str_starts_with($version, $compare)) {
$text = $config[$compare];
}
}
$this->showLine();
$this->boxed('');
if (null === $text || '' === $text) {
$this->boxed(sprintf('Thank you for updating to Firefly III, v%s', $version));
$this->boxedInfo('There are no extra upgrade instructions.');
$this->boxed('Firefly III should be ready for use.');
$this->boxed('');
$this->showLine();
return;
}
$this->boxed(sprintf('Thank you for updating to Firefly III, v%s!', $version));
$this->boxedInfo($text);
$this->boxed('');
$this->showLine();
}
}

View File

@@ -2,7 +2,7 @@
/*
* VerifySecurityAlerts.php
* Copyright (c) 2021 james@firefly-iii.org
* Copyright (c) 2023 james@firefly-iii.org
*
* This file is part of Firefly III (https://github.com/firefly-iii).
*
@@ -22,12 +22,12 @@
declare(strict_types=1);
namespace FireflyIII\Console\Commands;
namespace FireflyIII\Console\Commands\System;
use Illuminate\Console\Command;
use Illuminate\Database\QueryException;
use Illuminate\Support\Facades\Log;
use League\Flysystem\FilesystemException;
use Log;
use Storage;
/**

View File

@@ -36,7 +36,7 @@ use FireflyIII\Repositories\RuleGroup\RuleGroupRepositoryInterface;
use FireflyIII\TransactionRules\Engine\RuleEngineInterface;
use Illuminate\Console\Command;
use Illuminate\Support\Collection;
use Log;
use Illuminate\Support\Facades\Log;
/**
* Class ApplyRules

View File

@@ -31,8 +31,8 @@ use FireflyIII\Support\Cronjobs\BillWarningCronjob;
use FireflyIII\Support\Cronjobs\ExchangeRatesCronjob;
use FireflyIII\Support\Cronjobs\RecurringCronjob;
use Illuminate\Console\Command;
use Illuminate\Support\Facades\Log;
use InvalidArgumentException;
use Log;
use Psr\Container\ContainerExceptionInterface;
use Psr\Container\NotFoundExceptionInterface;
@@ -123,62 +123,6 @@ class Cron extends Command
return 0;
}
/**
* @param bool $force
* @param Carbon|null $date
*/
private function exchangeRatesCronJob(bool $force, ?Carbon $date): void
{
$exchangeRates = new ExchangeRatesCronjob();
$exchangeRates->setForce($force);
// set date in cron job:
if (null !== $date) {
$exchangeRates->setDate($date);
}
$exchangeRates->fire();
if ($exchangeRates->jobErrored) {
$this->error(sprintf('Error in "exchange rates" cron: %s', $exchangeRates->message));
}
if ($exchangeRates->jobFired) {
$this->line(sprintf('"Exchange rates" cron fired: %s', $exchangeRates->message));
}
if ($exchangeRates->jobSucceeded) {
$this->info(sprintf('"Exchange rates" cron ran with success: %s', $exchangeRates->message));
}
}
/**
* @param bool $force
* @param Carbon|null $date
*
* @throws ContainerExceptionInterface
* @throws FireflyException
* @throws NotFoundExceptionInterface
*/
private function recurringCronJob(bool $force, ?Carbon $date): void
{
$recurring = new RecurringCronjob();
$recurring->setForce($force);
// set date in cron job:
if (null !== $date) {
$recurring->setDate($date);
}
$recurring->fire();
if ($recurring->jobErrored) {
$this->error(sprintf('Error in "create recurring transactions" cron: %s', $recurring->message));
}
if ($recurring->jobFired) {
$this->line(sprintf('"Create recurring transactions" cron fired: %s', $recurring->message));
}
if ($recurring->jobSucceeded) {
$this->info(sprintf('"Create recurring transactions" cron ran with success: %s', $recurring->message));
}
}
/**
* @param bool $force
* @param Carbon|null $date
@@ -234,4 +178,60 @@ class Cron extends Command
$this->info(sprintf('"Send bill warnings" cron ran with success: %s', $autoBudget->message));
}
}
/**
* @param bool $force
* @param Carbon|null $date
*/
private function exchangeRatesCronJob(bool $force, ?Carbon $date): void
{
$exchangeRates = new ExchangeRatesCronjob();
$exchangeRates->setForce($force);
// set date in cron job:
if (null !== $date) {
$exchangeRates->setDate($date);
}
$exchangeRates->fire();
if ($exchangeRates->jobErrored) {
$this->error(sprintf('Error in "exchange rates" cron: %s', $exchangeRates->message));
}
if ($exchangeRates->jobFired) {
$this->line(sprintf('"Exchange rates" cron fired: %s', $exchangeRates->message));
}
if ($exchangeRates->jobSucceeded) {
$this->info(sprintf('"Exchange rates" cron ran with success: %s', $exchangeRates->message));
}
}
/**
* @param bool $force
* @param Carbon|null $date
*
* @throws ContainerExceptionInterface
* @throws FireflyException
* @throws NotFoundExceptionInterface
*/
private function recurringCronJob(bool $force, ?Carbon $date): void
{
$recurring = new RecurringCronjob();
$recurring->setForce($force);
// set date in cron job:
if (null !== $date) {
$recurring->setDate($date);
}
$recurring->fire();
if ($recurring->jobErrored) {
$this->error(sprintf('Error in "create recurring transactions" cron: %s', $recurring->message));
}
if ($recurring->jobFired) {
$this->line(sprintf('"Create recurring transactions" cron fired: %s', $recurring->message));
}
if ($recurring->jobSucceeded) {
$this->info(sprintf('"Create recurring transactions" cron ran with success: %s', $recurring->message));
}
}
}

View File

@@ -33,7 +33,7 @@ use FireflyIII\Repositories\Account\AccountRepositoryInterface;
use FireflyIII\Repositories\User\UserRepositoryInterface;
use FireflyIII\User;
use Illuminate\Console\Command;
use Log;
use Illuminate\Support\Facades\Log;
use Psr\Container\ContainerExceptionInterface;
use Psr\Container\NotFoundExceptionInterface;
@@ -96,20 +96,6 @@ class AccountCurrencies extends Command
return 0;
}
/**
* Laravel will execute ALL __construct() methods for ALL commands whenever a SINGLE command is
* executed. This leads to noticeable slow-downs and class calls. To prevent this, this method should
* be called from the handle method instead of using the constructor to initialize the command.
*
*/
private function stupidLaravel(): void
{
$this->accountRepos = app(AccountRepositoryInterface::class);
$this->userRepos = app(UserRepositoryInterface::class);
$this->count = 0;
}
/**
* @return bool
* @throws ContainerExceptionInterface
@@ -128,50 +114,23 @@ class AccountCurrencies extends Command
/**
*
*/
private function updateAccountCurrencies(): void
private function markAsExecuted(): void
{
Log::debug('Now in updateAccountCurrencies()');
$users = $this->userRepos->all();
$defaultCurrencyCode = (string)config('firefly.default_currency', 'EUR');
Log::debug(sprintf('Default currency is %s', $defaultCurrencyCode));
foreach ($users as $user) {
$this->updateCurrenciesForUser($user, $defaultCurrencyCode);
}
app('fireflyconfig')->set(self::CONFIG_NAME, true);
}
/**
* @param User $user
* @param string $systemCurrencyCode
* Laravel will execute ALL __construct() methods for ALL commands whenever a SINGLE command is
* executed. This leads to noticeable slow-downs and class calls. To prevent this, this method should
* be called from the handle method instead of using the constructor to initialize the command.
*
* @throws FireflyException
*/
private function updateCurrenciesForUser(User $user, string $systemCurrencyCode): void
private function stupidLaravel(): void
{
Log::debug(sprintf('Now in updateCurrenciesForUser(%s, %s)', $user->email, $systemCurrencyCode));
$this->accountRepos->setUser($user);
$accounts = $this->accountRepos->getAccountsByType([AccountType::DEFAULT, AccountType::ASSET]);
// get user's currency preference:
$defaultCurrencyCode = app('preferences')->getForUser($user, 'currencyPreference', $systemCurrencyCode)->data;
if (!is_string($defaultCurrencyCode)) {
$defaultCurrencyCode = $systemCurrencyCode;
}
Log::debug(sprintf('Users currency pref is %s', $defaultCurrencyCode));
/** @var TransactionCurrency|null $defaultCurrency */
$defaultCurrency = TransactionCurrency::where('code', $defaultCurrencyCode)->first();
if (null === $defaultCurrency) {
Log::error(sprintf('Users currency pref "%s" does not exist!', $defaultCurrencyCode));
$this->error(sprintf('User has a preference for "%s", but this currency does not exist.', $defaultCurrencyCode));
return;
}
/** @var Account $account */
foreach ($accounts as $account) {
$this->updateAccount($account, $defaultCurrency);
}
$this->accountRepos = app(AccountRepositoryInterface::class);
$this->userRepos = app(UserRepositoryInterface::class);
$this->count = 0;
}
/**
@@ -237,8 +196,49 @@ class AccountCurrencies extends Command
/**
*
*/
private function markAsExecuted(): void
private function updateAccountCurrencies(): void
{
app('fireflyconfig')->set(self::CONFIG_NAME, true);
Log::debug('Now in updateAccountCurrencies()');
$users = $this->userRepos->all();
$defaultCurrencyCode = (string)config('firefly.default_currency', 'EUR');
Log::debug(sprintf('Default currency is %s', $defaultCurrencyCode));
foreach ($users as $user) {
$this->updateCurrenciesForUser($user, $defaultCurrencyCode);
}
}
/**
* @param User $user
* @param string $systemCurrencyCode
*
* @throws FireflyException
*/
private function updateCurrenciesForUser(User $user, string $systemCurrencyCode): void
{
Log::debug(sprintf('Now in updateCurrenciesForUser(%s, %s)', $user->email, $systemCurrencyCode));
$this->accountRepos->setUser($user);
$accounts = $this->accountRepos->getAccountsByType([AccountType::DEFAULT, AccountType::ASSET]);
// get user's currency preference:
$defaultCurrencyCode = app('preferences')->getForUser($user, 'currencyPreference', $systemCurrencyCode)->data;
if (!is_string($defaultCurrencyCode)) {
$defaultCurrencyCode = $systemCurrencyCode;
}
Log::debug(sprintf('Users currency pref is %s', $defaultCurrencyCode));
/** @var TransactionCurrency|null $defaultCurrency */
$defaultCurrency = TransactionCurrency::where('code', $defaultCurrencyCode)->first();
if (null === $defaultCurrency) {
Log::error(sprintf('Users currency pref "%s" does not exist!', $defaultCurrencyCode));
$this->error(sprintf('User has a preference for "%s", but this currency does not exist.', $defaultCurrencyCode));
return;
}
/** @var Account $account */
foreach ($accounts as $account) {
$this->updateAccount($account, $defaultCurrency);
}
}
}

View File

@@ -26,7 +26,7 @@ namespace FireflyIII\Console\Commands\Upgrade;
use FireflyIII\Exceptions\FireflyException;
use FireflyIII\Models\BudgetLimit;
use Illuminate\Console\Command;
use Log;
use Illuminate\Support\Facades\Log;
use Psr\Container\ContainerExceptionInterface;
use Psr\Container\NotFoundExceptionInterface;
@@ -73,30 +73,6 @@ class AppendBudgetLimitPeriods extends Command
return 0;
}
/**
* @return bool
* @throws ContainerExceptionInterface
* @throws NotFoundExceptionInterface
*/
private function isExecuted(): bool
{
$configVar = app('fireflyconfig')->get(self::CONFIG_NAME, false);
return (bool)$configVar->data;
}
/**
*
*/
private function theresNoLimit(): void
{
$limits = BudgetLimit::whereNull('period')->get();
/** @var BudgetLimit $limit */
foreach ($limits as $limit) {
$this->fixLimit($limit);
}
}
/**
* @param BudgetLimit $limit
*/
@@ -182,6 +158,18 @@ class AppendBudgetLimitPeriods extends Command
return null;
}
/**
* @return bool
* @throws ContainerExceptionInterface
* @throws NotFoundExceptionInterface
*/
private function isExecuted(): bool
{
$configVar = app('fireflyconfig')->get(self::CONFIG_NAME, false);
return (bool)$configVar->data;
}
/**
*
*/
@@ -189,4 +177,16 @@ class AppendBudgetLimitPeriods extends Command
{
app('fireflyconfig')->set(self::CONFIG_NAME, true);
}
/**
*
*/
private function theresNoLimit(): void
{
$limits = BudgetLimit::whereNull('period')->get();
/** @var BudgetLimit $limit */
foreach ($limits as $limit) {
$this->fixLimit($limit);
}
}
}

View File

@@ -31,7 +31,7 @@ use FireflyIII\Models\Transaction;
use FireflyIII\Models\TransactionJournal;
use Illuminate\Console\Command;
use Illuminate\Support\Collection;
use Log;
use Illuminate\Support\Facades\Log;
use Psr\Container\ContainerExceptionInterface;
use Psr\Container\NotFoundExceptionInterface;
@@ -87,15 +87,39 @@ class BackToJournals extends Command
}
/**
* @return bool
* @throws ContainerExceptionInterface
* @throws NotFoundExceptionInterface
* @return array
*/
private function isMigrated(): bool
private function getIdsForBudgets(): array
{
$configVar = app('fireflyconfig')->get(MigrateToGroups::CONFIG_NAME, false);
$transactions = DB::table('budget_transaction')->distinct()->pluck('transaction_id')->toArray();
$array = [];
$chunks = array_chunk($transactions, 500);
return (bool)$configVar->data;
foreach ($chunks as $chunk) {
$set = DB::table('transactions')->whereIn('transactions.id', $chunk)->pluck('transaction_journal_id')->toArray();
$array = array_merge($array, $set);
}
return $array;
}
/**
* @return array
*/
private function getIdsForCategories(): array
{
$transactions = DB::table('category_transaction')->distinct()->pluck('transaction_id')->toArray();
$array = [];
$chunks = array_chunk($transactions, 500);
foreach ($chunks as $chunk) {
$set = DB::table('transactions')
->whereIn('transactions.id', $chunk)
->pluck('transaction_journal_id')->toArray();
$array = array_merge($array, $set);
}
return $array;
}
/**
@@ -110,6 +134,26 @@ class BackToJournals extends Command
return (bool)$configVar->data;
}
/**
* @return bool
* @throws ContainerExceptionInterface
* @throws NotFoundExceptionInterface
*/
private function isMigrated(): bool
{
$configVar = app('fireflyconfig')->get(MigrateToGroups::CONFIG_NAME, false);
return (bool)$configVar->data;
}
/**
*
*/
private function markAsExecuted(): void
{
app('fireflyconfig')->set(self::CONFIG_NAME, true);
}
/**
*
*/
@@ -143,23 +187,6 @@ class BackToJournals extends Command
}
}
/**
* @return array
*/
private function getIdsForBudgets(): array
{
$transactions = DB::table('budget_transaction')->distinct()->pluck('transaction_id')->toArray();
$array = [];
$chunks = array_chunk($transactions, 500);
foreach ($chunks as $chunk) {
$set = DB::table('transactions')->whereIn('transactions.id', $chunk)->pluck('transaction_journal_id')->toArray();
$array = array_merge($array, $set);
}
return $array;
}
/**
* @param TransactionJournal $journal
*/
@@ -217,25 +244,6 @@ class BackToJournals extends Command
}
}
/**
* @return array
*/
private function getIdsForCategories(): array
{
$transactions = DB::table('category_transaction')->distinct()->pluck('transaction_id')->toArray();
$array = [];
$chunks = array_chunk($transactions, 500);
foreach ($chunks as $chunk) {
$set = DB::table('transactions')
->whereIn('transactions.id', $chunk)
->pluck('transaction_journal_id')->toArray();
$array = array_merge($array, $set);
}
return $array;
}
/**
* @param TransactionJournal $journal
*/
@@ -265,12 +273,4 @@ class BackToJournals extends Command
$journal->categories()->sync([(int)$category->id]);
}
}
/**
*
*/
private function markAsExecuted(): void
{
app('fireflyconfig')->set(self::CONFIG_NAME, true);
}
}

View File

@@ -1,8 +1,8 @@
<?php
/**
/*
* DecryptDatabase.php
* Copyright (c) 2020 james@firefly-iii.org
* Copyright (c) 2023 james@firefly-iii.org
*
* This file is part of Firefly III (https://github.com/firefly-iii).
*
@@ -22,7 +22,7 @@
declare(strict_types=1);
namespace FireflyIII\Console\Commands;
namespace FireflyIII\Console\Commands\Upgrade;
use Crypt;
use DB;
@@ -30,8 +30,8 @@ use FireflyIII\Exceptions\FireflyException;
use FireflyIII\Models\Preference;
use Illuminate\Console\Command;
use Illuminate\Contracts\Encryption\DecryptException;
use Illuminate\Support\Facades\Log;
use JsonException;
use Log;
use Psr\Container\ContainerExceptionInterface;
use Psr\Container\NotFoundExceptionInterface;
use stdClass;
@@ -87,6 +87,81 @@ class DecryptDatabase extends Command
return 0;
}
/**
* @param string $table
* @param string $field
*/
private function decryptField(string $table, string $field): void
{
$rows = DB::table($table)->get(['id', $field]);
/** @var stdClass $row */
foreach ($rows as $row) {
$this->decryptRow($table, $field, $row);
}
}
/**
* @param int $id
* @param string $value
*/
private function decryptPreferencesRow(int $id, string $value): void
{
// try to json_decrypt the value.
try {
$newValue = json_decode($value, true, 512, JSON_THROW_ON_ERROR) ?? $value;
} catch (JsonException $e) {
$message = sprintf('Could not JSON decode preference row #%d: %s. This does not have to be a problem.', $id, $e->getMessage());
$this->error($message);
app('log')->warning($message);
app('log')->warning($value);
app('log')->warning($e->getTraceAsString());
return;
}
/** @var Preference $object */
$object = Preference::find((int)$id);
if (null !== $object) {
$object->data = $newValue;
$object->save();
}
}
/**
* @param string $table
* @param string $field
* @param stdClass $row
*/
private function decryptRow(string $table, string $field, stdClass $row): void
{
$original = $row->$field;
if (null === $original) {
return;
}
$id = (int)$row->id;
$value = '';
try {
$value = $this->tryDecrypt($original);
} catch (FireflyException $e) {
$message = sprintf('Could not decrypt field "%s" in row #%d of table "%s": %s', $field, $id, $table, $e->getMessage());
$this->error($message);
Log::error($message);
Log::error($e->getTraceAsString());
}
// A separate routine for preferences table:
if ('preferences' === $table) {
$this->decryptPreferencesRow($id, $value);
return;
}
if ($value !== $original) {
DB::table($table)->where('id', $id)->update([$field => $value]);
}
}
/**
* @param string $table
* @param array $fields
@@ -132,54 +207,6 @@ class DecryptDatabase extends Command
return false;
}
/**
* @param string $table
* @param string $field
*/
private function decryptField(string $table, string $field): void
{
$rows = DB::table($table)->get(['id', $field]);
/** @var stdClass $row */
foreach ($rows as $row) {
$this->decryptRow($table, $field, $row);
}
}
/**
* @param string $table
* @param string $field
* @param stdClass $row
*/
private function decryptRow(string $table, string $field, stdClass $row): void
{
$original = $row->$field;
if (null === $original) {
return;
}
$id = (int)$row->id;
$value = '';
try {
$value = $this->tryDecrypt($original);
} catch (FireflyException $e) {
$message = sprintf('Could not decrypt field "%s" in row #%d of table "%s": %s', $field, $id, $table, $e->getMessage());
$this->error($message);
Log::error($message);
Log::error($e->getTraceAsString());
}
// A separate routine for preferences table:
if ('preferences' === $table) {
$this->decryptPreferencesRow($id, $value);
return;
}
if ($value !== $original) {
DB::table($table)->where('id', $id)->update([$field => $value]);
}
}
/**
* Tries to decrypt data. Will only throw an exception when the MAC is invalid.
*
@@ -200,31 +227,4 @@ class DecryptDatabase extends Command
return $value;
}
/**
* @param int $id
* @param string $value
*/
private function decryptPreferencesRow(int $id, string $value): void
{
// try to json_decrypt the value.
try {
$newValue = json_decode($value, true, 512, JSON_THROW_ON_ERROR) ?? $value;
} catch (JsonException $e) {
$message = sprintf('Could not JSON decode preference row #%d: %s. This does not have to be a problem.', $id, $e->getMessage());
$this->error($message);
app('log')->warning($message);
app('log')->warning($value);
app('log')->warning($e->getTraceAsString());
return;
}
/** @var Preference $object */
$object = Preference::find((int)$id);
if (null !== $object) {
$object->data = $newValue;
$object->save();
}
}
}

View File

@@ -2,7 +2,7 @@
/*
* FixPostgresSequences.php
* Copyright (c) 2021 james@firefly-iii.org
* Copyright (c) 2023 james@firefly-iii.org
*
* This file is part of Firefly III (https://github.com/firefly-iii).
*
@@ -22,7 +22,7 @@
declare(strict_types=1);
namespace FireflyIII\Console\Commands\Correction;
namespace FireflyIII\Console\Commands\Upgrade;
use DB;
use Illuminate\Console\Command;
@@ -76,10 +76,8 @@ class FixPostgresSequences extends Command
'category_transaction_journal',
'configuration',
'currency_exchange_rates',
'export_jobs',
'failed_jobs',
'group_journals',
'import_jobs',
'jobs',
'journal_links',
'journal_meta',

View File

@@ -27,7 +27,7 @@ use FireflyIII\Exceptions\FireflyException;
use FireflyIII\Models\Attachment;
use FireflyIII\Models\Note;
use Illuminate\Console\Command;
use Log;
use Illuminate\Support\Facades\Log;
use Psr\Container\ContainerExceptionInterface;
use Psr\Container\NotFoundExceptionInterface;

View File

@@ -27,7 +27,7 @@ use FireflyIII\Exceptions\FireflyException;
use FireflyIII\Models\Note;
use FireflyIII\Models\TransactionJournalMeta;
use Illuminate\Console\Command;
use Log;
use Illuminate\Support\Facades\Log;
use Psr\Container\ContainerExceptionInterface;
use Psr\Container\NotFoundExceptionInterface;

View File

@@ -102,20 +102,11 @@ class MigrateRecurrenceMeta extends Command
}
/**
* @return int
* @throws JsonException
*
*/
private function migrateMetaData(): int
private function markAsExecuted(): void
{
$count = 0;
// get all recurrence meta data:
$collection = RecurrenceMeta::with('recurrence')->get();
/** @var RecurrenceMeta $meta */
foreach ($collection as $meta) {
$count += $this->migrateEntry($meta);
}
return $count;
app('fireflyconfig')->set(self::CONFIG_NAME, true);
}
/**
@@ -155,10 +146,19 @@ class MigrateRecurrenceMeta extends Command
}
/**
*
* @return int
* @throws JsonException
*/
private function markAsExecuted(): void
private function migrateMetaData(): int
{
app('fireflyconfig')->set(self::CONFIG_NAME, true);
$count = 0;
// get all recurrence meta data:
$collection = RecurrenceMeta::with('recurrence')->get();
/** @var RecurrenceMeta $meta */
foreach ($collection as $meta) {
$count += $this->migrateEntry($meta);
}
return $count;
}
}

View File

@@ -78,6 +78,14 @@ class MigrateRecurrenceType extends Command
return 0;
}
/**
*
*/
private function getInvalidType(): TransactionType
{
return TransactionType::whereType(TransactionType::INVALID)->firstOrCreate(['type' => TransactionType::INVALID]);
}
/**
* @return bool
* @throws ContainerExceptionInterface
@@ -96,15 +104,9 @@ class MigrateRecurrenceType extends Command
/**
*
*/
private function migrateTypes(): void
private function markAsExecuted(): void
{
$set = Recurrence::get();
/** @var Recurrence $recurrence */
foreach ($set as $recurrence) {
if ($recurrence->transactionType->type !== TransactionType::INVALID) {
$this->migrateRecurrence($recurrence);
}
}
app('fireflyconfig')->set(self::CONFIG_NAME, true);
}
private function migrateRecurrence(Recurrence $recurrence): void
@@ -124,16 +126,14 @@ class MigrateRecurrenceType extends Command
/**
*
*/
private function getInvalidType(): TransactionType
private function migrateTypes(): void
{
return TransactionType::whereType(TransactionType::INVALID)->firstOrCreate(['type' => TransactionType::INVALID]);
}
/**
*
*/
private function markAsExecuted(): void
{
app('fireflyconfig')->set(self::CONFIG_NAME, true);
$set = Recurrence::get();
/** @var Recurrence $recurrence */
foreach ($set as $recurrence) {
if ($recurrence->transactionType->type !== TransactionType::INVALID) {
$this->migrateRecurrence($recurrence);
}
}
}
}

View File

@@ -75,6 +75,16 @@ class MigrateTagLocations extends Command
return 0;
}
/**
* @param Tag $tag
*
* @return bool
*/
private function hasLocationDetails(Tag $tag): bool
{
return null !== $tag->latitude && null !== $tag->longitude && null !== $tag->zoomLevel;
}
/**
* @return bool
* @throws ContainerExceptionInterface
@@ -90,25 +100,12 @@ class MigrateTagLocations extends Command
return false;
}
private function migrateTagLocations(): void
{
$tags = Tag::get();
/** @var Tag $tag */
foreach ($tags as $tag) {
if ($this->hasLocationDetails($tag)) {
$this->migrateLocationDetails($tag);
}
}
}
/**
* @param Tag $tag
*
* @return bool
*/
private function hasLocationDetails(Tag $tag): bool
private function markAsExecuted(): void
{
return null !== $tag->latitude && null !== $tag->longitude && null !== $tag->zoomLevel;
app('fireflyconfig')->set(self::CONFIG_NAME, true);
}
/**
@@ -129,11 +126,14 @@ class MigrateTagLocations extends Command
$tag->save();
}
/**
*
*/
private function markAsExecuted(): void
private function migrateTagLocations(): void
{
app('fireflyconfig')->set(self::CONFIG_NAME, true);
$tags = Tag::get();
/** @var Tag $tag */
foreach ($tags as $tag) {
if ($this->hasLocationDetails($tag)) {
$this->migrateLocationDetails($tag);
}
}
}
}

View File

@@ -36,7 +36,7 @@ use FireflyIII\Repositories\Journal\JournalRepositoryInterface;
use FireflyIII\Services\Internal\Destroy\JournalDestroyService;
use Illuminate\Console\Command;
use Illuminate\Support\Collection;
use Log;
use Illuminate\Support\Facades\Log;
use Psr\Container\ContainerExceptionInterface;
use Psr\Container\NotFoundExceptionInterface;

View File

@@ -105,22 +105,6 @@ class MigrateToRules extends Command
return 0;
}
/**
* Laravel will execute ALL __construct() methods for ALL commands whenever a SINGLE command is
* executed. This leads to noticeable slow-downs and class calls. To prevent this, this method should
* be called from the handle method instead of using the constructor to initialize the command.
*
*/
private function stupidLaravel(): void
{
$this->count = 0;
$this->userRepository = app(UserRepositoryInterface::class);
$this->ruleGroupRepository = app(RuleGroupRepositoryInterface::class);
$this->billRepository = app(BillRepositoryInterface::class);
$this->ruleRepository = app(RuleRepositoryInterface::class);
}
/**
* @return bool
* @throws ContainerExceptionInterface
@@ -137,38 +121,11 @@ class MigrateToRules extends Command
}
/**
* Migrate bills to new rule structure for a specific user.
*
* @param User $user
*
* @throws FireflyException
*/
private function migrateUser(User $user): void
private function markAsExecuted(): void
{
$this->ruleGroupRepository->setUser($user);
$this->billRepository->setUser($user);
$this->ruleRepository->setUser($user);
/** @var Preference $lang */
$lang = app('preferences')->getForUser($user, 'language', 'en_US');
$groupTitle = (string)trans('firefly.rulegroup_for_bills_title', [], $lang->data);
$ruleGroup = $this->ruleGroupRepository->findByTitle($groupTitle);
if (null === $ruleGroup) {
$ruleGroup = $this->ruleGroupRepository->store(
[
'title' => (string)trans('firefly.rulegroup_for_bills_title', [], $lang->data),
'description' => (string)trans('firefly.rulegroup_for_bills_description', [], $lang->data),
'active' => true,
]
);
}
$bills = $this->billRepository->getBills();
/** @var Bill $bill */
foreach ($bills as $bill) {
$this->migrateBill($ruleGroup, $bill, $lang);
}
app('fireflyconfig')->set(self::CONFIG_NAME, true);
}
/**
@@ -243,10 +200,53 @@ class MigrateToRules extends Command
}
/**
* Migrate bills to new rule structure for a specific user.
*
* @param User $user
*
* @throws FireflyException
*/
private function markAsExecuted(): void
private function migrateUser(User $user): void
{
app('fireflyconfig')->set(self::CONFIG_NAME, true);
$this->ruleGroupRepository->setUser($user);
$this->billRepository->setUser($user);
$this->ruleRepository->setUser($user);
/** @var Preference $lang */
$lang = app('preferences')->getForUser($user, 'language', 'en_US');
$groupTitle = (string)trans('firefly.rulegroup_for_bills_title', [], $lang->data);
$ruleGroup = $this->ruleGroupRepository->findByTitle($groupTitle);
if (null === $ruleGroup) {
$ruleGroup = $this->ruleGroupRepository->store(
[
'title' => (string)trans('firefly.rulegroup_for_bills_title', [], $lang->data),
'description' => (string)trans('firefly.rulegroup_for_bills_description', [], $lang->data),
'active' => true,
]
);
}
$bills = $this->billRepository->getBills();
/** @var Bill $bill */
foreach ($bills as $bill) {
$this->migrateBill($ruleGroup, $bill, $lang);
}
}
/**
* Laravel will execute ALL __construct() methods for ALL commands whenever a SINGLE command is
* executed. This leads to noticeable slow-downs and class calls. To prevent this, this method should
* be called from the handle method instead of using the constructor to initialize the command.
*
*/
private function stupidLaravel(): void
{
$this->count = 0;
$this->userRepository = app(UserRepositoryInterface::class);
$this->ruleGroupRepository = app(RuleGroupRepositoryInterface::class);
$this->billRepository = app(BillRepositoryInterface::class);
$this->ruleRepository = app(RuleRepositoryInterface::class);
}
}

View File

@@ -29,7 +29,7 @@ use FireflyIII\Models\TransactionJournal;
use FireflyIII\Repositories\Journal\JournalCLIRepositoryInterface;
use Illuminate\Console\Command;
use Illuminate\Database\QueryException;
use Log;
use Illuminate\Support\Facades\Log;
use Psr\Container\ContainerExceptionInterface;
use Psr\Container\NotFoundExceptionInterface;
use Schema;
@@ -107,63 +107,6 @@ class TransactionIdentifier extends Command
return 0;
}
/**
* Laravel will execute ALL __construct() methods for ALL commands whenever a SINGLE command is
* executed. This leads to noticeable slow-downs and class calls. To prevent this, this method should
* be called from the handle method instead of using the constructor to initialize the command.
*
*/
private function stupidLaravel(): void
{
$this->cliRepository = app(JournalCLIRepositoryInterface::class);
$this->count = 0;
}
/**
* @return bool
* @throws ContainerExceptionInterface
* @throws NotFoundExceptionInterface
*/
private function isExecuted(): bool
{
$configVar = app('fireflyconfig')->get(self::CONFIG_NAME, false);
if (null !== $configVar) {
return (bool)$configVar->data;
}
return false;
}
/**
* Grab all positive transactions from this journal that are not deleted. for each one, grab the negative opposing one
* which has 0 as an identifier and give it the same identifier.
*
* @param TransactionJournal $transactionJournal
*/
private function updateJournalIdentifiers(TransactionJournal $transactionJournal): void
{
$identifier = 0;
$exclude = []; // transactions already processed.
$transactions = $transactionJournal->transactions()->where('amount', '>', 0)->get();
/** @var Transaction $transaction */
foreach ($transactions as $transaction) {
$opposing = $this->findOpposing($transaction, $exclude);
if (null !== $opposing) {
// give both a new identifier:
$transaction->identifier = $identifier;
$opposing->identifier = $identifier;
$transaction->save();
$opposing->save();
$exclude[] = $transaction->id;
$exclude[] = $opposing->id;
$this->count++;
}
++$identifier;
}
}
/**
* @param Transaction $transaction
* @param array $exclude
@@ -194,6 +137,21 @@ class TransactionIdentifier extends Command
return $opposing;
}
/**
* @return bool
* @throws ContainerExceptionInterface
* @throws NotFoundExceptionInterface
*/
private function isExecuted(): bool
{
$configVar = app('fireflyconfig')->get(self::CONFIG_NAME, false);
if (null !== $configVar) {
return (bool)$configVar->data;
}
return false;
}
/**
*
*/
@@ -201,4 +159,46 @@ class TransactionIdentifier extends Command
{
app('fireflyconfig')->set(self::CONFIG_NAME, true);
}
/**
* Laravel will execute ALL __construct() methods for ALL commands whenever a SINGLE command is
* executed. This leads to noticeable slow-downs and class calls. To prevent this, this method should
* be called from the handle method instead of using the constructor to initialize the command.
*
*/
private function stupidLaravel(): void
{
$this->cliRepository = app(JournalCLIRepositoryInterface::class);
$this->count = 0;
}
/**
* Grab all positive transactions from this journal that are not deleted. for each one, grab the negative opposing one
* which has 0 as an identifier and give it the same identifier.
*
* @param TransactionJournal $transactionJournal
*/
private function updateJournalIdentifiers(TransactionJournal $transactionJournal): void
{
$identifier = 0;
$exclude = []; // transactions already processed.
$transactions = $transactionJournal->transactions()->where('amount', '>', 0)->get();
/** @var Transaction $transaction */
foreach ($transactions as $transaction) {
$opposing = $this->findOpposing($transaction, $exclude);
if (null !== $opposing) {
// give both a new identifier:
$transaction->identifier = $identifier;
$opposing->identifier = $identifier;
$transaction->save();
$opposing->save();
$exclude[] = $transaction->id;
$exclude[] = $opposing->id;
$this->count++;
}
++$identifier;
}
}
}

View File

@@ -32,7 +32,7 @@ use FireflyIII\Models\TransactionType;
use FireflyIII\Repositories\Account\AccountRepositoryInterface;
use FireflyIII\Repositories\Journal\JournalCLIRepositoryInterface;
use Illuminate\Console\Command;
use Log;
use Illuminate\Support\Facades\Log;
use Psr\Container\ContainerExceptionInterface;
use Psr\Container\NotFoundExceptionInterface;

View File

@@ -57,7 +57,6 @@ class UpgradeDatabase extends Command
{
$this->callInitialCommands();
$commands = [
// there are 14 upgrade commands.
'firefly-iii:transaction-identifiers',
'firefly-iii:migrate-to-groups',
'firefly-iii:account-currencies',
@@ -75,41 +74,7 @@ class UpgradeDatabase extends Command
'firefly-iii:migrate-recurrence-type',
'firefly-iii:upgrade-liabilities',
'firefly-iii:liabilities-600',
// there are 16 verify commands.
'firefly-iii:fix-piggies',
'firefly-iii:create-link-types',
'firefly-iii:create-access-tokens',
'firefly-iii:remove-bills',
'firefly-iii:fix-negative-limits',
'firefly-iii:enable-currencies',
'firefly-iii:fix-transfer-budgets',
'firefly-iii:fix-uneven-amount',
'firefly-iii:delete-zero-amount',
'firefly-iii:delete-orphaned-transactions',
'firefly-iii:delete-empty-journals',
'firefly-iii:delete-empty-groups',
'firefly-iii:fix-account-types',
'firefly-iii:fix-account-order',
'firefly-iii:rename-meta-fields',
'firefly-iii:fix-ob-currencies',
'firefly-iii:fix-long-descriptions',
'firefly-iii:fix-recurring-transactions',
'firefly-iii:unify-group-accounts',
'firefly-iii:fix-transaction-types',
'firefly-iii:fix-frontpage-accounts',
'firefly-iii:fix-ibans',
'firefly-iii:create-group-memberships',
'firefly-iii:upgrade-group-information',
// two report commands
'firefly-iii:report-empty-objects',
'firefly-iii:report-sum',
'firefly-iii:restore-oauth-keys',
// instructions
'firefly:instructions update',
'firefly-iii:verify-security-alerts',
'firefly-iii:budget-limit-periods',
];
$args = [];
if ($this->option('force')) {
@@ -117,9 +82,7 @@ class UpgradeDatabase extends Command
}
foreach ($commands as $command) {
$this->line(sprintf('Now executing %s', $command));
Artisan::call($command, $args);
$result = Artisan::output();
echo $result;
$this->call($command, $args);
}
// set new DB version.
app('fireflyconfig')->set('db_version', (int)config('firefly.db_version'));
@@ -129,22 +92,19 @@ class UpgradeDatabase extends Command
return 0;
}
/**
* @return void
*/
private function callInitialCommands(): void
{
$this->line('Now seeding the database...');
Artisan::call('migrate', ['--seed' => true, '--force' => true]);
$result = Artisan::output();
echo $result;
$this->call('migrate', ['--seed' => true, '--force' => true, '--no-interaction' => true]);
$this->line('Fix PostgreSQL sequences.');
Artisan::call('firefly-iii:fix-pgsql-sequences');
$result = Artisan::output();
echo $result;
$this->call('firefly-iii:fix-pgsql-sequences');
$this->line('Now decrypting the database (if necessary)...');
Artisan::call('firefly-iii:decrypt-all');
$result = Artisan::output();
echo $result;
$this->call('firefly-iii:decrypt-all');
$this->line('Done!');
}

View File

@@ -33,7 +33,7 @@ use FireflyIII\Repositories\Account\AccountRepositoryInterface;
use FireflyIII\Services\Internal\Support\CreditRecalculateService;
use FireflyIII\User;
use Illuminate\Console\Command;
use Log;
use Illuminate\Support\Facades\Log;
use Psr\Container\ContainerExceptionInterface;
use Psr\Container\NotFoundExceptionInterface;
@@ -82,79 +82,6 @@ class UpgradeLiabilities extends Command
return 0;
}
/**
* @return bool
* @throws ContainerExceptionInterface
* @throws NotFoundExceptionInterface
*/
private function isExecuted(): bool
{
$configVar = app('fireflyconfig')->get(self::CONFIG_NAME, false);
if (null !== $configVar) {
return (bool)$configVar->data;
}
return false;
}
/**
*
*/
private function upgradeLiabilities(): void
{
Log::debug('Upgrading liabilities.');
$users = User::get();
/** @var User $user */
foreach ($users as $user) {
$this->upgradeForUser($user);
}
}
/**
* @param User $user
*/
private function upgradeForUser(User $user): void
{
Log::debug(sprintf('Upgrading liabilities for user #%d', $user->id));
$accounts = $user->accounts()
->leftJoin('account_types', 'account_types.id', '=', 'accounts.account_type_id')
->whereIn('account_types.type', config('firefly.valid_liabilities'))
->get(['accounts.*']);
/** @var Account $account */
foreach ($accounts as $account) {
$this->upgradeLiability($account);
$service = app(CreditRecalculateService::class);
$service->setAccount($account);
$service->recalculate();
}
}
/**
* @param Account $account
*/
private function upgradeLiability(Account $account): void
{
/** @var AccountRepositoryInterface $repository */
$repository = app(AccountRepositoryInterface::class);
$repository->setUser($account->user);
Log::debug(sprintf('Upgrade liability #%d', $account->id));
// get opening balance, and correct if necessary.
$openingBalance = $repository->getOpeningBalance($account);
if (null !== $openingBalance) {
// correct if necessary
$this->correctOpeningBalance($account, $openingBalance);
}
// add liability direction property (if it does not yet exist!)
$value = $repository->getMetaValue($account, 'liability_direction');
if (null === $value) {
/** @var AccountMetaFactory $factory */
$factory = app(AccountMetaFactory::class);
$factory->crud($account, 'liability_direction', 'debit');
}
}
/**
* @param Account $account
* @param TransactionJournal $openingBalance
@@ -185,9 +112,9 @@ class UpgradeLiabilities extends Command
*
* @return Transaction|null
*/
private function getSourceTransaction(TransactionJournal $journal): ?Transaction
private function getDestinationTransaction(TransactionJournal $journal): ?Transaction
{
return $journal->transactions()->where('amount', '<', 0)->first();
return $journal->transactions()->where('amount', '>', 0)->first();
}
/**
@@ -195,9 +122,24 @@ class UpgradeLiabilities extends Command
*
* @return Transaction|null
*/
private function getDestinationTransaction(TransactionJournal $journal): ?Transaction
private function getSourceTransaction(TransactionJournal $journal): ?Transaction
{
return $journal->transactions()->where('amount', '>', 0)->first();
return $journal->transactions()->where('amount', '<', 0)->first();
}
/**
* @return bool
* @throws ContainerExceptionInterface
* @throws NotFoundExceptionInterface
*/
private function isExecuted(): bool
{
$configVar = app('fireflyconfig')->get(self::CONFIG_NAME, false);
if (null !== $configVar) {
return (bool)$configVar->data;
}
return false;
}
/**
@@ -207,4 +149,62 @@ class UpgradeLiabilities extends Command
{
app('fireflyconfig')->set(self::CONFIG_NAME, true);
}
/**
* @param User $user
*/
private function upgradeForUser(User $user): void
{
Log::debug(sprintf('Upgrading liabilities for user #%d', $user->id));
$accounts = $user->accounts()
->leftJoin('account_types', 'account_types.id', '=', 'accounts.account_type_id')
->whereIn('account_types.type', config('firefly.valid_liabilities'))
->get(['accounts.*']);
/** @var Account $account */
foreach ($accounts as $account) {
$this->upgradeLiability($account);
$service = app(CreditRecalculateService::class);
$service->setAccount($account);
$service->recalculate();
}
}
/**
*
*/
private function upgradeLiabilities(): void
{
Log::debug('Upgrading liabilities.');
$users = User::get();
/** @var User $user */
foreach ($users as $user) {
$this->upgradeForUser($user);
}
}
/**
* @param Account $account
*/
private function upgradeLiability(Account $account): void
{
/** @var AccountRepositoryInterface $repository */
$repository = app(AccountRepositoryInterface::class);
$repository->setUser($account->user);
Log::debug(sprintf('Upgrade liability #%d', $account->id));
// get opening balance, and correct if necessary.
$openingBalance = $repository->getOpeningBalance($account);
if (null !== $openingBalance) {
// correct if necessary
$this->correctOpeningBalance($account, $openingBalance);
}
// add liability direction property (if it does not yet exist!)
$value = $repository->getMetaValue($account, 'liability_direction');
if (null === $value) {
/** @var AccountMetaFactory $factory */
$factory = app(AccountMetaFactory::class);
$factory->crud($account, 'liability_direction', 'debit');
}
}
}

View File

@@ -83,115 +83,6 @@ class UpgradeLiabilitiesEight extends Command
return 0;
}
/**
* @return bool
* @throws ContainerExceptionInterface
* @throws NotFoundExceptionInterface
*/
private function isExecuted(): bool
{
$configVar = app('fireflyconfig')->get(self::CONFIG_NAME, false);
if (null !== $configVar) {
return (bool)$configVar->data;
}
return false;
}
/**
*
*/
private function upgradeLiabilities(): void
{
Log::debug('Upgrading liabilities.');
$users = User::get();
/** @var User $user */
foreach ($users as $user) {
$this->upgradeForUser($user);
}
}
/**
* @param User $user
*/
private function upgradeForUser(User $user): void
{
Log::debug(sprintf('Upgrading liabilities for user #%d', $user->id));
$accounts = $user->accounts()
->leftJoin('account_types', 'account_types.id', '=', 'accounts.account_type_id')
->whereIn('account_types.type', config('firefly.valid_liabilities'))
->get(['accounts.*']);
/** @var Account $account */
foreach ($accounts as $account) {
$this->upgradeLiability($account);
$service = app(CreditRecalculateService::class);
$service->setAccount($account);
$service->recalculate();
}
}
/**
* @param Account $account
*/
private function upgradeLiability(Account $account): void
{
Log::debug(sprintf('Upgrade liability #%d ("%s")', $account->id, $account->name));
/** @var AccountRepositoryInterface $repository */
$repository = app(AccountRepositoryInterface::class);
$repository->setUser($account->user);
$direction = $repository->getMetaValue($account, 'liability_direction');
if ('debit' === $direction) {
Log::debug('Direction is debit ("I owe this amount"), so no need to upgrade.');
}
if ('credit' === $direction && $this->hasBadOpening($account)) {
$this->deleteCreditTransaction($account);
$this->reverseOpeningBalance($account);
$this->line(sprintf('Corrected opening balance for liability #%d ("%s")', $account->id, $account->name));
}
if ('credit' === $direction) {
$count = $this->deleteTransactions($account);
if ($count > 0) {
$this->line(sprintf('Removed %d old format transaction(s) for liability #%d ("%s")', $count, $account->id, $account->name));
}
}
Log::debug(sprintf('Done upgrading liability #%d ("%s")', $account->id, $account->name));
}
/**
* @param Account $account
* @return bool
*/
private function hasBadOpening(Account $account): bool
{
$openingBalanceType = TransactionType::whereType(TransactionType::OPENING_BALANCE)->first();
$liabilityType = TransactionType::whereType(TransactionType::LIABILITY_CREDIT)->first();
$openingJournal = TransactionJournal::leftJoin('transactions', 'transactions.transaction_journal_id', '=', 'transaction_journals.id')
->where('transactions.account_id', $account->id)
->where('transaction_journals.transaction_type_id', $openingBalanceType->id)
->first(['transaction_journals.*']);
if (null === $openingJournal) {
Log::debug('Account has no opening balance and can be skipped.');
return false;
}
$liabilityJournal = TransactionJournal::leftJoin('transactions', 'transactions.transaction_journal_id', '=', 'transaction_journals.id')
->where('transactions.account_id', $account->id)
->where('transaction_journals.transaction_type_id', $liabilityType->id)
->first(['transaction_journals.*']);
if (null === $liabilityJournal) {
Log::debug('Account has no liability credit and can be skipped.');
return false;
}
if (!$openingJournal->date->isSameDay($liabilityJournal->date)) {
Log::debug('Account has opening/credit not on the same day.');
return false;
}
Log::debug('Account has bad opening balance data.');
return true;
}
/**
* @param Account $account
* @return void
@@ -214,35 +105,6 @@ class UpgradeLiabilitiesEight extends Command
Log::debug('No liability credit journal found.');
}
/**
* @param Account $account
* @return void
*/
private function reverseOpeningBalance(Account $account): void
{
$openingBalanceType = TransactionType::whereType(TransactionType::OPENING_BALANCE)->first();
/** @var TransactionJournal $openingJournal */
$openingJournal = TransactionJournal::leftJoin('transactions', 'transactions.transaction_journal_id', '=', 'transaction_journals.id')
->where('transactions.account_id', $account->id)
->where('transaction_journals.transaction_type_id', $openingBalanceType->id)
->first(['transaction_journals.*']);
/** @var Transaction|null $source */
$source = $openingJournal->transactions()->where('amount', '<', 0)->first();
/** @var Transaction|null $dest */
$dest = $openingJournal->transactions()->where('amount', '>', 0)->first();
if ($source && $dest) {
$sourceId = $source->account_id;
$destId = $dest->account_id;
$dest->account_id = $sourceId;
$source->account_id = $destId;
$source->save();
$dest->save();
Log::debug(sprintf('Opening balance transaction journal #%d reversed.', $openingJournal->id));
return;
}
Log::warning('Did not find opening balance.');
}
/**
* @param $account
* @return int
@@ -293,6 +155,54 @@ class UpgradeLiabilitiesEight extends Command
return $count;
}
/**
* @param Account $account
* @return bool
*/
private function hasBadOpening(Account $account): bool
{
$openingBalanceType = TransactionType::whereType(TransactionType::OPENING_BALANCE)->first();
$liabilityType = TransactionType::whereType(TransactionType::LIABILITY_CREDIT)->first();
$openingJournal = TransactionJournal::leftJoin('transactions', 'transactions.transaction_journal_id', '=', 'transaction_journals.id')
->where('transactions.account_id', $account->id)
->where('transaction_journals.transaction_type_id', $openingBalanceType->id)
->first(['transaction_journals.*']);
if (null === $openingJournal) {
Log::debug('Account has no opening balance and can be skipped.');
return false;
}
$liabilityJournal = TransactionJournal::leftJoin('transactions', 'transactions.transaction_journal_id', '=', 'transaction_journals.id')
->where('transactions.account_id', $account->id)
->where('transaction_journals.transaction_type_id', $liabilityType->id)
->first(['transaction_journals.*']);
if (null === $liabilityJournal) {
Log::debug('Account has no liability credit and can be skipped.');
return false;
}
if (!$openingJournal->date->isSameDay($liabilityJournal->date)) {
Log::debug('Account has opening/credit not on the same day.');
return false;
}
Log::debug('Account has bad opening balance data.');
return true;
}
/**
* @return bool
* @throws ContainerExceptionInterface
* @throws NotFoundExceptionInterface
*/
private function isExecuted(): bool
{
$configVar = app('fireflyconfig')->get(self::CONFIG_NAME, false);
if (null !== $configVar) {
return (bool)$configVar->data;
}
return false;
}
/**
*
*/
@@ -300,4 +210,94 @@ class UpgradeLiabilitiesEight extends Command
{
app('fireflyconfig')->set(self::CONFIG_NAME, true);
}
/**
* @param Account $account
* @return void
*/
private function reverseOpeningBalance(Account $account): void
{
$openingBalanceType = TransactionType::whereType(TransactionType::OPENING_BALANCE)->first();
/** @var TransactionJournal $openingJournal */
$openingJournal = TransactionJournal::leftJoin('transactions', 'transactions.transaction_journal_id', '=', 'transaction_journals.id')
->where('transactions.account_id', $account->id)
->where('transaction_journals.transaction_type_id', $openingBalanceType->id)
->first(['transaction_journals.*']);
/** @var Transaction|null $source */
$source = $openingJournal->transactions()->where('amount', '<', 0)->first();
/** @var Transaction|null $dest */
$dest = $openingJournal->transactions()->where('amount', '>', 0)->first();
if ($source && $dest) {
$sourceId = $source->account_id;
$destId = $dest->account_id;
$dest->account_id = $sourceId;
$source->account_id = $destId;
$source->save();
$dest->save();
Log::debug(sprintf('Opening balance transaction journal #%d reversed.', $openingJournal->id));
return;
}
Log::warning('Did not find opening balance.');
}
/**
* @param User $user
*/
private function upgradeForUser(User $user): void
{
Log::debug(sprintf('Upgrading liabilities for user #%d', $user->id));
$accounts = $user->accounts()
->leftJoin('account_types', 'account_types.id', '=', 'accounts.account_type_id')
->whereIn('account_types.type', config('firefly.valid_liabilities'))
->get(['accounts.*']);
/** @var Account $account */
foreach ($accounts as $account) {
$this->upgradeLiability($account);
$service = app(CreditRecalculateService::class);
$service->setAccount($account);
$service->recalculate();
}
}
/**
*
*/
private function upgradeLiabilities(): void
{
Log::debug('Upgrading liabilities.');
$users = User::get();
/** @var User $user */
foreach ($users as $user) {
$this->upgradeForUser($user);
}
}
/**
* @param Account $account
*/
private function upgradeLiability(Account $account): void
{
Log::debug(sprintf('Upgrade liability #%d ("%s")', $account->id, $account->name));
/** @var AccountRepositoryInterface $repository */
$repository = app(AccountRepositoryInterface::class);
$repository->setUser($account->user);
$direction = $repository->getMetaValue($account, 'liability_direction');
if ('debit' === $direction) {
Log::debug('Direction is debit ("I owe this amount"), so no need to upgrade.');
}
if ('credit' === $direction && $this->hasBadOpening($account)) {
$this->deleteCreditTransaction($account);
$this->reverseOpeningBalance($account);
$this->line(sprintf('Corrected opening balance for liability #%d ("%s")', $account->id, $account->name));
}
if ('credit' === $direction) {
$count = $this->deleteTransactions($account);
if ($count > 0) {
$this->line(sprintf('Removed %d old format transaction(s) for liability #%d ("%s")', $count, $account->id, $account->name));
}
}
Log::debug(sprintf('Done upgrading liability #%d ("%s")', $account->id, $account->name));
}
}

View File

@@ -26,7 +26,7 @@ namespace FireflyIII\Console\Commands;
use FireflyIII\Exceptions\FireflyException;
use FireflyIII\Repositories\User\UserRepositoryInterface;
use FireflyIII\User;
use Log;
use Illuminate\Support\Facades\Log;
/**
* Trait VerifiesAccessToken.

View File

@@ -26,7 +26,7 @@ namespace FireflyIII\Console;
use Illuminate\Console\Scheduling\Schedule;
use Illuminate\Foundation\Console\Kernel as ConsoleKernel;
use Log;
use Illuminate\Support\Facades\Log;
/**
* File to make sure commands work.

View File

@@ -31,4 +31,5 @@ enum AutoBudgetType: int
{
case AUTO_BUDGET_RESET = 1;
case AUTO_BUDGET_ROLLOVER = 2;
case AUTO_BUDGET_ADJUSTED = 3;
}

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