Compare commits

..

105 Commits

Author SHA1 Message Date
github-actions
ac8a43bb37 Auto commit for release 'develop' on 2024-07-29 2024-07-29 05:06:54 +02:00
James Cole
2df4b40a28 Add a command to sync up currency information 2024-07-28 15:13:49 +02:00
James Cole
e06736c254 Returns accounts consistently. 2024-07-28 12:23:45 +02:00
James Cole
ec367e94ce Expand account object api 2024-07-28 07:47:54 +02:00
James Cole
1515dea9fa add user group validation 2024-07-28 07:02:04 +02:00
James Cole
adedf9c17d Merge branch 'main' into develop 2024-07-27 15:43:37 +02:00
James Cole
0b52fb84f1 Merge branch 'develop' of github.com:firefly-iii/firefly-iii into develop 2024-07-27 15:42:54 +02:00
James Cole
16e742ae73 Various API updates. 2024-07-27 15:42:43 +02:00
James Cole
1b4471dfae Merge pull request #9090 from firefly-iii/dependabot/composer/develop/symfony/http-client-7.1.3
Bump symfony/http-client from 7.1.2 to 7.1.3
2024-07-27 15:42:12 +02:00
James Cole
ae152ce0a4 Merge pull request #9092 from firefly-iii/dependabot/npm_and_yarn/npm_and_yarn-19f3e7cf70
Bump postcss from 8.4.39 to 8.4.40 in the npm_and_yarn group across 1 directory
2024-07-27 15:41:55 +02:00
James Cole
2aa023f140 Merge pull request #9091 from firefly-iii/dependabot/npm_and_yarn/develop/vue/compiler-sfc-3.4.34
Bump @vue/compiler-sfc from 3.4.33 to 3.4.34
2024-07-27 15:41:47 +02:00
dependabot[bot]
6e2e4c6f08 Bump symfony/http-client from 7.1.2 to 7.1.3
Bumps [symfony/http-client](https://github.com/symfony/http-client) from 7.1.2 to 7.1.3.
- [Release notes](https://github.com/symfony/http-client/releases)
- [Changelog](https://github.com/symfony/http-client/blob/7.1/CHANGELOG.md)
- [Commits](https://github.com/symfony/http-client/compare/v7.1.2...v7.1.3)

---
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>
2024-07-27 13:33:08 +00:00
James Cole
1c8c038735 Merge pull request #9089 from firefly-iii/dependabot/composer/develop/symfony/mailgun-mailer-7.1.3
Bump symfony/mailgun-mailer from 7.1.2 to 7.1.3
2024-07-27 15:32:43 +02:00
James Cole
4d339a6da8 Merge pull request #9088 from firefly-iii/dependabot/npm_and_yarn/develop/postcss-8.4.40
Bump postcss from 8.4.39 to 8.4.40
2024-07-27 15:31:49 +02:00
James Cole
b7edd4407a Merge pull request #9087 from firefly-iii/dependabot/composer/develop/laravel/framework-11.18.1
Bump laravel/framework from 11.17.0 to 11.18.1
2024-07-27 15:31:34 +02:00
dependabot[bot]
a679a1e94a Bump postcss in the npm_and_yarn group across 1 directory
Bumps the npm_and_yarn group with 1 update in the / directory: [postcss](https://github.com/postcss/postcss).


Updates `postcss` from 8.4.39 to 8.4.40
- [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.39...8.4.40)

---
updated-dependencies:
- dependency-name: postcss
  dependency-type: direct:development
  dependency-group: npm_and_yarn
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-07-27 13:30:39 +00:00
James Cole
180451d32f Merge pull request #9086 from firefly-iii/dependabot/github_actions/github/command-1.2.1
Bump github/command from 1.2.0 to 1.2.1
2024-07-27 15:30:04 +02:00
dependabot[bot]
7396f22bca Bump @vue/compiler-sfc from 3.4.33 to 3.4.34
Bumps [@vue/compiler-sfc](https://github.com/vuejs/core/tree/HEAD/packages/compiler-sfc) from 3.4.33 to 3.4.34.
- [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.4.34/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>
2024-07-27 13:28:28 +00:00
dependabot[bot]
058019aa84 Bump symfony/mailgun-mailer from 7.1.2 to 7.1.3
Bumps [symfony/mailgun-mailer](https://github.com/symfony/mailgun-mailer) from 7.1.2 to 7.1.3.
- [Release notes](https://github.com/symfony/mailgun-mailer/releases)
- [Changelog](https://github.com/symfony/mailgun-mailer/blob/7.1/CHANGELOG.md)
- [Commits](https://github.com/symfony/mailgun-mailer/compare/v7.1.2...v7.1.3)

---
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>
2024-07-27 13:28:11 +00:00
dependabot[bot]
695f83d1d8 Bump postcss from 8.4.39 to 8.4.40
Bumps [postcss](https://github.com/postcss/postcss) from 8.4.39 to 8.4.40.
- [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.39...8.4.40)

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

Signed-off-by: dependabot[bot] <support@github.com>
2024-07-27 13:28:06 +00:00
dependabot[bot]
ac4dfb3baf Bump laravel/framework from 11.17.0 to 11.18.1
Bumps [laravel/framework](https://github.com/laravel/framework) from 11.17.0 to 11.18.1.
- [Release notes](https://github.com/laravel/framework/releases)
- [Changelog](https://github.com/laravel/framework/blob/11.x/CHANGELOG.md)
- [Commits](https://github.com/laravel/framework/compare/v11.17.0...v11.18.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>
2024-07-27 13:28:05 +00:00
dependabot[bot]
427001b223 Bump github/command from 1.2.0 to 1.2.1
Bumps [github/command](https://github.com/github/command) from 1.2.0 to 1.2.1.
- [Release notes](https://github.com/github/command/releases)
- [Commits](https://github.com/github/command/compare/v1.2.0...v1.2.1)

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

Signed-off-by: dependabot[bot] <support@github.com>
2024-07-27 13:27:56 +00:00
James Cole
3117d8b30d Update dependabot.yml
Remove labels.

Signed-off-by: James Cole <james@firefly-iii.org>
2024-07-27 15:27:34 +02:00
James Cole
d19dd2a8b2 Clean up some code, clean routes. [skip ci] 2024-07-26 18:50:41 +02:00
James Cole
de3dcc3fc2 Add "not expected this period" message, fix https://github.com/firefly-iii/firefly-iii/issues/9084 2024-07-26 12:53:13 +02:00
James Cole
077f3e095b Various API changes for v2 2024-07-26 12:52:54 +02:00
James Cole
ad3b0bb320 Time to enable the expression engine. 2024-07-26 04:19:49 +02:00
James Cole
8538741341 Fix https://github.com/orgs/firefly-iii/discussions/9080 2024-07-26 03:57:35 +02:00
James Cole
a0aef5d579 Fix https://github.com/firefly-iii/firefly-iii/issues/9078 2024-07-24 14:57:51 +02:00
github-actions
fdd93427aa Auto commit for release 'develop' on 2024-07-22 2024-07-22 05:07:54 +02:00
github-actions
ac3f6557de Auto commit for release 'develop' on 2024-07-20 2024-07-20 10:36:54 +02:00
github-actions
b0a909150c Auto commit for release 'v6.1.19' on 2024-07-20 2024-07-20 06:56:39 +02:00
James Cole
913f163fe4 Update changelog 2024-07-20 06:51:33 +02:00
github-actions
3126b07b33 Auto commit for release 'develop' on 2024-07-15 2024-07-15 06:18:29 +02:00
James Cole
08ca90cf75 Merge pull request #9049 from firefly-iii/dependabot/npm_and_yarn/develop/sass-1.77.8 2024-07-15 06:15:16 +02:00
James Cole
540ac2a277 Merge pull request #9050 from firefly-iii/dependabot/npm_and_yarn/develop/ag-grid-community/core-32.0.2 2024-07-15 06:15:08 +02:00
dependabot[bot]
ed80bed066 Bump sass from 1.77.6 to 1.77.8
Bumps [sass](https://github.com/sass/dart-sass) from 1.77.6 to 1.77.8.
- [Release notes](https://github.com/sass/dart-sass/releases)
- [Changelog](https://github.com/sass/dart-sass/blob/main/CHANGELOG.md)
- [Commits](https://github.com/sass/dart-sass/compare/1.77.6...1.77.8)

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

Signed-off-by: dependabot[bot] <support@github.com>
2024-07-15 04:14:54 +00:00
dependabot[bot]
41d2541c6a Bump @ag-grid-community/core from 32.0.0 to 32.0.2
Bumps [@ag-grid-community/core](https://github.com/ag-grid/ag-grid) from 32.0.0 to 32.0.2.
- [Release notes](https://github.com/ag-grid/ag-grid/releases)
- [Commits](https://github.com/ag-grid/ag-grid/compare/v32.0.0...v32.0.2)

---
updated-dependencies:
- dependency-name: "@ag-grid-community/core"
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-07-15 04:14:44 +00:00
James Cole
5dedf63498 Merge pull request #9051 from firefly-iii/dependabot/npm_and_yarn/develop/laravel-vite-plugin-1.0.5 2024-07-15 06:14:12 +02:00
James Cole
09bc4f41d2 Merge pull request #9052 from firefly-iii/dependabot/npm_and_yarn/develop/ag-grid-community/infinite-row-model-32.0.2 2024-07-15 06:14:05 +02:00
James Cole
cebf0b5c57 Merge pull request #9053 from firefly-iii/dependabot/npm_and_yarn/develop/ag-grid-community/client-side-row-model-32.0.2 2024-07-15 06:13:57 +02:00
James Cole
1632a57e3e Merge pull request #9054 from firefly-iii/dependabot/composer/develop/barryvdh/laravel-ide-helper-3.1.0 2024-07-15 06:13:49 +02:00
James Cole
744c4be7d1 Merge pull request #9055 from firefly-iii/dependabot/composer/develop/phpunit/phpunit-10.5.27 2024-07-15 06:13:41 +02:00
James Cole
bd99ef3eff Merge pull request #9056 from firefly-iii/dependabot/composer/develop/laravel/framework-11.15.0 2024-07-15 06:13:33 +02:00
dependabot[bot]
8a86f13a5d Bump laravel/framework from 11.14.0 to 11.15.0
Bumps [laravel/framework](https://github.com/laravel/framework) from 11.14.0 to 11.15.0.
- [Release notes](https://github.com/laravel/framework/releases)
- [Changelog](https://github.com/laravel/framework/blob/11.x/CHANGELOG.md)
- [Commits](https://github.com/laravel/framework/compare/v11.14.0...v11.15.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>
2024-07-15 03:28:11 +00:00
dependabot[bot]
7418b2f0ee Bump phpunit/phpunit from 10.5.25 to 10.5.27
Bumps [phpunit/phpunit](https://github.com/sebastianbergmann/phpunit) from 10.5.25 to 10.5.27.
- [Release notes](https://github.com/sebastianbergmann/phpunit/releases)
- [Changelog](https://github.com/sebastianbergmann/phpunit/blob/10.5.27/ChangeLog-10.5.md)
- [Commits](https://github.com/sebastianbergmann/phpunit/compare/10.5.25...10.5.27)

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

Signed-off-by: dependabot[bot] <support@github.com>
2024-07-15 03:27:58 +00:00
dependabot[bot]
a0e9de9312 Bump barryvdh/laravel-ide-helper from 3.0.0 to 3.1.0
Bumps [barryvdh/laravel-ide-helper](https://github.com/barryvdh/laravel-ide-helper) from 3.0.0 to 3.1.0.
- [Release notes](https://github.com/barryvdh/laravel-ide-helper/releases)
- [Changelog](https://github.com/barryvdh/laravel-ide-helper/blob/master/CHANGELOG.md)
- [Commits](https://github.com/barryvdh/laravel-ide-helper/compare/v3.0.0...v3.1.0)

---
updated-dependencies:
- dependency-name: barryvdh/laravel-ide-helper
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-07-15 03:27:52 +00:00
dependabot[bot]
7e23a6f5e8 Bump @ag-grid-community/client-side-row-model from 32.0.0 to 32.0.2
Bumps [@ag-grid-community/client-side-row-model](https://github.com/ag-grid/ag-grid) from 32.0.0 to 32.0.2.
- [Release notes](https://github.com/ag-grid/ag-grid/releases)
- [Commits](https://github.com/ag-grid/ag-grid/compare/v32.0.0...v32.0.2)

---
updated-dependencies:
- dependency-name: "@ag-grid-community/client-side-row-model"
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-07-15 03:11:06 +00:00
dependabot[bot]
44589f8744 Bump @ag-grid-community/infinite-row-model from 32.0.0 to 32.0.2
Bumps [@ag-grid-community/infinite-row-model](https://github.com/ag-grid/ag-grid) from 32.0.0 to 32.0.2.
- [Release notes](https://github.com/ag-grid/ag-grid/releases)
- [Commits](https://github.com/ag-grid/ag-grid/compare/v32.0.0...v32.0.2)

---
updated-dependencies:
- dependency-name: "@ag-grid-community/infinite-row-model"
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-07-15 03:10:52 +00:00
dependabot[bot]
d24531030f Bump laravel-vite-plugin from 1.0.4 to 1.0.5
Bumps [laravel-vite-plugin](https://github.com/laravel/vite-plugin) from 1.0.4 to 1.0.5.
- [Release notes](https://github.com/laravel/vite-plugin/releases)
- [Changelog](https://github.com/laravel/vite-plugin/blob/1.x/CHANGELOG.md)
- [Commits](https://github.com/laravel/vite-plugin/compare/v1.0.4...v1.0.5)

---
updated-dependencies:
- dependency-name: laravel-vite-plugin
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-07-15 03:10:36 +00:00
James Cole
25bdab1346 Add some debug info. 2024-07-10 11:55:02 +02:00
James Cole
41af1c863a Fix https://github.com/firefly-iii/firefly-iii/issues/9009 2024-07-10 11:40:41 +02:00
James Cole
76b3b18cfb Merge pull request #9030 from firefly-iii/dependabot/npm_and_yarn/develop/ag-grid-community/client-side-row-model-32.0.0
Bump @ag-grid-community/client-side-row-model from 31.3.2 to 32.0.0
2024-07-08 13:19:40 +02:00
dependabot[bot]
e6fb2958a9 Bump @ag-grid-community/client-side-row-model from 31.3.2 to 32.0.0
Bumps [@ag-grid-community/client-side-row-model](https://github.com/ag-grid/ag-grid) from 31.3.2 to 32.0.0.
- [Release notes](https://github.com/ag-grid/ag-grid/releases)
- [Commits](https://github.com/ag-grid/ag-grid/compare/v31.3.2...v32.0.0)

---
updated-dependencies:
- dependency-name: "@ag-grid-community/client-side-row-model"
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-07-08 11:19:16 +00:00
James Cole
15b75b322f Merge pull request #9029 from firefly-iii/dependabot/npm_and_yarn/develop/ag-grid-community/infinite-row-model-32.0.0
Bump @ag-grid-community/infinite-row-model from 31.3.2 to 32.0.0
2024-07-08 13:18:28 +02:00
dependabot[bot]
86149d1032 Bump @ag-grid-community/infinite-row-model from 31.3.2 to 32.0.0
Bumps [@ag-grid-community/infinite-row-model](https://github.com/ag-grid/ag-grid) from 31.3.2 to 32.0.0.
- [Release notes](https://github.com/ag-grid/ag-grid/releases)
- [Commits](https://github.com/ag-grid/ag-grid/compare/v31.3.2...v32.0.0)

---
updated-dependencies:
- dependency-name: "@ag-grid-community/infinite-row-model"
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-07-08 11:18:02 +00:00
James Cole
ded142cd9e Merge pull request #9031 from firefly-iii/dependabot/npm_and_yarn/develop/ag-grid-community/core-32.0.0
Bump @ag-grid-community/core from 31.3.2 to 32.0.0
2024-07-08 13:17:12 +02:00
dependabot[bot]
7923eb9ec9 Bump @ag-grid-community/core from 31.3.2 to 32.0.0
Bumps [@ag-grid-community/core](https://github.com/ag-grid/ag-grid) from 31.3.2 to 32.0.0.
- [Release notes](https://github.com/ag-grid/ag-grid/releases)
- [Commits](https://github.com/ag-grid/ag-grid/compare/v31.3.2...v32.0.0)

---
updated-dependencies:
- dependency-name: "@ag-grid-community/core"
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-07-08 10:59:19 +00:00
James Cole
132553c108 Merge pull request #9032 from firefly-iii/dependabot/npm_and_yarn/develop/ag-grid-community/styles-32.0.0
Bump @ag-grid-community/styles from 31.3.2 to 32.0.0
2024-07-08 12:58:14 +02:00
github-actions
c2269fc9a4 Auto commit for release 'develop' on 2024-07-08 2024-07-08 05:07:00 +02:00
dependabot[bot]
aed30d1499 Bump @ag-grid-community/styles from 31.3.2 to 32.0.0
Bumps [@ag-grid-community/styles](https://github.com/ag-grid/ag-grid) from 31.3.2 to 32.0.0.
- [Release notes](https://github.com/ag-grid/ag-grid/releases)
- [Commits](https://github.com/ag-grid/ag-grid/compare/v31.3.2...v32.0.0)

---
updated-dependencies:
- dependency-name: "@ag-grid-community/styles"
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-07-08 03:05:13 +00:00
James Cole
84a1a876e1 Fix https://github.com/firefly-iii/firefly-iii/issues/8844 2024-07-06 18:50:33 +02:00
James Cole
dc675707f9 Fix https://github.com/firefly-iii/firefly-iii/issues/9021 2024-07-06 15:50:20 +02:00
James Cole
d5667c7ef6 Merge branch 'develop' of github.com:firefly-iii/firefly-iii into develop
# Conflicts:
#	app/Support/Http/Api/ExchangeRateConverter.php
2024-07-06 15:43:27 +02:00
James Cole
cba1213dd1 Better cache 2024-07-06 15:42:50 +02:00
James Cole
7219c90957 Fix https://github.com/firefly-iii/firefly-iii/issues/9022 2024-07-06 15:42:33 +02:00
github-actions
af13bd991e Auto commit for release 'develop' on 2024-07-01 2024-07-01 05:06:49 +02:00
James Cole
48e548eb52 Better disable thing. 2024-06-30 18:20:52 +02:00
github-actions
1a19e27f0e Auto commit for release 'develop' on 2024-06-24 2024-06-24 05:07:31 +02:00
James Cole
0cbd22426d Fix https://github.com/firefly-iii/firefly-iii/issues/8986 2024-06-20 18:29:00 +02:00
James Cole
d5e52e99e0 Fix #8981 2024-06-18 19:44:22 +02:00
github-actions
f52978e71f Auto commit for release 'v6.1.18' on 2024-06-17 2024-06-17 20:47:03 +02:00
James Cole
3a3358124d Meta data for new release. 2024-06-17 20:43:02 +02:00
github-actions
929808c633 Auto commit for release 'develop' on 2024-06-17 2024-06-17 05:07:03 +02:00
github-actions
a78df574f3 Auto commit for release 'develop' on 2024-06-16 2024-06-16 20:26:04 +02:00
James Cole
875cad16b6 Possible fix for https://github.com/firefly-iii/firefly-iii/issues/8977 2024-06-16 20:21:39 +02:00
James Cole
7bc30192ca Fix https://github.com/firefly-iii/firefly-iii/issues/8978 2024-06-16 19:27:38 +02:00
github-actions
a1a8968e98 Auto commit for release 'develop' on 2024-06-15 2024-06-15 16:16:40 +02:00
James Cole
6abb74a038 Mondays only [skip ci] 2024-06-15 14:26:59 +02:00
github-actions
2d7d05e985 Auto commit for release 'v6.1.17' on 2024-06-15 2024-06-15 13:07:23 +02:00
github-actions
d426e09474 Merge branch 'develop' 2024-06-15 11:04:29 +00:00
James Cole
72d55cb953 Revert workflow change. 2024-06-15 13:02:53 +02:00
James Cole
73ad865581 Add changelog. 2024-06-15 12:56:41 +02:00
James Cole
fefb52beb7 Weekly develop 2024-06-15 12:50:15 +02:00
James Cole
abd503543b Fix regression error in cookie queue 2024-06-15 12:33:56 +02:00
James Cole
e3eb550581 Add currency because why not. 2024-06-15 09:42:09 +02:00
James Cole
46b780758e Fix https://github.com/firefly-iii/firefly-iii/issues/8927 2024-06-15 09:38:19 +02:00
James Cole
b2c3ee9779 Fix https://github.com/firefly-iii/firefly-iii/issues/8954 2024-06-15 09:29:40 +02:00
James Cole
dca899bcee Fix https://github.com/firefly-iii/firefly-iii/issues/8893 2024-06-15 09:25:41 +02:00
James Cole
9667b8a948 Fix https://github.com/firefly-iii/firefly-iii/issues/8958 2024-06-15 09:17:41 +02:00
James Cole
661f225fe7 Add custom routes for Laravel passport. 2024-06-15 09:15:48 +02:00
github-actions
4c6fe0c8de Auto commit for release 'develop' on 2024-06-13 2024-06-13 05:08:55 +02:00
James Cole
78f457950e Merge pull request #8957 from JeroenED/unlimited-nesting-level
Remove nesting level for markdown
2024-06-11 15:17:43 +02:00
Jeroen De Meerleer
d831cc8df2 Update max nesting level for Markdown converter
Increased the max nesting level to 5 for better parsing.
2024-06-11 15:04:15 +02:00
James Cole
7056406afc Merge pull request #8951 from stevewasiura/patch-3
add icon for delete action
2024-06-11 15:03:09 +02:00
github-actions
c85cfcf3e6 Auto commit for release 'develop' on 2024-06-10 2024-06-10 05:09:13 +02:00
Jeroen De Meerleer
db06d06789 Remove unnecessary option from Markdown converter
The 'max_nesting_level' option was removed from the Markdown converter configuration in order to simplify and optimize the code.
2024-06-07 09:05:38 +02:00
github-actions
a28b990cd1 Auto commit for release 'develop' on 2024-06-06 2024-06-06 05:09:02 +02:00
Steve Wasiura
dab4bfa7a6 add icon for delete action
in workflow of reconciling account, sometimes a record needs to be deleted (i.e. in event of a duplicated transaction from an import or error) and this change adds an icon to the delete route

Signed-off-by: Steve Wasiura <steve@waztech.com>
2024-06-03 22:09:22 -04:00
James Cole
6575236f2b Merge pull request #8949 from firefly-iii/dependabot/github_actions/crowdin/github-action-2
Bump crowdin/github-action from 1 to 2
2024-06-03 07:34:04 +02:00
dependabot[bot]
ad582c8806 Bump crowdin/github-action from 1 to 2
Bumps [crowdin/github-action](https://github.com/crowdin/github-action) from 1 to 2.
- [Release notes](https://github.com/crowdin/github-action/releases)
- [Commits](https://github.com/crowdin/github-action/compare/v1...v2)

---
updated-dependencies:
- dependency-name: crowdin/github-action
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-06-03 03:59:42 +00:00
github-actions
452e9cb953 Auto commit for release 'develop' on 2024-06-03 2024-06-03 05:09:54 +02:00
James Cole
a64f137b39 Fix missing locales files. 2024-06-02 07:29:41 +02:00
James Cole
c067d6aab0 Catch division by zero 2024-06-01 05:36:21 +02:00
James Cole
99ed54fce8 Revert steps 2024-05-30 05:45:04 +02:00
115 changed files with 3545 additions and 1868 deletions

View File

@@ -72,30 +72,38 @@
},
{
"name": "composer/pcre",
"version": "3.1.4",
"version": "3.2.0",
"source": {
"type": "git",
"url": "https://github.com/composer/pcre.git",
"reference": "04229f163664973f68f38f6f73d917799168ef24"
"reference": "ea4ab6f9580a4fd221e0418f2c357cdd39102a90"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/composer/pcre/zipball/04229f163664973f68f38f6f73d917799168ef24",
"reference": "04229f163664973f68f38f6f73d917799168ef24",
"url": "https://api.github.com/repos/composer/pcre/zipball/ea4ab6f9580a4fd221e0418f2c357cdd39102a90",
"reference": "ea4ab6f9580a4fd221e0418f2c357cdd39102a90",
"shasum": ""
},
"require": {
"php": "^7.4 || ^8.0"
},
"conflict": {
"phpstan/phpstan": "<1.11.8"
},
"require-dev": {
"phpstan/phpstan": "^1.3",
"phpstan/phpstan": "^1.11.8",
"phpstan/phpstan-strict-rules": "^1.1",
"symfony/phpunit-bridge": "^5"
"phpunit/phpunit": "^8 || ^9"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-main": "3.x-dev"
},
"phpstan": {
"includes": [
"extension.neon"
]
}
},
"autoload": {
@@ -123,7 +131,7 @@
],
"support": {
"issues": "https://github.com/composer/pcre/issues",
"source": "https://github.com/composer/pcre/tree/3.1.4"
"source": "https://github.com/composer/pcre/tree/3.2.0"
},
"funding": [
{
@@ -139,20 +147,20 @@
"type": "tidelift"
}
],
"time": "2024-05-27T13:40:54+00:00"
"time": "2024-07-25T09:36:02+00:00"
},
{
"name": "composer/semver",
"version": "3.4.0",
"version": "3.4.2",
"source": {
"type": "git",
"url": "https://github.com/composer/semver.git",
"reference": "35e8d0af4486141bc745f23a29cc2091eb624a32"
"reference": "c51258e759afdb17f1fd1fe83bc12baaef6309d6"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/composer/semver/zipball/35e8d0af4486141bc745f23a29cc2091eb624a32",
"reference": "35e8d0af4486141bc745f23a29cc2091eb624a32",
"url": "https://api.github.com/repos/composer/semver/zipball/c51258e759afdb17f1fd1fe83bc12baaef6309d6",
"reference": "c51258e759afdb17f1fd1fe83bc12baaef6309d6",
"shasum": ""
},
"require": {
@@ -204,7 +212,7 @@
"support": {
"irc": "ircs://irc.libera.chat:6697/composer",
"issues": "https://github.com/composer/semver/issues",
"source": "https://github.com/composer/semver/tree/3.4.0"
"source": "https://github.com/composer/semver/tree/3.4.2"
},
"funding": [
{
@@ -220,7 +228,7 @@
"type": "tidelift"
}
],
"time": "2023-08-31T09:50:34+00:00"
"time": "2024-07-12T11:35:52+00:00"
},
{
"name": "composer/xdebug-handler",
@@ -398,16 +406,16 @@
},
{
"name": "friendsofphp/php-cs-fixer",
"version": "v3.58.1",
"version": "v3.60.0",
"source": {
"type": "git",
"url": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer.git",
"reference": "04e9424025677a86914b9a4944dbbf4060bb0aff"
"reference": "e595e4e070d17c5d42ed8c4206f630fcc5f401a4"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/PHP-CS-Fixer/PHP-CS-Fixer/zipball/04e9424025677a86914b9a4944dbbf4060bb0aff",
"reference": "04e9424025677a86914b9a4944dbbf4060bb0aff",
"url": "https://api.github.com/repos/PHP-CS-Fixer/PHP-CS-Fixer/zipball/e595e4e070d17c5d42ed8c4206f630fcc5f401a4",
"reference": "e595e4e070d17c5d42ed8c4206f630fcc5f401a4",
"shasum": ""
},
"require": {
@@ -437,16 +445,16 @@
"symfony/stopwatch": "^5.4 || ^6.0 || ^7.0"
},
"require-dev": {
"facile-it/paraunit": "^1.3 || ^2.0",
"infection/infection": "^0.27.11",
"facile-it/paraunit": "^1.3 || ^2.3",
"infection/infection": "^0.29.5",
"justinrainbow/json-schema": "^5.2",
"keradus/cli-executor": "^2.1",
"mikey179/vfsstream": "^1.6.11",
"php-coveralls/php-coveralls": "^2.7",
"php-cs-fixer/accessible-object": "^1.1",
"php-cs-fixer/phpunit-constraint-isidenticalstring": "^1.4",
"php-cs-fixer/phpunit-constraint-xmlmatchesxsd": "^1.4",
"phpunit/phpunit": "^9.6 || ^10.5.5 || ^11.0.2",
"php-cs-fixer/phpunit-constraint-isidenticalstring": "^1.5",
"php-cs-fixer/phpunit-constraint-xmlmatchesxsd": "^1.5",
"phpunit/phpunit": "^9.6.19 || ^10.5.21 || ^11.2",
"symfony/var-dumper": "^5.4 || ^6.0 || ^7.0",
"symfony/yaml": "^5.4 || ^6.0 || ^7.0"
},
@@ -461,7 +469,10 @@
"autoload": {
"psr-4": {
"PhpCsFixer\\": "src/"
}
},
"exclude-from-classmap": [
"src/Fixer/Internal/*"
]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
@@ -486,7 +497,7 @@
],
"support": {
"issues": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/issues",
"source": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/tree/v3.58.1"
"source": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/tree/v3.60.0"
},
"funding": [
{
@@ -494,7 +505,7 @@
"type": "github"
}
],
"time": "2024-05-29T16:39:07+00:00"
"time": "2024-07-25T09:26:51+00:00"
},
{
"name": "psr/container",
@@ -802,28 +813,28 @@
},
{
"name": "react/dns",
"version": "v1.12.0",
"version": "v1.13.0",
"source": {
"type": "git",
"url": "https://github.com/reactphp/dns.git",
"reference": "c134600642fa615b46b41237ef243daa65bb64ec"
"reference": "eb8ae001b5a455665c89c1df97f6fb682f8fb0f5"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/reactphp/dns/zipball/c134600642fa615b46b41237ef243daa65bb64ec",
"reference": "c134600642fa615b46b41237ef243daa65bb64ec",
"url": "https://api.github.com/repos/reactphp/dns/zipball/eb8ae001b5a455665c89c1df97f6fb682f8fb0f5",
"reference": "eb8ae001b5a455665c89c1df97f6fb682f8fb0f5",
"shasum": ""
},
"require": {
"php": ">=5.3.0",
"react/cache": "^1.0 || ^0.6 || ^0.5",
"react/event-loop": "^1.2",
"react/promise": "^3.0 || ^2.7 || ^1.2.1"
"react/promise": "^3.2 || ^2.7 || ^1.2.1"
},
"require-dev": {
"phpunit/phpunit": "^9.6 || ^5.7 || ^4.8.36",
"react/async": "^4 || ^3 || ^2",
"react/promise-timer": "^1.9"
"react/async": "^4.3 || ^3 || ^2",
"react/promise-timer": "^1.11"
},
"type": "library",
"autoload": {
@@ -866,7 +877,7 @@
],
"support": {
"issues": "https://github.com/reactphp/dns/issues",
"source": "https://github.com/reactphp/dns/tree/v1.12.0"
"source": "https://github.com/reactphp/dns/tree/v1.13.0"
},
"funding": [
{
@@ -874,7 +885,7 @@
"type": "open_collective"
}
],
"time": "2023-11-29T12:41:06+00:00"
"time": "2024-06-13T14:18:03+00:00"
},
{
"name": "react/event-loop",
@@ -1023,31 +1034,31 @@
},
{
"name": "react/socket",
"version": "v1.15.0",
"version": "v1.16.0",
"source": {
"type": "git",
"url": "https://github.com/reactphp/socket.git",
"reference": "216d3aec0b87f04a40ca04f481e6af01bdd1d038"
"reference": "23e4ff33ea3e160d2d1f59a0e6050e4b0fb0eac1"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/reactphp/socket/zipball/216d3aec0b87f04a40ca04f481e6af01bdd1d038",
"reference": "216d3aec0b87f04a40ca04f481e6af01bdd1d038",
"url": "https://api.github.com/repos/reactphp/socket/zipball/23e4ff33ea3e160d2d1f59a0e6050e4b0fb0eac1",
"reference": "23e4ff33ea3e160d2d1f59a0e6050e4b0fb0eac1",
"shasum": ""
},
"require": {
"evenement/evenement": "^3.0 || ^2.0 || ^1.0",
"php": ">=5.3.0",
"react/dns": "^1.11",
"react/dns": "^1.13",
"react/event-loop": "^1.2",
"react/promise": "^3 || ^2.6 || ^1.2.1",
"react/stream": "^1.2"
"react/promise": "^3.2 || ^2.6 || ^1.2.1",
"react/stream": "^1.4"
},
"require-dev": {
"phpunit/phpunit": "^9.6 || ^5.7 || ^4.8.36",
"react/async": "^4 || ^3 || ^2",
"react/async": "^4.3 || ^3.3 || ^2",
"react/promise-stream": "^1.4",
"react/promise-timer": "^1.10"
"react/promise-timer": "^1.11"
},
"type": "library",
"autoload": {
@@ -1091,7 +1102,7 @@
],
"support": {
"issues": "https://github.com/reactphp/socket/issues",
"source": "https://github.com/reactphp/socket/tree/v1.15.0"
"source": "https://github.com/reactphp/socket/tree/v1.16.0"
},
"funding": [
{
@@ -1099,20 +1110,20 @@
"type": "open_collective"
}
],
"time": "2023-12-15T11:02:10+00:00"
"time": "2024-07-26T10:38:09+00:00"
},
{
"name": "react/stream",
"version": "v1.3.0",
"version": "v1.4.0",
"source": {
"type": "git",
"url": "https://github.com/reactphp/stream.git",
"reference": "6fbc9672905c7d5a885f2da2fc696f65840f4a66"
"reference": "1e5b0acb8fe55143b5b426817155190eb6f5b18d"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/reactphp/stream/zipball/6fbc9672905c7d5a885f2da2fc696f65840f4a66",
"reference": "6fbc9672905c7d5a885f2da2fc696f65840f4a66",
"url": "https://api.github.com/repos/reactphp/stream/zipball/1e5b0acb8fe55143b5b426817155190eb6f5b18d",
"reference": "1e5b0acb8fe55143b5b426817155190eb6f5b18d",
"shasum": ""
},
"require": {
@@ -1122,7 +1133,7 @@
},
"require-dev": {
"clue/stream-filter": "~1.2",
"phpunit/phpunit": "^9.5 || ^5.7 || ^4.8.35"
"phpunit/phpunit": "^9.6 || ^5.7 || ^4.8.36"
},
"type": "library",
"autoload": {
@@ -1169,7 +1180,7 @@
],
"support": {
"issues": "https://github.com/reactphp/stream/issues",
"source": "https://github.com/reactphp/stream/tree/v1.3.0"
"source": "https://github.com/reactphp/stream/tree/v1.4.0"
},
"funding": [
{
@@ -1177,20 +1188,20 @@
"type": "open_collective"
}
],
"time": "2023-06-16T10:52:11+00:00"
"time": "2024-06-11T12:45:25+00:00"
},
{
"name": "sebastian/diff",
"version": "6.0.1",
"version": "6.0.2",
"source": {
"type": "git",
"url": "https://github.com/sebastianbergmann/diff.git",
"reference": "ab83243ecc233de5655b76f577711de9f842e712"
"reference": "b4ccd857127db5d41a5b676f24b51371d76d8544"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/ab83243ecc233de5655b76f577711de9f842e712",
"reference": "ab83243ecc233de5655b76f577711de9f842e712",
"url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/b4ccd857127db5d41a5b676f24b51371d76d8544",
"reference": "b4ccd857127db5d41a5b676f24b51371d76d8544",
"shasum": ""
},
"require": {
@@ -1236,7 +1247,7 @@
"support": {
"issues": "https://github.com/sebastianbergmann/diff/issues",
"security": "https://github.com/sebastianbergmann/diff/security/policy",
"source": "https://github.com/sebastianbergmann/diff/tree/6.0.1"
"source": "https://github.com/sebastianbergmann/diff/tree/6.0.2"
},
"funding": [
{
@@ -1244,20 +1255,20 @@
"type": "github"
}
],
"time": "2024-03-02T07:30:33+00:00"
"time": "2024-07-03T04:53:05+00:00"
},
{
"name": "symfony/console",
"version": "v7.0.7",
"version": "v7.1.3",
"source": {
"type": "git",
"url": "https://github.com/symfony/console.git",
"reference": "c981e0e9380ce9f146416bde3150c79197ce9986"
"reference": "cb1dcb30ebc7005c29864ee78adb47b5fb7c3cd9"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/console/zipball/c981e0e9380ce9f146416bde3150c79197ce9986",
"reference": "c981e0e9380ce9f146416bde3150c79197ce9986",
"url": "https://api.github.com/repos/symfony/console/zipball/cb1dcb30ebc7005c29864ee78adb47b5fb7c3cd9",
"reference": "cb1dcb30ebc7005c29864ee78adb47b5fb7c3cd9",
"shasum": ""
},
"require": {
@@ -1321,7 +1332,7 @@
"terminal"
],
"support": {
"source": "https://github.com/symfony/console/tree/v7.0.7"
"source": "https://github.com/symfony/console/tree/v7.1.3"
},
"funding": [
{
@@ -1337,7 +1348,7 @@
"type": "tidelift"
}
],
"time": "2024-04-18T09:29:19+00:00"
"time": "2024-07-26T12:41:01+00:00"
},
{
"name": "symfony/deprecation-contracts",
@@ -1408,16 +1419,16 @@
},
{
"name": "symfony/event-dispatcher",
"version": "v7.0.7",
"version": "v7.1.1",
"source": {
"type": "git",
"url": "https://github.com/symfony/event-dispatcher.git",
"reference": "db2a7fab994d67d92356bb39c367db115d9d30f9"
"reference": "9fa7f7a21beb22a39a8f3f28618b29e50d7a55a7"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/db2a7fab994d67d92356bb39c367db115d9d30f9",
"reference": "db2a7fab994d67d92356bb39c367db115d9d30f9",
"url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/9fa7f7a21beb22a39a8f3f28618b29e50d7a55a7",
"reference": "9fa7f7a21beb22a39a8f3f28618b29e50d7a55a7",
"shasum": ""
},
"require": {
@@ -1468,7 +1479,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/v7.0.7"
"source": "https://github.com/symfony/event-dispatcher/tree/v7.1.1"
},
"funding": [
{
@@ -1484,7 +1495,7 @@
"type": "tidelift"
}
],
"time": "2024-04-18T09:29:19+00:00"
"time": "2024-05-31T14:57:53+00:00"
},
{
"name": "symfony/event-dispatcher-contracts",
@@ -1564,22 +1575,24 @@
},
{
"name": "symfony/filesystem",
"version": "v7.0.7",
"version": "v7.1.2",
"source": {
"type": "git",
"url": "https://github.com/symfony/filesystem.git",
"reference": "cc168be6fbdcdf3401f50ae863ee3818ed4338f5"
"reference": "92a91985250c251de9b947a14bb2c9390b1a562c"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/filesystem/zipball/cc168be6fbdcdf3401f50ae863ee3818ed4338f5",
"reference": "cc168be6fbdcdf3401f50ae863ee3818ed4338f5",
"url": "https://api.github.com/repos/symfony/filesystem/zipball/92a91985250c251de9b947a14bb2c9390b1a562c",
"reference": "92a91985250c251de9b947a14bb2c9390b1a562c",
"shasum": ""
},
"require": {
"php": ">=8.2",
"symfony/polyfill-ctype": "~1.8",
"symfony/polyfill-mbstring": "~1.8",
"symfony/polyfill-mbstring": "~1.8"
},
"require-dev": {
"symfony/process": "^6.4|^7.0"
},
"type": "library",
@@ -1608,7 +1621,7 @@
"description": "Provides basic utilities for the filesystem",
"homepage": "https://symfony.com",
"support": {
"source": "https://github.com/symfony/filesystem/tree/v7.0.7"
"source": "https://github.com/symfony/filesystem/tree/v7.1.2"
},
"funding": [
{
@@ -1624,20 +1637,20 @@
"type": "tidelift"
}
],
"time": "2024-04-18T09:29:19+00:00"
"time": "2024-06-28T10:03:55+00:00"
},
{
"name": "symfony/finder",
"version": "v7.0.7",
"version": "v7.1.3",
"source": {
"type": "git",
"url": "https://github.com/symfony/finder.git",
"reference": "4d58f0f4fe95a30d7b538d71197135483560b97c"
"reference": "717c6329886f32dc65e27461f80f2a465412fdca"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/finder/zipball/4d58f0f4fe95a30d7b538d71197135483560b97c",
"reference": "4d58f0f4fe95a30d7b538d71197135483560b97c",
"url": "https://api.github.com/repos/symfony/finder/zipball/717c6329886f32dc65e27461f80f2a465412fdca",
"reference": "717c6329886f32dc65e27461f80f2a465412fdca",
"shasum": ""
},
"require": {
@@ -1672,7 +1685,7 @@
"description": "Finds files and directories via an intuitive fluent interface",
"homepage": "https://symfony.com",
"support": {
"source": "https://github.com/symfony/finder/tree/v7.0.7"
"source": "https://github.com/symfony/finder/tree/v7.1.3"
},
"funding": [
{
@@ -1688,20 +1701,20 @@
"type": "tidelift"
}
],
"time": "2024-04-28T11:44:19+00:00"
"time": "2024-07-24T07:08:44+00:00"
},
{
"name": "symfony/options-resolver",
"version": "v7.0.7",
"version": "v7.1.1",
"source": {
"type": "git",
"url": "https://github.com/symfony/options-resolver.git",
"reference": "23cc173858776ad451e31f053b1c9f47840b2cfa"
"reference": "47aa818121ed3950acd2b58d1d37d08a94f9bf55"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/options-resolver/zipball/23cc173858776ad451e31f053b1c9f47840b2cfa",
"reference": "23cc173858776ad451e31f053b1c9f47840b2cfa",
"url": "https://api.github.com/repos/symfony/options-resolver/zipball/47aa818121ed3950acd2b58d1d37d08a94f9bf55",
"reference": "47aa818121ed3950acd2b58d1d37d08a94f9bf55",
"shasum": ""
},
"require": {
@@ -1739,7 +1752,7 @@
"options"
],
"support": {
"source": "https://github.com/symfony/options-resolver/tree/v7.0.7"
"source": "https://github.com/symfony/options-resolver/tree/v7.1.1"
},
"funding": [
{
@@ -1755,20 +1768,20 @@
"type": "tidelift"
}
],
"time": "2024-04-18T09:29:19+00:00"
"time": "2024-05-31T14:57:53+00:00"
},
{
"name": "symfony/polyfill-ctype",
"version": "v1.29.0",
"version": "v1.30.0",
"source": {
"type": "git",
"url": "https://github.com/symfony/polyfill-ctype.git",
"reference": "ef4d7e442ca910c4764bce785146269b30cb5fc4"
"reference": "0424dff1c58f028c451efff2045f5d92410bd540"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/ef4d7e442ca910c4764bce785146269b30cb5fc4",
"reference": "ef4d7e442ca910c4764bce785146269b30cb5fc4",
"url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/0424dff1c58f028c451efff2045f5d92410bd540",
"reference": "0424dff1c58f028c451efff2045f5d92410bd540",
"shasum": ""
},
"require": {
@@ -1818,7 +1831,7 @@
"portable"
],
"support": {
"source": "https://github.com/symfony/polyfill-ctype/tree/v1.29.0"
"source": "https://github.com/symfony/polyfill-ctype/tree/v1.30.0"
},
"funding": [
{
@@ -1834,20 +1847,20 @@
"type": "tidelift"
}
],
"time": "2024-01-29T20:11:03+00:00"
"time": "2024-05-31T15:07:36+00:00"
},
{
"name": "symfony/polyfill-intl-grapheme",
"version": "v1.29.0",
"version": "v1.30.0",
"source": {
"type": "git",
"url": "https://github.com/symfony/polyfill-intl-grapheme.git",
"reference": "32a9da87d7b3245e09ac426c83d334ae9f06f80f"
"reference": "64647a7c30b2283f5d49b874d84a18fc22054b7a"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/polyfill-intl-grapheme/zipball/32a9da87d7b3245e09ac426c83d334ae9f06f80f",
"reference": "32a9da87d7b3245e09ac426c83d334ae9f06f80f",
"url": "https://api.github.com/repos/symfony/polyfill-intl-grapheme/zipball/64647a7c30b2283f5d49b874d84a18fc22054b7a",
"reference": "64647a7c30b2283f5d49b874d84a18fc22054b7a",
"shasum": ""
},
"require": {
@@ -1896,7 +1909,7 @@
"shim"
],
"support": {
"source": "https://github.com/symfony/polyfill-intl-grapheme/tree/v1.29.0"
"source": "https://github.com/symfony/polyfill-intl-grapheme/tree/v1.30.0"
},
"funding": [
{
@@ -1912,20 +1925,20 @@
"type": "tidelift"
}
],
"time": "2024-01-29T20:11:03+00:00"
"time": "2024-05-31T15:07:36+00:00"
},
{
"name": "symfony/polyfill-intl-normalizer",
"version": "v1.29.0",
"version": "v1.30.0",
"source": {
"type": "git",
"url": "https://github.com/symfony/polyfill-intl-normalizer.git",
"reference": "bc45c394692b948b4d383a08d7753968bed9a83d"
"reference": "a95281b0be0d9ab48050ebd988b967875cdb9fdb"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/polyfill-intl-normalizer/zipball/bc45c394692b948b4d383a08d7753968bed9a83d",
"reference": "bc45c394692b948b4d383a08d7753968bed9a83d",
"url": "https://api.github.com/repos/symfony/polyfill-intl-normalizer/zipball/a95281b0be0d9ab48050ebd988b967875cdb9fdb",
"reference": "a95281b0be0d9ab48050ebd988b967875cdb9fdb",
"shasum": ""
},
"require": {
@@ -1977,7 +1990,7 @@
"shim"
],
"support": {
"source": "https://github.com/symfony/polyfill-intl-normalizer/tree/v1.29.0"
"source": "https://github.com/symfony/polyfill-intl-normalizer/tree/v1.30.0"
},
"funding": [
{
@@ -1993,20 +2006,20 @@
"type": "tidelift"
}
],
"time": "2024-01-29T20:11:03+00:00"
"time": "2024-05-31T15:07:36+00:00"
},
{
"name": "symfony/polyfill-mbstring",
"version": "v1.29.0",
"version": "v1.30.0",
"source": {
"type": "git",
"url": "https://github.com/symfony/polyfill-mbstring.git",
"reference": "9773676c8a1bb1f8d4340a62efe641cf76eda7ec"
"reference": "fd22ab50000ef01661e2a31d850ebaa297f8e03c"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/9773676c8a1bb1f8d4340a62efe641cf76eda7ec",
"reference": "9773676c8a1bb1f8d4340a62efe641cf76eda7ec",
"url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/fd22ab50000ef01661e2a31d850ebaa297f8e03c",
"reference": "fd22ab50000ef01661e2a31d850ebaa297f8e03c",
"shasum": ""
},
"require": {
@@ -2057,7 +2070,7 @@
"shim"
],
"support": {
"source": "https://github.com/symfony/polyfill-mbstring/tree/v1.29.0"
"source": "https://github.com/symfony/polyfill-mbstring/tree/v1.30.0"
},
"funding": [
{
@@ -2073,20 +2086,20 @@
"type": "tidelift"
}
],
"time": "2024-01-29T20:11:03+00:00"
"time": "2024-06-19T12:30:46+00:00"
},
{
"name": "symfony/polyfill-php80",
"version": "v1.29.0",
"version": "v1.30.0",
"source": {
"type": "git",
"url": "https://github.com/symfony/polyfill-php80.git",
"reference": "87b68208d5c1188808dd7839ee1e6c8ec3b02f1b"
"reference": "77fa7995ac1b21ab60769b7323d600a991a90433"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/polyfill-php80/zipball/87b68208d5c1188808dd7839ee1e6c8ec3b02f1b",
"reference": "87b68208d5c1188808dd7839ee1e6c8ec3b02f1b",
"url": "https://api.github.com/repos/symfony/polyfill-php80/zipball/77fa7995ac1b21ab60769b7323d600a991a90433",
"reference": "77fa7995ac1b21ab60769b7323d600a991a90433",
"shasum": ""
},
"require": {
@@ -2137,7 +2150,7 @@
"shim"
],
"support": {
"source": "https://github.com/symfony/polyfill-php80/tree/v1.29.0"
"source": "https://github.com/symfony/polyfill-php80/tree/v1.30.0"
},
"funding": [
{
@@ -2153,20 +2166,20 @@
"type": "tidelift"
}
],
"time": "2024-01-29T20:11:03+00:00"
"time": "2024-05-31T15:07:36+00:00"
},
{
"name": "symfony/polyfill-php81",
"version": "v1.29.0",
"version": "v1.30.0",
"source": {
"type": "git",
"url": "https://github.com/symfony/polyfill-php81.git",
"reference": "c565ad1e63f30e7477fc40738343c62b40bc672d"
"reference": "3fb075789fb91f9ad9af537c4012d523085bd5af"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/polyfill-php81/zipball/c565ad1e63f30e7477fc40738343c62b40bc672d",
"reference": "c565ad1e63f30e7477fc40738343c62b40bc672d",
"url": "https://api.github.com/repos/symfony/polyfill-php81/zipball/3fb075789fb91f9ad9af537c4012d523085bd5af",
"reference": "3fb075789fb91f9ad9af537c4012d523085bd5af",
"shasum": ""
},
"require": {
@@ -2213,7 +2226,7 @@
"shim"
],
"support": {
"source": "https://github.com/symfony/polyfill-php81/tree/v1.29.0"
"source": "https://github.com/symfony/polyfill-php81/tree/v1.30.0"
},
"funding": [
{
@@ -2229,20 +2242,20 @@
"type": "tidelift"
}
],
"time": "2024-01-29T20:11:03+00:00"
"time": "2024-06-19T12:30:46+00:00"
},
{
"name": "symfony/process",
"version": "v7.0.7",
"version": "v7.1.3",
"source": {
"type": "git",
"url": "https://github.com/symfony/process.git",
"reference": "3839e56b94dd1dbd13235d27504e66baf23faba0"
"reference": "7f2f542c668ad6c313dc4a5e9c3321f733197eca"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/process/zipball/3839e56b94dd1dbd13235d27504e66baf23faba0",
"reference": "3839e56b94dd1dbd13235d27504e66baf23faba0",
"url": "https://api.github.com/repos/symfony/process/zipball/7f2f542c668ad6c313dc4a5e9c3321f733197eca",
"reference": "7f2f542c668ad6c313dc4a5e9c3321f733197eca",
"shasum": ""
},
"require": {
@@ -2274,7 +2287,7 @@
"description": "Executes commands in sub-processes",
"homepage": "https://symfony.com",
"support": {
"source": "https://github.com/symfony/process/tree/v7.0.7"
"source": "https://github.com/symfony/process/tree/v7.1.3"
},
"funding": [
{
@@ -2290,7 +2303,7 @@
"type": "tidelift"
}
],
"time": "2024-04-18T09:29:19+00:00"
"time": "2024-07-26T12:44:47+00:00"
},
{
"name": "symfony/service-contracts",
@@ -2377,16 +2390,16 @@
},
{
"name": "symfony/stopwatch",
"version": "v7.0.7",
"version": "v7.1.1",
"source": {
"type": "git",
"url": "https://github.com/symfony/stopwatch.git",
"reference": "41a7a24aa1dc82adf46a06bc292d1923acfe6b84"
"reference": "5b75bb1ac2ba1b9d05c47fc4b3046a625377d23d"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/stopwatch/zipball/41a7a24aa1dc82adf46a06bc292d1923acfe6b84",
"reference": "41a7a24aa1dc82adf46a06bc292d1923acfe6b84",
"url": "https://api.github.com/repos/symfony/stopwatch/zipball/5b75bb1ac2ba1b9d05c47fc4b3046a625377d23d",
"reference": "5b75bb1ac2ba1b9d05c47fc4b3046a625377d23d",
"shasum": ""
},
"require": {
@@ -2419,7 +2432,7 @@
"description": "Provides a way to profile code",
"homepage": "https://symfony.com",
"support": {
"source": "https://github.com/symfony/stopwatch/tree/v7.0.7"
"source": "https://github.com/symfony/stopwatch/tree/v7.1.1"
},
"funding": [
{
@@ -2435,20 +2448,20 @@
"type": "tidelift"
}
],
"time": "2024-04-18T09:29:19+00:00"
"time": "2024-05-31T14:57:53+00:00"
},
{
"name": "symfony/string",
"version": "v7.0.7",
"version": "v7.1.3",
"source": {
"type": "git",
"url": "https://github.com/symfony/string.git",
"reference": "e405b5424dc2528e02e31ba26b83a79fd4eb8f63"
"reference": "ea272a882be7f20cad58d5d78c215001617b7f07"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/string/zipball/e405b5424dc2528e02e31ba26b83a79fd4eb8f63",
"reference": "e405b5424dc2528e02e31ba26b83a79fd4eb8f63",
"url": "https://api.github.com/repos/symfony/string/zipball/ea272a882be7f20cad58d5d78c215001617b7f07",
"reference": "ea272a882be7f20cad58d5d78c215001617b7f07",
"shasum": ""
},
"require": {
@@ -2462,6 +2475,7 @@
"symfony/translation-contracts": "<2.5"
},
"require-dev": {
"symfony/emoji": "^7.1",
"symfony/error-handler": "^6.4|^7.0",
"symfony/http-client": "^6.4|^7.0",
"symfony/intl": "^6.4|^7.0",
@@ -2505,7 +2519,7 @@
"utf8"
],
"support": {
"source": "https://github.com/symfony/string/tree/v7.0.7"
"source": "https://github.com/symfony/string/tree/v7.1.3"
},
"funding": [
{
@@ -2521,7 +2535,7 @@
"type": "tidelift"
}
],
"time": "2024-04-18T09:29:19+00:00"
"time": "2024-07-22T10:25:37+00:00"
}
],
"packages-dev": [],

View File

@@ -4,6 +4,7 @@ updates:
# Check for updates to GitHub Actions every week
- package-ecosystem: "github-actions"
directory: "/"
labels: []
schedule:
interval: "weekly"
@@ -11,6 +12,7 @@ updates:
- package-ecosystem: "composer"
directory: "/" # Location of package manifests
target-branch: develop
labels: []
versioning-strategy: increase
schedule:
interval: "weekly"
@@ -18,6 +20,7 @@ updates:
# yarn / JS updates
- package-ecosystem: "npm"
directory: "/"
labels: []
target-branch: develop
versioning-strategy: increase
schedule:

View File

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

View File

@@ -8,7 +8,7 @@ on:
required: true
default: 'develop'
schedule:
- cron: '0 3 * * MON,THU'
- cron: '0 3 * * MON'
jobs:
build:
@@ -39,7 +39,7 @@ jobs:
php-version: '8.3'
extensions: mbstring, intl, zip, bcmath
- name: crowdin action
uses: crowdin/github-action@v1
uses: crowdin/github-action@v2
with:
upload_sources: true
download_translations: true
@@ -125,9 +125,9 @@ jobs:
- name: Build JS
run: |
npm install
npm update
npm run prod --workspace=v1
npm run build --workspace=v2
npm update
- name: Run CI
run: |
rm -rf vendor composer.lock

View File

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

View File

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

View File

@@ -0,0 +1,110 @@
<?php
/*
* AccountController.php
* Copyright (c) 2024 james@firefly-iii.org.
*
* This file is part of Firefly III (https://github.com/firefly-iii).
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see https://www.gnu.org/licenses/.
*/
declare(strict_types=1);
namespace FireflyIII\Api\V2\Controllers\JsonApi;
use FireflyIII\Http\Controllers\Controller;
use FireflyIII\JsonApi\V2\Accounts\AccountCollectionQuery;
use FireflyIII\JsonApi\V2\Accounts\AccountSchema;
use FireflyIII\JsonApi\V2\Accounts\AccountSingleQuery;
use FireflyIII\Models\Account;
use Illuminate\Contracts\Support\Responsable;
use Illuminate\Http\Response;
use Illuminate\Support\Facades\Log;
use LaravelJsonApi\Core\Responses\DataResponse;
use LaravelJsonApi\Laravel\Http\Controllers\Actions;
/**
* Class AccountController
*
* This class handles api/v2 requests for accounts.
* Most stuff is default stuff.
*/
class AccountController extends Controller
{
use Actions\AttachRelationship;
use Actions\Destroy;
use Actions\DetachRelationship;
// use Actions\FetchMany;
// use Actions\FetchOne;
use Actions\FetchRelated;
use Actions\FetchRelationship;
use Actions\Store;
use Actions\Update;
use Actions\UpdateRelationship;
/**
* Fetch zero to many JSON API resources.
*
* @return Responsable|Response
*/
public function index(AccountSchema $schema, AccountCollectionQuery $request)
{
Log::debug(__METHOD__);
$models = $schema
->repository()
->queryAll()
->withRequest($request)
->get()
;
// do something custom...
return new DataResponse($models);
}
/**
* Fetch zero to one JSON API resource by id.
*
* @return Responsable|Response
*/
public function show(AccountSchema $schema, AccountSingleQuery $request, Account $account)
{
$model = $schema
->repository()
->queryOne($account)
->withRequest($request)
->first()
;
// do something custom...
return new DataResponse($model);
}
// public function readAccountBalances(AnonymousQuery $query, AccountBalanceSchema $schema, Account $account): Responsable
// {
// $schema = JsonApi::server()->schemas()->schemaFor('account-balances');
//
// $models = $schema
// ->repository()
// ->queryAll()
// ->withRequest($query)
// ->withAccount($account)
// ->get()
// ;
//
// return DataResponse::make($models);
// }
}

View File

@@ -44,55 +44,8 @@ class FixUnevenAmount extends Command
*/
public function handle(): int
{
$count = 0;
$journals = \DB::table('transactions')
->groupBy('transaction_journal_id')
->whereNull('deleted_at')
->get(['transaction_journal_id', \DB::raw('SUM(amount) AS the_sum')])
;
/** @var \stdClass $entry */
foreach ($journals as $entry) {
$sum = (string)$entry->the_sum;
if (!is_numeric($sum)
|| '' === $sum // @phpstan-ignore-line
|| str_contains($sum, 'e')
|| str_contains($sum, ',')) {
$message = sprintf(
'Journal #%d has an invalid sum ("%s"). No sure what to do.',
$entry->transaction_journal_id,
$entry->the_sum
);
$this->friendlyWarning($message);
app('log')->warning($message);
++$count;
continue;
}
$res = -1;
try {
$res = bccomp($sum, '0');
} catch (\ValueError $e) {
$this->friendlyError(sprintf('Could not bccomp("%s", "0").', $sum));
Log::error($e->getMessage());
Log::error($e->getTraceAsString());
}
if (0 !== $res) {
$message = sprintf(
'Sum of journal #%d is %s instead of zero.',
$entry->transaction_journal_id,
$entry->the_sum
);
$this->friendlyWarning($message);
app('log')->warning($message);
$this->fixJournal($entry->transaction_journal_id);
++$count;
}
}
if (0 === $count) {
$this->friendlyPositive('Database amount integrity is OK');
}
$this->fixUnevenAmounts();
$this->matchCurrencies();
return 0;
}
@@ -149,4 +102,76 @@ class FixUnevenAmount extends Command
$message = sprintf('Corrected amount in transaction journal #%d', $param);
$this->friendlyInfo($message);
}
private function fixUnevenAmounts(): void
{
$count = 0;
$journals = \DB::table('transactions')
->groupBy('transaction_journal_id')
->whereNull('deleted_at')
->get(['transaction_journal_id', \DB::raw('SUM(amount) AS the_sum')])
;
/** @var \stdClass $entry */
foreach ($journals as $entry) {
$sum = (string) $entry->the_sum;
if (!is_numeric($sum)
|| '' === $sum // @phpstan-ignore-line
|| str_contains($sum, 'e')
|| str_contains($sum, ',')) {
$message = sprintf(
'Journal #%d has an invalid sum ("%s"). No sure what to do.',
$entry->transaction_journal_id,
$entry->the_sum
);
$this->friendlyWarning($message);
app('log')->warning($message);
++$count;
continue;
}
$res = -1;
try {
$res = bccomp($sum, '0');
} catch (\ValueError $e) {
$this->friendlyError(sprintf('Could not bccomp("%s", "0").', $sum));
Log::error($e->getMessage());
Log::error($e->getTraceAsString());
}
if (0 !== $res) {
$message = sprintf(
'Sum of journal #%d is %s instead of zero.',
$entry->transaction_journal_id,
$entry->the_sum
);
$this->friendlyWarning($message);
app('log')->warning($message);
$this->fixJournal($entry->transaction_journal_id);
++$count;
}
}
if (0 === $count) {
$this->friendlyPositive('Database amount integrity is OK');
}
}
private function matchCurrencies(): void
{
$journals = TransactionJournal::leftJoin('transactions', 'transaction_journals.id', 'transactions.transaction_journal_id')
->where('transactions.transaction_currency_id', '!=', \DB::raw('transaction_journals.transaction_currency_id'))
->get(['transaction_journals.*'])
;
if (0 === $journals->count()) {
$this->friendlyPositive('Journal currency integrity is OK');
return;
}
/** @var TransactionJournal $journal */
foreach ($journals as $journal) {
Transaction::where('transaction_journal_id', $journal->id)->update(['transaction_currency_id' => $journal->transaction_currency_id]);
}
$this->friendlyPositive(sprintf('Fixed %d journal(s) with mismatched currencies.', $journals->count()));
}
}

View File

@@ -115,7 +115,7 @@ class UpdateGroupInformation extends Command
return;
}
if (0 !== $result) {
$this->friendlyPositive(sprintf('User #%d: Moved %d %s objects to the correct group.', $user->id, $result, str_replace('FireflyIII\\Models\\', '', $className)));
$this->friendlyPositive(sprintf('User #%d: Moved %d %s objects to the correct group.', $user->id, $result, str_replace('FireflyIII\Models\\', '', $className)));
}
}
}

View File

@@ -111,7 +111,7 @@ class ForceDecimalSize extends Command
{
// switch stuff based on database connection:
$this->operator = 'REGEXP';
$this->regularExpression = '\'\\\\.[\\\\d]{%d}[1-9]+\'';
$this->regularExpression = '\'\\\.[\\\d]{%d}[1-9]+\'';
$this->cast = 'CHAR';
if ('pgsql' === config('database.default')) {
$this->operator = 'SIMILAR TO';
@@ -119,7 +119,7 @@ class ForceDecimalSize extends Command
$this->cast = 'TEXT';
}
if ('sqlite' === config('database.default')) {
$this->regularExpression = '"\\.[\d]{%d}[1-9]+"';
$this->regularExpression = '"\.[\d]{%d}[1-9]+"';
}
}

View File

@@ -43,7 +43,7 @@ class AttachmentFactory
public function create(array $data): ?Attachment
{
// append if necessary.
$model = !str_contains($data['attachable_type'], 'FireflyIII') ? sprintf('FireflyIII\\Models\\%s', $data['attachable_type'])
$model = !str_contains($data['attachable_type'], 'FireflyIII') ? sprintf('FireflyIII\Models\%s', $data['attachable_type'])
: $data['attachable_type'];
// get journal instead of transaction.

View File

@@ -717,7 +717,7 @@ trait MetaCollection
$this->joinMetaDataTables();
$this->query->where('journal_meta.name', '=', 'internal_reference');
$this->query->where('journal_meta.data', 'LIKE', sprintf('%%%s%%', $internalReference));
$this->query->where('journal_meta.data', '=', $internalReference);
return $this;
}

View File

@@ -1,43 +0,0 @@
<?php
declare(strict_types=1);
namespace FireflyIII\Http\Controllers\Api\V3\Controllers;
use FireflyIII\Http\Controllers\Controller;
use FireflyIII\JsonApi\V3\AccountBalances\AccountBalanceSchema;
use FireflyIII\Models\Account;
use Illuminate\Contracts\Support\Responsable;
use LaravelJsonApi\Core\Facades\JsonApi;
use LaravelJsonApi\Core\Responses\DataResponse;
use LaravelJsonApi\Laravel\Http\Controllers\Actions;
use LaravelJsonApi\Laravel\Http\Requests\AnonymousQuery;
class AccountController extends Controller
{
use Actions\AttachRelationship;
use Actions\Destroy;
use Actions\DetachRelationship;
use Actions\FetchMany;
use Actions\FetchOne;
use Actions\FetchRelated;
use Actions\FetchRelationship;
use Actions\Store;
use Actions\Update;
use Actions\UpdateRelationship;
public function readAccountBalances(AnonymousQuery $query, AccountBalanceSchema $schema, Account $account): Responsable
{
$schema = JsonApi::server()->schemas()->schemaFor('account-balances');
$models = $schema
->repository()
->queryAll()
->withRequest($query)
->withAccount($account)
->get()
;
return DataResponse::make($models);
}
}

View File

@@ -121,7 +121,7 @@ class LoginController extends Controller
// Copied directly from AuthenticatesUsers, but with logging added:
// If the login attempt was unsuccessful we will increment the number of attempts
// to login and redirect the user back to the login form. Of course, when this
// to log in and redirect the user back to the login form. Of course, when this
// user surpasses their maximum number of attempts they will get locked out.
$this->incrementLoginAttempts($request);
Log::channel('audit')->warning(sprintf('Login failed. Attempt for user "%s" failed.', $request->get($this->username())));
@@ -233,7 +233,7 @@ class LoginController extends Controller
$storeInCookie = config('google2fa.store_in_cookie', false);
if (false !== $storeInCookie) {
$cookieName = config('google2fa.cookie_name', 'google2fa_token');
request()->cookies->set($cookieName, 'invalid');
\Cookie::queue(\Cookie::make($cookieName, 'invalid-'.time()));
}
$usernameField = $this->username();

View File

@@ -185,7 +185,7 @@ class BudgetLimitController extends Controller
$array['amount_formatted'] = app('amount')->formatAnything($limit->transactionCurrency, $limit['amount']);
$array['days_left'] = (string)$this->activeDaysLeft($start, $end);
// left per day:
$array['left_per_day'] = bcdiv(bcadd($array['spent'], $array['amount']), $array['days_left']);
$array['left_per_day'] = 0 === bccomp('0', $array['days_left']) ? bcadd($array['spent'], $array['amount']) : bcdiv(bcadd($array['spent'], $array['amount']), $array['days_left']);
// left per day formatted.
$array['left_per_day_formatted'] = app('amount')->formatAnything($limit->transactionCurrency, $array['left_per_day']);

View File

@@ -81,6 +81,8 @@ class ReconcileController extends Controller
if ($end->lt($start)) {
[$start, $end] = [$end, $start];
}
$end->endOfDay();
$start->startOfDay();
$route = route('accounts.reconcile.submit', [$account->id, $start->format('Ymd'), $end->format('Ymd')]);
$selectedIds = $request->get('journals') ?? [];

View File

@@ -81,7 +81,12 @@ class RecurrenceController extends Controller
$skip = $skip < 0 || $skip > 31 ? 0 : $skip;
$weekend = $weekend < 1 || $weekend > 4 ? 1 : $weekend;
if (null === $start || null === $end || null === $firstDate || null === $endDate) {
if (null === $endDate) {
// safety catch:
$endDate = now()->addYear();
}
if (null === $start || null === $end || null === $firstDate) {
return response()->json();
}

View File

@@ -120,7 +120,7 @@ class PreferencesController extends Controller
// list of locales also has "equal" which makes it equal to whatever the language is.
try {
$locales = json_decode((string)file_get_contents(resource_path(sprintf('lang/%s/locales.json', $language))), true, 512, JSON_THROW_ON_ERROR);
$locales = json_decode((string)file_get_contents(resource_path(sprintf('locales/%s/locales.json', $language))), true, 512, JSON_THROW_ON_ERROR);
} catch (\JsonException $e) {
app('log')->error($e->getMessage());
$locales = [];

View File

@@ -84,6 +84,7 @@ class ShowController extends Controller
$transformer->setParameters(new ParameterBag());
$array = $transformer->transform($recurrence);
$groups = $this->recurring->getTransactions($recurrence);
$today = today(config('app.timezone'));
$array['repeat_until'] = null !== $array['repeat_until'] ? new Carbon($array['repeat_until']) : null;

View File

@@ -23,7 +23,6 @@ declare(strict_types=1);
namespace FireflyIII\Http\Controllers\Transaction;
use Exception;
use FireflyIII\Events\UpdatedTransactionGroup;
use FireflyIII\Exceptions\FireflyException;
use FireflyIII\Http\Controllers\Controller;
@@ -65,7 +64,7 @@ class ConvertController extends Controller
$this->middleware(
function ($request, $next) {
$this->accountRepository = app(AccountRepositoryInterface::class);
app('view')->share('title', (string)trans('firefly.transactions'));
app('view')->share('title', (string) trans('firefly.transactions'));
app('view')->share('mainTitleIcon', 'fa-exchange');
return $next($request);
@@ -95,7 +94,7 @@ class ConvertController extends Controller
$groupTitle = $group->title ?? $first->description;
$groupArray = $transformer->transformObject($group);
$subTitle = (string)trans('firefly.convert_to_'.$destinationType->type, ['description' => $groupTitle]);
$subTitle = (string) trans('firefly.convert_to_'.$destinationType->type, ['description' => $groupTitle]);
$subTitleIcon = 'fa-exchange';
// get a list of asset accounts and liabilities and stuff, in various combinations:
@@ -111,7 +110,7 @@ class ConvertController extends Controller
if ($sourceType->type === $destinationType->type) { // cannot convert to its own type.
app('log')->debug('This is already a transaction of the expected type..');
session()->flash('info', (string)trans('firefly.convert_is_already_type_'.$destinationType->type));
session()->flash('info', (string) trans('firefly.convert_is_already_type_'.$destinationType->type));
return redirect(route('transactions.show', [$group->id]));
}
@@ -147,7 +146,7 @@ class ConvertController extends Controller
// group accounts:
/** @var Account $account */
foreach ($accountList as $account) {
$role = (string)$this->accountRepository->getMetaValue($account, 'account_role');
$role = (string) $this->accountRepository->getMetaValue($account, 'account_role');
$name = $account->name;
if ('' === $role) {
$role = 'no_account_type';
@@ -165,7 +164,7 @@ class ConvertController extends Controller
$role = 'revenue_account';
}
$key = (string)trans('firefly.opt_group_'.$role);
$key = (string) trans('firefly.opt_group_'.$role);
$grouped[$key][$account->id] = $name;
}
@@ -184,7 +183,7 @@ class ConvertController extends Controller
// group accounts:
/** @var Account $account */
foreach ($accountList as $account) {
$role = (string)$this->accountRepository->getMetaValue($account, 'account_role');
$role = (string) $this->accountRepository->getMetaValue($account, 'account_role');
$name = $account->name;
if ('' === $role) {
$role = 'no_account_type';
@@ -202,7 +201,7 @@ class ConvertController extends Controller
$role = 'expense_account';
}
$key = (string)trans('firefly.opt_group_'.$role);
$key = (string) trans('firefly.opt_group_'.$role);
$grouped[$key][$account->id] = $name;
}
@@ -225,7 +224,7 @@ class ConvertController extends Controller
$balance = app('steam')->balance($account, today());
$currency = $this->accountRepository->getAccountCurrency($account) ?? $defaultCurrency;
$role = 'l_'.$account->accountType->type;
$key = (string)trans('firefly.opt_group_'.$role);
$key = (string) trans('firefly.opt_group_'.$role);
$grouped[$key][$account->id] = $account->name.' ('.app('amount')->formatAnything($currency, $balance, false).')';
}
@@ -247,12 +246,12 @@ class ConvertController extends Controller
foreach ($accountList as $account) {
$balance = app('steam')->balance($account, today());
$currency = $this->accountRepository->getAccountCurrency($account) ?? $defaultCurrency;
$role = (string)$this->accountRepository->getMetaValue($account, 'account_role');
$role = (string) $this->accountRepository->getMetaValue($account, 'account_role');
if ('' === $role) {
$role = 'no_account_type';
}
$key = (string)trans('firefly.opt_group_'.$role);
$key = (string) trans('firefly.opt_group_'.$role);
$grouped[$key][$account->id] = $account->name.' ('.app('amount')->formatAnything($currency, $balance, false).')';
}
@@ -285,7 +284,7 @@ class ConvertController extends Controller
// correct transfers:
$group->refresh();
session()->flash('success', (string)trans('firefly.converted_to_'.$destinationType->type));
session()->flash('success', (string) trans('firefly.converted_to_'.$destinationType->type));
event(new UpdatedTransactionGroup($group, true, true));
return redirect(route('transactions.show', [$group->id]));
@@ -306,11 +305,11 @@ class ConvertController extends Controller
$destinationId = $data['destination_id'][$journal->id] ?? null;
$destinationName = $data['destination_name'][$journal->id] ?? null;
// double check its not an empty string.
$sourceId = '' === $sourceId || null === $sourceId ? null : (int)$sourceId;
$sourceName = '' === $sourceName ? null : (string)$sourceName;
$destinationId = '' === $destinationId || null === $destinationId ? null : (int)$destinationId;
$destinationName = '' === $destinationName ? null : (string)$destinationName;
// double check it's not an empty string.
$sourceId = '' === $sourceId || null === $sourceId ? null : (int) $sourceId;
$sourceName = '' === $sourceName ? null : (string) $sourceName;
$destinationId = '' === $destinationId || null === $destinationId ? null : (int) $destinationId;
$destinationName = '' === $destinationName ? null : (string) $destinationName;
$validSource = $validator->validateSource(['id' => $sourceId, 'name' => $sourceName]);
$validDestination = $validator->validateDestination(['id' => $destinationId, 'name' => $destinationName]);
@@ -331,6 +330,19 @@ class ConvertController extends Controller
'type' => $transactionType->type,
];
// also set the currency to the currency of the source account, in case you're converting a deposit into a transfer.
if (TransactionType::TRANSFER === $transactionType->type && TransactionType::DEPOSIT === $journal->transactionType->type) {
$source = $this->accountRepository->find((int) $sourceId);
$sourceCurrency = $this->accountRepository->getAccountCurrency($source);
$dest = $this->accountRepository->find((int) $destinationId);
$destCurrency = $this->accountRepository->getAccountCurrency($dest);
if (null !== $sourceCurrency && null !== $destCurrency && $sourceCurrency->code !== $destCurrency->code) {
$update['currency_id'] = $sourceCurrency->id;
$update['foreign_currency_id'] = $destCurrency->id;
$update['foreign_amount'] = '1'; // not the best solution but at this point the amount is hard to get.
}
}
/** @var JournalUpdateService $service */
$service = app(JournalUpdateService::class);
$service->setTransactionJournal($journal);

View File

@@ -27,6 +27,7 @@ use Carbon\Carbon;
use FireflyIII\Repositories\Journal\JournalRepositoryInterface;
use FireflyIII\Support\Http\Controllers\RequestInformation;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Log;
/**
* Class SessionFilter.
@@ -63,6 +64,7 @@ class Range
{
// ignore preference. set the range to be the current month:
if (!app('session')->has('start') && !app('session')->has('end')) {
Log::debug('setRange: Session has no start or end.');
$viewRange = app('preferences')->get('viewRange', '1M')->data;
if (is_array($viewRange)) {
$viewRange = '1M';
@@ -76,6 +78,8 @@ class Range
app('session')->put('end', $end);
}
if (!app('session')->has('first')) {
Log::debug('setRange: Session has no "first".');
/** @var JournalRepositoryInterface $repository */
$repository = app(JournalRepositoryInterface::class);
$journal = $repository->firstNull();

View File

@@ -28,4 +28,9 @@ use Illuminate\Foundation\Http\Middleware\VerifyCsrfToken as Middleware;
/**
* Class VerifyCsrfToken.
*/
class VerifyCsrfToken extends Middleware {}
class VerifyCsrfToken extends Middleware
{
protected $except = [
'oauth/token',
];
}

View File

@@ -361,11 +361,17 @@ class CreateRecurringTransactions implements ShouldQueue
// create transaction array and send to factory.
$groupTitle = null;
$count = $recurrence->recurrenceTransactions->count();
if ($count > 1) {
// #8844, if there is one recurrence transaction, use the first title as the title.
if (1 === $count) {
/** @var RecurrenceTransaction $first */
$first = $recurrence->recurrenceTransactions()->first();
$groupTitle = $first->description;
}
// #8844, if there are more, use the recurrence transaction itself.
if ($count > 1) {
$groupTitle = $recurrence->title;
}
if (0 === $count) {
app('log')->error('No transactions to be created in this recurrence. Cannot continue.');
@@ -411,12 +417,12 @@ class CreateRecurringTransactions implements ShouldQueue
/** @var RecurrenceTransaction $transaction */
foreach ($transactions as $index => $transaction) {
$single = [
'type' => null === $first->transactionType ? strtolower($recurrence->transactionType->type) : strtolower($first->transactionType->type),
'type' => null === $transaction?->transactionType?->type ? strtolower($recurrence->transactionType->type) : strtolower($transaction->transactionType->type),
'date' => $date,
'user' => $recurrence->user_id,
'currency_id' => $transaction->transaction_currency_id,
'currency_code' => null,
'description' => $first->description,
'description' => $transaction->description,
'amount' => $transaction->amount,
'budget_id' => $this->repository->getBudget($transaction),
'budget_name' => null,

View File

@@ -21,7 +21,7 @@
declare(strict_types=1);
namespace FireflyIII\JsonApi\V3\AccountBalances;
namespace FireflyIII\JsonApi\V2\AccountBalances;
use FireflyIII\Entities\AccountBalance;
use LaravelJsonApi\Contracts\Store\QueriesAll;

View File

@@ -2,7 +2,7 @@
declare(strict_types=1);
namespace FireflyIII\JsonApi\V3\AccountBalances;
namespace FireflyIII\JsonApi\V2\AccountBalances;
use Illuminate\Http\Request;
use LaravelJsonApi\Core\Resources\JsonApiResource;

View File

@@ -2,7 +2,7 @@
declare(strict_types=1);
namespace FireflyIII\JsonApi\V3\AccountBalances;
namespace FireflyIII\JsonApi\V2\AccountBalances;
use FireflyIII\Entities\AccountBalance;
use LaravelJsonApi\Core\Schema\Schema;

View File

@@ -21,7 +21,7 @@
declare(strict_types=1);
namespace FireflyIII\JsonApi\V3\AccountBalances\Capabilities;
namespace FireflyIII\JsonApi\V2\AccountBalances\Capabilities;
use FireflyIII\Entities\AccountBalance;
use FireflyIII\Models\Account;

View File

@@ -0,0 +1,60 @@
<?php
declare(strict_types=1);
namespace FireflyIII\JsonApi\V2\Accounts;
use FireflyIII\Models\Account;
use FireflyIII\Rules\IsAllowedGroupAction;
use Illuminate\Support\Facades\Log;
use LaravelJsonApi\Laravel\Http\Requests\ResourceQuery;
use LaravelJsonApi\Validation\Rule as JsonApiRule;
class AccountCollectionQuery extends ResourceQuery
{
/**
* Get the validation rules that apply to the request query parameters.
*/
public function rules(): array
{
Log::debug(__METHOD__);
return [
'fields' => [
'nullable',
'array',
JsonApiRule::fieldSets(),
],
'user_group_id' => [
'nullable',
'integer',
new IsAllowedGroupAction(Account::class, request()->method()),
],
'filter' => [
'nullable',
'array',
JsonApiRule::filter(),
],
'include' => [
'nullable',
'string',
JsonApiRule::includePaths(),
],
'page' => [
'nullable',
'array',
JsonApiRule::page(),
],
'sort' => [
'nullable',
'string',
JsonApiRule::sort(),
],
'withCount' => [
'nullable',
'string',
JsonApiRule::countable(),
],
];
}
}

View File

@@ -0,0 +1,98 @@
<?php
/*
* AccountRepository.php
* Copyright (c) 2024 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\JsonApi\V2\Accounts;
use FireflyIII\Models\Account;
use FireflyIII\Support\JsonApi\Concerns\UsergroupAware;
use FireflyIII\Support\JsonApi\Enrichments\AccountEnrichment;
use Illuminate\Support\Facades\Log;
use LaravelJsonApi\Contracts\Store\QueriesAll;
use LaravelJsonApi\NonEloquent\AbstractRepository;
use LaravelJsonApi\NonEloquent\Capabilities\CrudRelations;
use LaravelJsonApi\NonEloquent\Concerns\HasCrudCapability;
use LaravelJsonApi\NonEloquent\Concerns\HasRelationsCapability;
/**
* Class AccountRepository
*
* The repository collects a single or many (account) objects from the database and returns them to the
* account resource. The account resource links all account properties to the JSON properties.
*
* For the queryAll thing, a separate query is constructed that does the actual querying of the database.
* This is necessary because the user can't just query all accounts (it would return other user's data)
* and because we also need to collect all kinds of metadata, like the currency and user info.
*/
class AccountRepository extends AbstractRepository implements QueriesAll
{
use HasCrudCapability;
use HasRelationsCapability;
use UsergroupAware;
/**
* SiteRepository constructor.
*/
public function __construct() {}
public function exists(string $resourceId): bool
{
Log::debug(__METHOD__);
return null !== Account::find((int) $resourceId);
}
public function find(string $resourceId): ?object
{
Log::debug(__METHOD__);
// throw new \RuntimeException('trace me');
$account = Account::find((int) $resourceId);
if (null === $account) {
return null;
}
// enrich the collected data
$enrichment = new AccountEnrichment();
return $enrichment->enrichSingle($account);
}
public function queryAll(): Capabilities\AccountQuery
{
Log::debug(__METHOD__);
return Capabilities\AccountQuery::make()
->withUserGroup($this->userGroup)
->withServer($this->server)
->withSchema($this->schema)
;
}
protected function crud(): Capabilities\CrudAccount
{
return Capabilities\CrudAccount::make();
}
protected function relations(): CrudRelations
{
return Capabilities\CrudAccountRelations::make();
}
}

View File

@@ -0,0 +1,74 @@
<?php
declare(strict_types=1);
namespace FireflyIII\JsonApi\V2\Accounts;
use FireflyIII\Models\Account;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Log;
use LaravelJsonApi\Core\Resources\JsonApiResource;
/**
* @property Account $resource
*/
class AccountResource extends JsonApiResource
{
/**
* Get the resource id.
*/
public function id(): string
{
Log::debug(__METHOD__);
return (string) $this->resource->id;
}
/**
* Get the resource's attributes.
*
* @param null|Request $request
*/
public function attributes($request): iterable
{
Log::debug(__METHOD__);
return [
'created_at' => $this->resource->created_at,
'updated_at' => $this->resource->updated_at,
'name' => $this->resource->name,
'active' => $this->resource->active,
'order' => $this->resource->order,
'type' => $this->resource->account_type_string,
'account_role' => $this->resource->account_role,
'account_number' => '' === $this->resource->account_number ? null : $this->resource->account_number,
// currency
'currency_id' => $this->resource->currency_id,
'currency_name' => $this->resource->currency_name,
'currency_code' => $this->resource->currency_code,
'currency_symbol' => $this->resource->currency_symbol,
'currency_decimal_places' => $this->resource->currency_decimal_places,
// liability things
'liability_direction' => $this->resource->liability_direction,
'interest' => $this->resource->interest,
'interest_period' => $this->resource->interest_period,
'current_debt' => $this->resource->current_debt,
'last_activity' => $this->resource->last_activity,
];
}
/**
* Get the resource's relationships.
*
* @param null|Request $request
*/
public function relationships($request): iterable
{
return [
$this->relation('user')->withData($this->resource->user),
];
}
}

View File

@@ -2,7 +2,7 @@
declare(strict_types=1);
namespace FireflyIII\JsonApi\V3\Accounts;
namespace FireflyIII\JsonApi\V2\Accounts;
use FireflyIII\Models\Account;
use Illuminate\Http\Request;
@@ -10,8 +10,13 @@ use LaravelJsonApi\Core\Resources\JsonApiResource;
/**
* @property Account $resource
*
* This class collects the resources attributes, the account in this case.
* Generally speaking, each property here is directly related to a property on the account object itself.
* However, many properties are collected from other sources, like the user or the currency.
* As a result, the account repository is where it's at, which is where the collection takes place and is optimised.
*/
class AccountResource extends JsonApiResource
class AccountResourceOld extends JsonApiResource
{
/**
* Get the resource's attributes.
@@ -20,32 +25,23 @@ class AccountResource extends JsonApiResource
*/
public function attributes($request): iterable
{
// fields removed here have been migrated.
return [
'created_at' => $this->resource->created_at,
'updated_at' => $this->resource->updated_at,
'name' => $this->resource->name,
'iban' => '' === $this->resource->iban ? null : $this->resource->iban,
'active' => $this->resource->active,
'last_activity' => $this->resource->last_activity,
'type' => $this->resource->type,
'account_role' => $this->resource->account_role,
'created_at' => $this->resource->created_at,
'updated_at' => $this->resource->updated_at,
'name' => $this->resource->name,
// 'virtual_balance' => $this->resource->virtual_balance,
// 'native_balance' => $this->resource->native_balance,
// 'user' => $this->resource->user_array,
// 'balances' => []
//
// currency
// 'currency_id' => $this->resource->currency_id,
// 'currency_code' => $this->resource->currency_code,
// 'currency_symbol' => $this->resource->currency_symbol,
// 'currency_decimal_places' => $this->resource->currency_decimal_places,
// balance (in currency, on date)
// 'current_balance' => $this->resource->current_balance,
// 'current_balance' => app('steam')->bcround(app('steam')->balance($account, $date), $decimalPlaces),
// 'current_balance_date' => $date->toAtomString(),
// 'notes' => $this->repository->getNoteText($account),
// 'monthly_payment_date' => $monthlyPaymentDate,
// 'credit_card_type' => $creditCardType,
@@ -65,11 +61,6 @@ class AccountResource extends JsonApiResource
// 'order' => $order,
// 'currency_id' => (string) $currency->id,
// 'currency_code' => $currency->code,
// 'currency_symbol' => $currency->symbol,
// 'currency_decimal_places' => $currency->decimal_places,
//
// 'native_currency_id' => (string) $this->default->id,
// 'native_currency_code' => $this->default->code,
// 'native_currency_symbol' => $this->default->symbol,
@@ -86,15 +77,9 @@ class AccountResource extends JsonApiResource
// 'balance_difference_start' => $diffStart,
// 'balance_difference_end' => $diffEnd,
//
// // more meta
// 'last_activity' => array_key_exists($id, $this->lastActivity) ? $this->lastActivity[$id]->toAtomString() : null,
//
// // liability stuff
// 'liability_type' => $liabilityType,
// 'liability_direction' => $liabilityDirection,
// 'interest' => $interest,
// 'interest_period' => $interestPeriod,
// 'current_debt' => $currentDebt,
//
// // object group
// 'object_group_id' => null !== $objectGroupId ? (string) $objectGroupId : null,
@@ -123,7 +108,8 @@ class AccountResource extends JsonApiResource
{
return [
$this->relation('user')->withData($this->resource->user),
$this->relation('account_balances')->withData($this->resource->balances),
$this->relation('currency')->withData($this->resource->transactionCurrency),
// $this->relation('account_balances')->withData($this->resource->balances),
];
}
}

View File

@@ -0,0 +1,88 @@
<?php
declare(strict_types=1);
namespace FireflyIII\JsonApi\V2\Accounts;
use FireflyIII\Models\Account;
use FireflyIII\Support\JsonApi\Concerns\UsergroupAware;
use Illuminate\Support\Facades\Log;
use LaravelJsonApi\Core\Schema\Schema;
use LaravelJsonApi\Eloquent\Fields\Relations\HasOne;
use LaravelJsonApi\NonEloquent\Fields\Attribute;
use LaravelJsonApi\NonEloquent\Fields\ID;
use LaravelJsonApi\NonEloquent\Filters\Filter;
class AccountSchema extends Schema
{
use UsergroupAware;
/**
* The model the schema corresponds to.
*/
public static string $model = Account::class;
/**
* Get the resource fields.
*/
public function fields(): array
{
Log::debug(__METHOD__);
return [
ID::make(),
Attribute::make('created_at'),
Attribute::make('updated_at'),
// basic info and meta data
Attribute::make('name'),
Attribute::make('active'),
Attribute::make('order'),
Attribute::make('type'),
Attribute::make('account_role'),
Attribute::make('account_number'),
// currency
Attribute::make('currency_id'),
Attribute::make('currency_name'),
Attribute::make('currency_code'),
Attribute::make('currency_symbol'),
Attribute::make('currency_decimal_places'),
// liability things
Attribute::make('liability_direction'),
Attribute::make('interest'),
Attribute::make('interest_period'),
Attribute::make('current_debt'),
// dynamic data
Attribute::make('last_activity'),
HasOne::make('user')->readOnly(),
];
}
/**
* Get the resource filters.
*/
public function filters(): array
{
Log::debug(__METHOD__);
return [
Filter::make('id'),
];
}
public function repository(): AccountRepository
{
Log::debug(__METHOD__);
$this->setUserGroup($this->server->getUsergroup());
return AccountRepository::make()
->withServer($this->server)
->withSchema($this)
->withUserGroup($this->userGroup)
;
}
}

View File

@@ -2,7 +2,7 @@
declare(strict_types=1);
namespace FireflyIII\JsonApi\V3\Accounts;
namespace FireflyIII\JsonApi\V2\Accounts;
use FireflyIII\Models\Account;
use LaravelJsonApi\Eloquent\Contracts\Paginator;
@@ -17,7 +17,14 @@ use LaravelJsonApi\Eloquent\Filters\WhereIdIn;
use LaravelJsonApi\Eloquent\Pagination\PagePagination;
use LaravelJsonApi\Eloquent\Schema;
class AccountSchema extends Schema
/**
* Class AccountSchema
*
* This is the schema of all fields that an account exposes to the world.
* Fields do not have to have a relation to the actual model.
* Fields mentioned here still need to be filled in by the AccountResource.
*/
class AccountSchemaOld extends Schema
{
/**
* The model the schema corresponds to.
@@ -34,18 +41,19 @@ class AccountSchema extends Schema
DateTime::make('created_at')->sortable()->readOnly(),
DateTime::make('updated_at')->sortable()->readOnly(),
Str::make('name')->sortable(),
Str::make('account_type'),
Str::make('virtual_balance'),
Str::make('iban'),
Boolean::make('active'),
Number::make('order'),
HasOne::make('user'),
HasMany::make('account_balances'),
// Str::make('account_type'),
// Str::make('virtual_balance'),
// Str::make('iban'),
// Boolean::make('active'),
// Number::make('order'),
HasOne::make('user')->readOnly(),
// HasMany::make('account_balances'),
];
}
/**
* Get the resource filters.
* Filters mentioned here can be used to filter the results.
* TODO write down exactly how this works.
*/
public function filters(): array
{

View File

@@ -0,0 +1,45 @@
<?php
declare(strict_types=1);
namespace FireflyIII\JsonApi\V2\Accounts;
use Illuminate\Support\Facades\Log;
use LaravelJsonApi\Laravel\Http\Requests\ResourceQuery;
use LaravelJsonApi\Validation\Rule as JsonApiRule;
class AccountSingleQuery extends ResourceQuery
{
/**
* Get the validation rules that apply to the request query parameters.
*/
public function rules(): array
{
Log::debug(__METHOD__);
return [
'fields' => [
'nullable',
'array',
JsonApiRule::fieldSets(),
],
'filter' => [
'nullable',
'array',
JsonApiRule::filter()->forget('id'),
],
'include' => [
'nullable',
'string',
JsonApiRule::includePaths(),
],
'page' => JsonApiRule::notSupported(),
'sort' => JsonApiRule::notSupported(),
'withCount' => [
'nullable',
'string',
JsonApiRule::countable(),
],
];
}
}

View File

@@ -21,7 +21,7 @@
declare(strict_types=1);
namespace FireflyIII\JsonApi\V3\Accounts\Capabilities;
namespace FireflyIII\JsonApi\V2\Accounts\Capabilities;
use FireflyIII\Support\JsonApi\Concerns\UsergroupAware;
use FireflyIII\Support\JsonApi\Enrichments\AccountEnrichment;
@@ -29,6 +29,7 @@ use FireflyIII\Support\JsonApi\ExpandsQuery;
use FireflyIII\Support\JsonApi\FiltersPagination;
use FireflyIII\Support\JsonApi\SortsCollection;
use FireflyIII\Support\JsonApi\ValidateSortParameters;
use Illuminate\Support\Facades\Log;
use LaravelJsonApi\Contracts\Store\HasPagination;
use LaravelJsonApi\NonEloquent\Capabilities\QueryAll;
use LaravelJsonApi\NonEloquent\Concerns\PaginatesEnumerables;
@@ -43,31 +44,45 @@ class AccountQuery extends QueryAll implements HasPagination
use ValidateSortParameters;
#[\Override]
/**
* This method returns all accounts, given a bunch of filters and sort fields, together with pagination.
*/
public function get(): iterable
{
Log::debug(__METHOD__);
// collect filters
$filters = $this->queryParameters->filter();
// collect sort options
$sort = $this->queryParameters->sortFields();
// collect pagination based on the page
$pagination = $this->filtersPagination($this->queryParameters->page());
$needsAll = $this->validateParams('account', $sort);
// check if we need all accounts, regardless of pagination
// This is necessary when the user wants to sort on specific params.
$needsAll = $this->needsFullDataset('account', $sort);
// start the query
$query = $this->userGroup->accounts();
// add pagination to the query, limiting the results.
if (!$needsAll) {
$query = $this->addPagination($query, $pagination);
}
// add sort and filter parameters to the query.
$query = $this->addSortParams($query, $sort);
$query = $this->addFilterParams('account', $query, $filters);
// collect the result.
$collection = $query->get(['accounts.*']);
// enrich data
// enrich the collected data
$enrichment = new AccountEnrichment();
$collection = $enrichment->enrich($collection);
// add filters after the query
// TODO add filters after the query, if there are filters that cannot be applied to the database but only
// to the enriched results.
// add sort after the query
// sort the data after the query, and return it right away.
return $this->sortCollection($collection, $sort);
// var_dump($filters->value('name'));
// exit;
}
}

View File

@@ -1,6 +1,6 @@
<?php
/*
* AccountRepository.php
* CrudAccount.php
* Copyright (c) 2024 james@firefly-iii.org.
*
* This file is part of Firefly III (https://github.com/firefly-iii).
@@ -21,33 +21,22 @@
declare(strict_types=1);
namespace FireflyIII\JsonApi\V3\Accounts;
namespace FireflyIII\JsonApi\V2\Accounts\Capabilities;
use FireflyIII\Models\Account;
use FireflyIII\Support\JsonApi\Concerns\UsergroupAware;
use LaravelJsonApi\Contracts\Store\QueriesAll;
use LaravelJsonApi\NonEloquent\AbstractRepository;
use FireflyIII\Support\JsonApi\Enrichments\AccountEnrichment;
use LaravelJsonApi\NonEloquent\Capabilities\CrudResource;
class AccountRepository extends AbstractRepository implements QueriesAll
class CrudAccount extends CrudResource
{
use UsergroupAware;
/**
* SiteRepository constructor.
* Read the supplied site.
*/
public function __construct() {}
public function find(string $resourceId): ?object
public function read(Account $account): ?Account
{
return Account::find((int) $resourceId);
}
// enrich the collected data
$enrichment = new AccountEnrichment();
public function queryAll(): Capabilities\AccountQuery
{
return Capabilities\AccountQuery::make()
->withUserGroup($this->userGroup)
->withServer($this->server)
->withSchema($this->schema)
;
return $enrichment->enrichSingle($account);
}
}

View File

@@ -0,0 +1,28 @@
<?php
/*
* CrudAccountRelations.php
* Copyright (c) 2024 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\JsonApi\V2\Accounts\Capabilities;
use LaravelJsonApi\NonEloquent\Capabilities\CrudRelations;
class CrudAccountRelations extends CrudRelations {}

53
app/JsonApi/V2/Server.php Normal file
View File

@@ -0,0 +1,53 @@
<?php
declare(strict_types=1);
namespace FireflyIII\JsonApi\V2;
use FireflyIII\JsonApi\V2\Accounts\AccountSchema;
use FireflyIII\JsonApi\V2\Users\UserSchema;
use FireflyIII\Support\JsonApi\Concerns\UsergroupAware;
use FireflyIII\Support\JsonApi\Concerns\UserGroupDetectable;
use Illuminate\Support\Facades\Log;
use LaravelJsonApi\Core\Server\Server as BaseServer;
/**
* Class Server
*
* This class serves as a generic class for the v2 API "server".
*/
class Server extends BaseServer
{
use UsergroupAware;
use UserGroupDetectable;
/**
* The base URI namespace for this server.
*/
protected string $baseUri = '/api/v2';
/**
* Bootstrap the server when it is handling an HTTP request.
*/
public function serving(): void
{
Log::debug(__METHOD__);
// at this point the user may not actually have access to this user group.
$res = $this->detectUserGroup();
$this->setUserGroup($res);
}
/**
* Get the server's list of schemas.
*/
protected function allSchemas(): array
{
Log::debug(__METHOD__);
return [
AccountSchema::class,
UserSchema::class,
// AccountBalanceSchema::class,
];
}
}

View File

@@ -2,7 +2,7 @@
declare(strict_types=1);
namespace FireflyIII\JsonApi\V3\Users;
namespace FireflyIII\JsonApi\V2\Users;
use FireflyIII\Models\User;
use Illuminate\Http\Request;

View File

@@ -2,7 +2,7 @@
declare(strict_types=1);
namespace FireflyIII\JsonApi\V3\Users;
namespace FireflyIII\JsonApi\V2\Users;
use FireflyIII\User;
use LaravelJsonApi\Eloquent\Contracts\Paginator;

View File

@@ -1,38 +0,0 @@
<?php
declare(strict_types=1);
namespace FireflyIII\JsonApi\V3;
use FireflyIII\JsonApi\V3\Accounts\AccountSchema;
use FireflyIII\JsonApi\V3\AccountBalances\AccountBalanceSchema;
use FireflyIII\JsonApi\V3\Users\UserSchema;
use LaravelJsonApi\Core\Server\Server as BaseServer;
class Server extends BaseServer
{
/**
* The base URI namespace for this server.
*/
protected string $baseUri = '/api/v3';
/**
* Bootstrap the server when it is handling an HTTP request.
*/
public function serving(): void
{
// no-op
}
/**
* Get the server's list of schemas.
*/
protected function allSchemas(): array
{
return [
AccountSchema::class,
UserSchema::class,
AccountBalanceSchema::class,
];
}
}

View File

@@ -28,6 +28,7 @@ use Eloquent;
use FireflyIII\Support\Models\ReturnsIntegerIdTrait;
use FireflyIII\Support\Models\ReturnsIntegerUserIdTrait;
use FireflyIII\User;
use GeneaLabs\LaravelModelCaching\Traits\Cachable;
use Illuminate\Database\Eloquent\Builder as EloquentBuilder;
use Illuminate\Database\Eloquent\Casts\Attribute;
use Illuminate\Database\Eloquent\Collection;
@@ -50,6 +51,7 @@ use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
* @property null|Carbon $deleted_at
* @property int $user_id
* @property int $account_type_id
* @property string $account_type_string
* @property string $name
* @property string $virtual_balance
* @property null|string $iban
@@ -74,6 +76,7 @@ use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
* @property Collection|Transaction[] $transactions
* @property null|int $transactions_count
* @property User $user
* @property string $last_activity
*
* @method static EloquentBuilder|Account accountTypeIn($types)
* @method static EloquentBuilder|Account newModelQuery()
@@ -116,6 +119,7 @@ use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
*/
class Account extends Model
{
use Cachable;
use HasFactory;
use ReturnsIntegerIdTrait;
use ReturnsIntegerUserIdTrait;
@@ -144,7 +148,7 @@ class Account extends Model
public static function routeBinder(string $value): self
{
if (auth()->check()) {
$accountId = (int)$value;
$accountId = (int) $value;
/** @var User $user */
$user = auth()->user();
@@ -246,7 +250,7 @@ class Account extends Model
public function setVirtualBalanceAttribute(mixed $value): void
{
$value = (string)$value;
$value = (string) $value;
if ('' === $value) {
$value = null;
}
@@ -266,7 +270,7 @@ class Account extends Model
protected function accountId(): Attribute
{
return Attribute::make(
get: static fn ($value) => (int)$value,
get: static fn ($value) => (int) $value,
);
}
@@ -276,21 +280,21 @@ class Account extends Model
protected function accountTypeId(): Attribute
{
return Attribute::make(
get: static fn ($value) => (int)$value,
get: static fn ($value) => (int) $value,
);
}
protected function iban(): Attribute
{
return Attribute::make(
get: static fn ($value) => null === $value ? null : trim(str_replace(' ', '', (string)$value)),
get: static fn ($value) => null === $value ? null : trim(str_replace(' ', '', (string) $value)),
);
}
protected function order(): Attribute
{
return Attribute::make(
get: static fn ($value) => (int)$value,
get: static fn ($value) => (int) $value,
);
}
@@ -300,7 +304,7 @@ class Account extends Model
protected function virtualBalance(): Attribute
{
return Attribute::make(
get: static fn ($value) => (string)$value,
get: static fn ($value) => (string) $value,
);
}
}

View File

@@ -26,6 +26,7 @@ namespace FireflyIII\Models;
use Carbon\Carbon;
use Eloquent;
use FireflyIII\Support\Models\ReturnsIntegerIdTrait;
use GeneaLabs\LaravelModelCaching\Traits\Cachable;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Casts\Attribute;
use Illuminate\Database\Eloquent\Collection;
@@ -93,6 +94,7 @@ use Illuminate\Database\Eloquent\SoftDeletes;
*/
class Transaction extends Model
{
use Cachable;
use HasFactory;
use ReturnsIntegerIdTrait;
use SoftDeletes;

View File

@@ -28,6 +28,7 @@ use Illuminate\Support\Facades\Response;
use Illuminate\Support\Facades\Route;
use Illuminate\Support\Facades\Schema;
use Illuminate\Support\ServiceProvider;
use Laravel\Passport\Passport;
/**
* Class AppServiceProvider
@@ -87,6 +88,7 @@ class AppServiceProvider extends ServiceProvider
*/
public function register(): void
{
Passport::ignoreRoutes();
// Passport::ignoreMigrations();
// Sanctum::ignoreMigrations();
}

View File

@@ -554,6 +554,12 @@ class AccountRepository implements AccountRepositoryInterface
++$index;
}
}
// reset the rest to zero.
$all = [AccountType::DEFAULT, AccountType::ASSET, AccountType::LOAN, AccountType::DEBT, AccountType::CREDITCARD, AccountType::MORTGAGE];
$this->user->accounts()->leftJoin('account_types', 'account_types.id', '=', 'accounts.account_type_id')
->whereNotIn('account_types.type', $all)
->update(['order' => 0])
;
}
public function searchAccount(string $query, array $types, int $limit): Collection

View File

@@ -146,7 +146,7 @@ class AttachmentRepository implements AttachmentRepositoryInterface
// should be validated already:
if (array_key_exists('attachable_type', $data) && array_key_exists('attachable_id', $data)) {
$attachment->attachable_id = (int)$data['attachable_id'];
$attachment->attachable_type = sprintf('FireflyIII\\Models\\%s', $data['attachable_type']);
$attachment->attachable_type = sprintf('FireflyIII\Models\%s', $data['attachable_type']);
}
$attachment->save();

View File

@@ -408,10 +408,16 @@ class RecurringRepository implements RecurringRepositoryInterface
private function filterMaxDate(?Carbon $max, array $occurrences): array
{
if (null === $max) {
return $occurrences;
}
$filtered = [];
if (null === $max) {
foreach ($occurrences as $date) {
if ($date->gt(today())) {
$filtered[] = $date;
}
}
return $filtered;
}
foreach ($occurrences as $date) {
if ($date->lte($max) && $date->gt(today())) {
$filtered[] = $date;

View File

@@ -150,7 +150,6 @@ class RuleRepository implements RuleRepositoryInterface
$params[] = sprintf('%s:true', OperatorQuerySearch::getRootOperator($trigger->trigger_type));
}
if (true === $needsContext) {
var_dump('x');
$params[] = sprintf('%s:"%s"', OperatorQuerySearch::getRootOperator($trigger->trigger_type), $trigger->trigger_value);
}
}

View File

@@ -241,6 +241,12 @@ class AccountRepository implements AccountRepositoryInterface
++$index;
}
}
// reset the rest to zero.
$all = [AccountType::DEFAULT, AccountType::ASSET, AccountType::LOAN, AccountType::DEBT, AccountType::CREDITCARD, AccountType::MORTGAGE];
$this->user->accounts()->leftJoin('account_types', 'account_types.id', '=', 'accounts.account_type_id')
->whereNotIn('account_types.type', $all)
->update(['order' => 0])
;
}
public function getAccountsByType(array $types, ?array $sort = [], ?array $filters = []): Collection

View File

@@ -0,0 +1,130 @@
<?php
/*
* IsAllowedGroupAction.php
* Copyright (c) 2024 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\Rules;
use FireflyIII\Enums\UserRoleEnum;
use FireflyIII\Models\Account;
use FireflyIII\Repositories\UserGroup\UserGroupRepositoryInterface;
use FireflyIII\User;
use Illuminate\Contracts\Validation\ValidationRule;
use Illuminate\Auth\Access\AuthorizationException;
use Illuminate\Support\Facades\Log;
class IsAllowedGroupAction implements ValidationRule
{
private string $className;
private string $methodName;
private array $acceptedRoles;
private UserGroupRepositoryInterface $repository;
public function __construct(string $className, string $methodName)
{
$this->className = $className;
$this->methodName = $methodName;
// you need these roles to do anything with any endpoint.
$this->acceptedRoles = [UserRoleEnum::OWNER, UserRoleEnum::FULL];
$this->repository = app(UserGroupRepositoryInterface::class);
}
/**
* @throws AuthorizationException
*/
#[\Override]
public function validate(string $attribute, mixed $value, \Closure $fail): void
{
if ('GET' === $this->methodName) {
// need at least "read only rights".
$this->acceptedRoles[] = UserRoleEnum::READ_ONLY;
}
if ('GET' !== $this->methodName) {
// either post, put or delete or something else.. you need more access rights.
switch ($this->className) {
default:
throw new AuthorizationException(sprintf('Cannot handle class "%s"', $this->className));
case Account::class:
$this->acceptedRoles[] = UserRoleEnum::MANAGE_TRANSACTIONS;
break;
}
}
$this->validateUserGroup((int)$value, $fail);
}
private function validateUserGroup(int $userGroupId, \Closure $fail): void
{
Log::debug(sprintf('validateUserGroup: %s', static::class));
if (!auth()->check()) {
Log::debug('validateUserGroup: user is not logged in, return NULL.');
$fail('validation.no_auth_user_group')->translate();
return;
}
/** @var User $user */
$user = auth()->user();
if (0 !== $userGroupId) {
Log::debug(sprintf('validateUserGroup: user group submitted, search for memberships in group #%d.', $userGroupId));
}
if (0 === $userGroupId) {
$userGroupId = $user->user_group_id;
Log::debug(sprintf('validateUserGroup: no user group submitted, use default group #%d.', $userGroupId));
}
$this->repository->setUser($user);
$memberships = $this->repository->getMembershipsFromGroupId($userGroupId);
if (0 === $memberships->count()) {
Log::debug(sprintf('validateUserGroup: user has no access to group #%d.', $userGroupId));
$fail('validation.no_access_user_group')->translate();
return;
}
// need to get the group from the membership:
$userGroup = $this->repository->getById($userGroupId);
if (null === $userGroup) {
Log::debug(sprintf('validateUserGroup: group #%d does not exist.', $userGroupId));
$fail('validation.belongs_user_or_user_group')->translate();
return;
}
Log::debug(sprintf('validateUserGroup: validate access of user to group #%d ("%s").', $userGroupId, $userGroup->title));
Log::debug(sprintf('validateUserGroup: have %d roles to check.', count($this->acceptedRoles)), $this->acceptedRoles);
/** @var UserRoleEnum $role */
foreach ($this->acceptedRoles as $role) {
if ($user->hasRoleInGroupOrOwner($userGroup, $role)) {
Log::debug(sprintf('validateUserGroup: User has role "%s" in group #%d, return.', $role->value, $userGroupId));
return;
}
Log::debug(sprintf('validateUserGroup: User does NOT have role "%s" in group #%d, continue searching.', $role->value, $userGroupId));
}
Log::debug('validateUserGroup: User does NOT have enough rights to access endpoint.');
$fail('validation.belongs_user_or_user_group')->translate();
}
}

View File

@@ -216,7 +216,6 @@ class CreditRecalculateService
app('log')->debug(sprintf('Destination amount "%s" is now "%s"', $dest->amount, app('steam')->negative($dest->amount)));
$source->amount = app('steam')->positive($source->amount);
$dest->amount = app('steam')->negative($source->amount);
var_dump($source->foreign_amount);
if (null !== $source->foreign_amount && '' !== $source->foreign_amount) {
$source->foreign_amount = app('steam')->positive($source->foreign_amount);
app('log')->debug(sprintf('Source foreign amount "%s" is now "%s"', $source->foreign_amount, app('steam')->positive($source->foreign_amount)));

View File

@@ -29,6 +29,7 @@ use FireflyIII\Exceptions\FireflyException;
use FireflyIII\Models\CurrencyExchangeRate;
use FireflyIII\Models\TransactionCurrency;
use FireflyIII\Support\CacheProperties;
use Illuminate\Support\Facades\Cache;
use Illuminate\Support\Facades\Log;
/**
@@ -48,7 +49,11 @@ class ExchangeRateConverter
*/
public function convert(TransactionCurrency $from, TransactionCurrency $to, Carbon $date, string $amount): string
{
Log::debug('convert()');
if (false === config('cer.enabled')) {
Log::debug('ExchangeRateConverter: disabled, return amount as is.');
return $amount;
}
$rate = $this->getCurrencyRate($from, $to, $date);
return bcmul($amount, $rate);
@@ -59,7 +64,11 @@ class ExchangeRateConverter
*/
public function getCurrencyRate(TransactionCurrency $from, TransactionCurrency $to, Carbon $date): string
{
Log::debug('getCurrencyRate()');
if (false === config('cer.enabled')) {
Log::debug('ExchangeRateConverter: disabled, return "1".');
return '1';
}
$rate = $this->getRate($from, $to, $date);
return '0' === $rate ? '1' : $rate;
@@ -70,25 +79,36 @@ class ExchangeRateConverter
*/
private function getRate(TransactionCurrency $from, TransactionCurrency $to, Carbon $date): string
{
Log::debug('getRate()');
if ($this->isPrepared && $this->noPreparedRates) {
$fallback = $this->fallback[$from->id][$to->id] ?? '0';
Log::debug(sprintf('Return fallback rate from #%d to #%d on %s: %s', $from->id, $to->id, $date->format('Y-m-d'), $fallback));
$key = $this->getCacheKey($from, $to, $date);
$res = Cache::get($key, null);
return $fallback;
// find in cache
if (null !== $res) {
Log::debug(sprintf('ExchangeRateConverter: Return cached rate from #%d to #%d on %s.', $from->id, $to->id, $date->format('Y-m-d')));
return $res;
}
// first attempt:
// find in database
$rate = $this->getFromDB($from->id, $to->id, $date->format('Y-m-d'));
if (null !== $rate) {
Cache::forever($key, $rate);
Log::debug(sprintf('ExchangeRateConverter: Return DB rate from #%d to #%d on %s.', $from->id, $to->id, $date->format('Y-m-d')));
return $rate;
}
// no result. perhaps the other way around?
// find reverse in database
$rate = $this->getFromDB($to->id, $from->id, $date->format('Y-m-d'));
if (null !== $rate) {
return bcdiv('1', $rate);
$rate = bcdiv('1', $rate);
Cache::forever($key, $rate);
Log::debug(sprintf('ExchangeRateConverter: Return DB rate from #%d to #%d on %s.', $from->id, $to->id, $date->format('Y-m-d')));
return $rate;
}
// if nothing in place, fall back on the rate for $from to EUR
// fallback scenario.
$first = $this->getEuroRate($from, $date);
$second = $this->getEuroRate($to, $date);
@@ -96,17 +116,19 @@ class ExchangeRateConverter
if (0 === bccomp('0', $first) || 0 === bccomp('0', $second)) {
Log::warning(sprintf('$first is "%s" and $second is "%s"', $first, $second));
return '0';
return '1';
}
$second = bcdiv('1', $second);
$rate = bcmul($first, $second);
Log::debug(sprintf('ExchangeRateConverter: Return DB rate from #%d to #%d on %s.', $from->id, $to->id, $date->format('Y-m-d')));
Cache::forever($key, $rate);
return bcmul($first, $second);
return $rate;
}
private function getFromDB(int $from, int $to, string $date): ?string
{
Log::debug('getFromDB()');
if ($from === $to) {
return '1';
}
@@ -115,7 +137,7 @@ class ExchangeRateConverter
// perhaps the rate has been cached during this particular run
$preparedRate = $this->prepared[$date][$from][$to] ?? null;
if (null !== $preparedRate && 0 !== bccomp('0', $preparedRate)) {
Log::debug(sprintf('Found prepared rate from #%d to #%d on %s.', $from, $to, $date));
Log::debug(sprintf('ExchangeRateConverter: Found prepared rate from #%d to #%d on %s.', $from, $to, $date));
return $preparedRate;
}
@@ -127,7 +149,7 @@ class ExchangeRateConverter
if ('' === $rate) {
return null;
}
Log::debug(sprintf('Found cached rate from #%d to #%d on %s.', $from, $to, $date));
Log::debug(sprintf('ExchangeRateConverter: Found !cached! rate from #%d to #%d on %s.', $from, $to, $date));
return $rate;
}
@@ -142,19 +164,19 @@ class ExchangeRateConverter
->first()
;
++$this->queryCount;
$rate = (string)$result?->rate;
$rate = (string) $result?->rate;
if ('' === $rate) {
app('log')->debug(sprintf('Found no rate for #%d->#%d (%s) in the DB.', $from, $to, $date));
app('log')->debug(sprintf('ExchangeRateConverter: Found no rate for #%d->#%d (%s) in the DB.', $from, $to, $date));
return null;
}
if (0 === bccomp('0', $rate)) {
app('log')->debug(sprintf('Found rate for #%d->#%d (%s) in the DB, but it\'s zero.', $from, $to, $date));
app('log')->debug(sprintf('ExchangeRateConverter: Found rate for #%d->#%d (%s) in the DB, but it\'s zero.', $from, $to, $date));
return null;
}
app('log')->debug(sprintf('Found rate for #%d->#%d (%s) in the DB: %s.', $from, $to, $date, $rate));
app('log')->debug(sprintf('ExchangeRateConverter: Found rate for #%d->#%d (%s) in the DB: %s.', $from, $to, $date, $rate));
$cache->store($rate);
// if the rate has not been cached during this particular run, save it
@@ -178,7 +200,6 @@ class ExchangeRateConverter
*/
private function getEuroRate(TransactionCurrency $currency, Carbon $date): string
{
Log::debug('getEuroRate()');
$euroId = $this->getEuroId();
if ($euroId === $currency->id) {
return '1';
@@ -198,7 +219,7 @@ class ExchangeRateConverter
// grab backup values from config file:
$backup = config(sprintf('cer.rates.%s', $currency->code));
if (null !== $backup) {
return bcdiv('1', (string)$backup);
return bcdiv('1', (string) $backup);
// app('log')->debug(sprintf('Backup rate for %s to EUR is %s.', $currency->code, $backup));
// return $backup;
}
@@ -216,7 +237,7 @@ class ExchangeRateConverter
$cache = new CacheProperties();
$cache->addProperty('cer-euro-id');
if ($cache->has()) {
return (int)$cache->get();
return (int) $cache->get();
}
$euro = TransactionCurrency::whereCode('EUR')->first();
++$this->queryCount;
@@ -233,6 +254,9 @@ class ExchangeRateConverter
*/
public function prepare(TransactionCurrency $from, TransactionCurrency $to, Carbon $start, Carbon $end): void
{
if (false === config('cer.enabled')) {
return;
}
Log::debug('prepare()');
$start->startOfDay();
$end->endOfDay();
@@ -305,6 +329,14 @@ class ExchangeRateConverter
public function summarize(): void
{
if (false === config('cer.enabled')) {
return;
}
Log::debug(sprintf('ExchangeRateConverter ran %d queries.', $this->queryCount));
}
private function getCacheKey(TransactionCurrency $from, TransactionCurrency $to, Carbon $date): string
{
return sprintf('cer-%d-%d-%s', $from->id, $to->id, $date->format('Y-m-d'));
}
}

View File

@@ -171,6 +171,8 @@ trait AugumentData
/** @var BudgetLimitRepositoryInterface $blRepository */
$blRepository = app(BudgetLimitRepositoryInterface::class);
$end->endOfMonth();
// properties for cache
$cache = new CacheProperties();
$cache->addProperty($start);

View File

@@ -370,6 +370,7 @@ trait PeriodOverview
$first = $this->journalRepos->firstNull();
$start = null === $first ? new Carbon() : $first->date;
$end = clone $theDate;
$end = app('navigation')->endOfPeriod($end, $range);
app('log')->debug(sprintf('Start for getNoCategoryPeriodOverview() is %s', $start->format('Y-m-d')));
app('log')->debug(sprintf('End for getNoCategoryPeriodOverview() is %s', $end->format('Y-m-d')));

View File

@@ -0,0 +1,62 @@
<?php
/*
* UserGroupDetectable.php
* Copyright (c) 2024 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\Support\JsonApi\Concerns;
use FireflyIII\Models\UserGroup;
use FireflyIII\User;
trait UserGroupDetectable
{
/**
* Return the user group or NULL if none is set.
* Will throw exception if invalid.
* TODO Duplicate from API v2 code.
*/
public function detectUserGroup(): ?UserGroup
{
/** @var User $user */
$user = auth()->user();
app('log')->debug('Now in detectUserGroup()');
/** @var null|UserGroup $userGroup */
$userGroup = request()->route()?->parameter('userGroup');
if (null === $userGroup) {
app('log')->debug('Request class has no userGroup parameter, but perhaps there is a parameter.');
$userGroupId = (int)request()->get('user_group_id');
if (0 === $userGroupId) {
app('log')->debug(sprintf('Request class has no user_group_id parameter, grab default from user (group #%d).', $user->user_group_id));
$userGroupId = (int)$user->user_group_id;
}
$userGroup = UserGroup::find($userGroupId);
if (null === $userGroup) {
app('log')->error(sprintf('Request class has user_group_id (#%d), but group does not exist.', $userGroupId));
return null;
}
app('log')->debug('Request class has valid user_group_id.');
}
return $userGroup;
}
}

View File

@@ -29,35 +29,56 @@ use FireflyIII\Models\Account;
use FireflyIII\Models\AccountType;
use FireflyIII\Repositories\UserGroups\Account\AccountRepositoryInterface;
use FireflyIII\Repositories\UserGroups\Currency\CurrencyRepositoryInterface;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Collection;
use Illuminate\Support\Facades\Log;
/**
* Class AccountEnrichment
*
* This class "enriches" accounts and adds data from other tables and models to each account model.
*/
class AccountEnrichment implements EnrichmentInterface
{
private Collection $collection;
private array $currencies;
private AccountRepositoryInterface $repository;
private CurrencyRepositoryInterface $currencyRepository;
public function __construct()
{
$this->repository = app(AccountRepositoryInterface::class);
$this->currencyRepository = app(CurrencyRepositoryInterface::class);
}
#[\Override]
/**
* Do the actual enrichment.
*/
public function enrich(Collection $collection): Collection
{
Log::debug(sprintf('Now doing account enrichment for %d account(s)', $collection->count()));
// prep local fields
$this->collection = $collection;
$this->currencies = [];
// do everything here:
$this->getLastActivity();
// $this->getMetaBalances();
$this->collectAccountTypes();
$this->collectMetaData();
// $this->getMetaBalances();
$this->collection->transform(function (Account $account) {
$account->user_array = ['id' => 1, 'bla bla' => 'bla'];
$account->balances = collect([
['balance_id' => 1, 'balance' => 5],
['balance_id' => 2, 'balance' => 5],
['balance_id' => 3, 'balance' => 5],
]);
return $account;
});
// $this->collection->transform(function (Account $account) {
// $account->user_array = ['id' => 1, 'bla bla' => 'bla'];
// $account->balances = collect([
// ['balance_id' => 1, 'balance' => 5],
// ['balance_id' => 2, 'balance' => 5],
// ['balance_id' => 3, 'balance' => 5],
// ]);
//
// return $account;
// });
return $this->collection;
}
@@ -67,9 +88,7 @@ class AccountEnrichment implements EnrichmentInterface
*/
private function getLastActivity(): void
{
/** @var AccountRepositoryInterface $accountRepository */
$accountRepository = app(AccountRepositoryInterface::class);
$lastActivity = $accountRepository->getLastActivity($this->collection);
$lastActivity = $this->repository->getLastActivity($this->collection);
foreach ($lastActivity as $row) {
$this->collection->where('id', $row['account_id'])->first()->last_activity = Carbon::parse($row['date_max'], config('app.timezone'));
}
@@ -98,17 +117,15 @@ class AccountEnrichment implements EnrichmentInterface
*/
private function collectAccountTypes(): void
{
/** @var AccountRepositoryInterface $accountRepository */
$accountRepository = app(AccountRepositoryInterface::class);
$accountTypes = $accountRepository->getAccountTypes($this->collection);
$types = [];
$accountTypes = $this->repository->getAccountTypes($this->collection);
$types = [];
/** @var AccountType $row */
foreach ($accountTypes as $row) {
$types[$row->id] = $row->type;
}
$this->collection->transform(function (Account $account) use ($types) {
$account->type = $types[$account->id];
$account->account_type_string = $types[$account->id];
return $account;
});
@@ -116,17 +133,11 @@ class AccountEnrichment implements EnrichmentInterface
private function collectMetaData(): void
{
/** @var AccountRepositoryInterface $accountRepository */
$accountRepository = app(AccountRepositoryInterface::class);
$metaFields = $this->repository->getMetaValues($this->collection, ['currency_id', 'account_role', 'account_number', 'liability_direction', 'interest', 'interest_period', 'current_debt']);
$currencyIds = $metaFields->where('name', 'currency_id')->pluck('data')->toArray();
/** @var CurrencyRepositoryInterface $repository */
$repository = app(CurrencyRepositoryInterface::class);
$metaFields = $accountRepository->getMetaValues($this->collection, ['currency_id', 'account_role', 'account_number', 'liability_direction', 'interest', 'interest_period', 'current_debt']);
$currencyIds = $metaFields->where('name', 'currency_id')->pluck('data')->toArray();
$currencies = [];
foreach ($repository->getByIds($currencyIds) as $currency) {
$currencies = [];
foreach ($this->currencyRepository->getByIds($currencyIds) as $currency) {
$id = $currency->id;
$currencies[$id] = $currency;
}
@@ -137,6 +148,7 @@ class AccountEnrichment implements EnrichmentInterface
$account->{$entry->name} = $entry->data;
if ('currency_id' === $entry->name) {
$id = (int) $entry->data;
$account->currency_name = $currencies[$id]?->name;
$account->currency_code = $currencies[$id]?->code;
$account->currency_symbol = $currencies[$id]?->symbol;
$account->currency_decimal_places = $currencies[$id]?->decimal_places;
@@ -146,4 +158,14 @@ class AccountEnrichment implements EnrichmentInterface
return $account;
});
}
#[\Override]
public function enrichSingle(Model $model): Model
{
Log::debug(__METHOD__);
$collection = new Collection([$model]);
$collection = $this->enrich($collection);
return $collection->first();
}
}

View File

@@ -23,9 +23,12 @@ declare(strict_types=1);
namespace FireflyIII\Support\JsonApi\Enrichments;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Collection;
interface EnrichmentInterface
{
public function enrich(Collection $collection): Collection;
public function enrichSingle(Model $model): Model;
}

View File

@@ -27,7 +27,7 @@ use LaravelJsonApi\Core\Query\SortFields;
trait ValidateSortParameters
{
public function validateParams(string $class, ?SortFields $params): bool
public function needsFullDataset(string $class, ?SortFields $params): bool
{
if (null === $params) {
return false;

View File

@@ -23,6 +23,7 @@ declare(strict_types=1);
namespace FireflyIII\Support\Models;
use FireflyIII\Exceptions\FireflyException;
use FireflyIII\Models\Account;
use FireflyIII\Models\AccountBalance;
use FireflyIII\Models\Transaction;
@@ -117,16 +118,38 @@ class AccountBalanceCalculator
$foreignCurrency = (int) $row->foreign_currency_id;
$sumAmount = (string) $row->sum_amount;
$sumForeignAmount = (string) $row->sum_foreign_amount;
$sumAmount = '' === $sumAmount ? '0' : $sumAmount;
$sumForeignAmount = '' === $sumForeignAmount ? '0' : $sumForeignAmount;
// at this point SQLite may return scientific notation because why not. Terrible.
$sumAmount = app('steam')->floatalize($sumAmount);
$sumForeignAmount = app('steam')->floatalize($sumForeignAmount);
// first create for normal currency:
$entry = $this->getAccountBalanceByAccount($account, $transactionCurrency);
$entry->balance = bcadd((string) $entry->balance, $sumAmount);
try {
$entry->balance = bcadd((string) $entry->balance, $sumAmount);
} catch (\ValueError $e) {
$message = sprintf('[a] Could not add "%s" to "%s": %s', $entry->balance, $sumAmount, $e->getMessage());
Log::error($message);
throw new FireflyException($message, 0, $e);
}
$entry->save();
// then do foreign amount, if present:
if ($foreignCurrency > 0) {
$entry = $this->getAccountBalanceByAccount($account, $foreignCurrency);
$entry->balance = bcadd((string) $entry->balance, $sumForeignAmount);
$entry = $this->getAccountBalanceByAccount($account, $foreignCurrency);
try {
$entry->balance = bcadd((string) $entry->balance, $sumForeignAmount);
} catch (\ValueError $e) {
$message = sprintf('[b] Could not add "%s" to "%s": %s', $entry->balance, $sumForeignAmount, $e->getMessage());
Log::error($message);
throw new FireflyException($message, 0, $e);
}
$entry->save();
}
}

View File

@@ -750,6 +750,8 @@ class Navigation
$function = $functionMap[$range];
$end->{$function}(); // @phpstan-ignore-line
Log::debug(sprintf('updateEndDate returns "%s"', $end->format('Y-m-d')));
return $end;
}
if ('6M' === $range) {
@@ -806,6 +808,7 @@ class Navigation
if (array_key_exists($range, $functionMap)) {
$function = $functionMap[$range];
$start->{$function}(); // @phpstan-ignore-line
Log::debug(sprintf('updateStartDate returns "%s"', $start->format('Y-m-d')));
return $start;
}

View File

@@ -73,6 +73,7 @@ trait ChecksLogin
/**
* Return the user group or NULL if none is set.
* Will throw exception if invalid.
* TODO duplicated in JSONAPI code.
*/
public function getUserGroup(): ?UserGroup
{

View File

@@ -836,6 +836,7 @@ class Steam
if (!str_contains($value, 'E')) {
return $value;
}
Log::debug(sprintf('Floatalizing %s', $value));
$number = substr($value, 0, (int)strpos($value, 'E'));
if (str_contains($number, '.')) {

View File

@@ -186,7 +186,7 @@ class General extends AbstractExtension
$converter = new GithubFlavoredMarkdownConverter(
[
'allow_unsafe_links' => false,
'max_nesting_level' => 3,
'max_nesting_level' => 5,
'html_input' => 'escape',
]
);

View File

@@ -53,7 +53,7 @@ class AttachmentTransformer extends AbstractTransformer
'created_at' => $attachment->created_at->toAtomString(),
'updated_at' => $attachment->updated_at->toAtomString(),
'attachable_id' => (string)$attachment->attachable_id,
'attachable_type' => str_replace('FireflyIII\\Models\\', '', $attachment->attachable_type),
'attachable_type' => str_replace('FireflyIII\Models\\', '', $attachment->attachable_type),
'md5' => $attachment->md5,
'filename' => $attachment->filename,
'download_url' => route('api.v1.attachments.download', [$attachment->id]),

View File

@@ -128,7 +128,8 @@ class RecurrenceTransformer extends AbstractTransformer
];
// get the (future) occurrences for this specific type of repetition:
$occurrences = $this->repository->getXOccurrencesSince($repetition, $fromDate, new Carbon(), 5);
$amount = 'daily' === $repetition->repetition_type ? 9 : 5;
$occurrences = $this->repository->getXOccurrencesSince($repetition, $fromDate, now(), $amount);
/** @var Carbon $carbon */
foreach ($occurrences as $carbon) {

View File

@@ -106,7 +106,13 @@ trait GroupValidation
'source_id', 'source_name', 'source_number', 'source_iban',
'destination_id', 'destination_name', 'destination_number', 'destination_iban',
];
// stop protesting when reconciliation is set to FALSE.
foreach ($data['transactions'] as $index => $row) {
if (false === ($row['reconciled'] ?? false)) {
continue;
}
foreach ($forbidden as $key) {
if (array_key_exists($key, $row)) {
$validator->errors()->add(

View File

@@ -3,6 +3,62 @@
All notable changes to this project will be documented in this file.
This project adheres to [Semantic Versioning](http://semver.org/).
## 6.1.19 - 2024-07-20
### Fixed
- [Issue 8844](https://github.com/firefly-iii/firefly-iii/issues/8844) (Split recurring transaction gets wrong (split) titles) reported by @dreautall
- [Issue 8981](https://github.com/firefly-iii/firefly-iii/issues/8981) (bcadd() error during Docker container startup) reported by @NoiTheCat
- [Issue 8986](https://github.com/firefly-iii/firefly-iii/issues/8986) (Search with "internal_reference_is" finds all transactions with full word of search string) reported by @baflo
- [Issue 9009](https://github.com/firefly-iii/firefly-iii/issues/9009) (Incorrect Amount Calculation in Reconciliation for Bank Account A) reported by @realzsan3
- [Issue 9021](https://github.com/firefly-iii/firefly-iii/issues/9021) (Incorrect "Expected Withdrawals" for Daily Recurring Transactions) reported by @xMarcii
- [Issue 9022](https://github.com/firefly-iii/firefly-iii/issues/9022) (Calendar Not Showing Green Fields for Recurring Transactions) reported by @xMarcii
- Improved currency exchange rate downloader
## 6.1.18 - 2024-06-19
### Fixed
- [Issue 8978](https://github.com/firefly-iii/firefly-iii/issues/8978) (Error! Internal Firefly III Exception: bcadd(): Argument #2 ($num2) is not well-formed) reported by @el-rhazi
- [Issue 8977](https://github.com/firefly-iii/firefly-iii/issues/8977) (Data Importer: "500 Server Error" with Firefly III v6.1.17) reported by @qtdzz
### Security
- [CVE-2024-37893](https://www.cve.org/CVERecord?id=CVE-2024-37893)
## 6.1.17 - 2024-06-16
### Added
- New routine that calculates account balances, first start could take a while.
### Removed
- Removed auto-generated language files.
### Fixed
- [Issue 8907](https://github.com/firefly-iii/firefly-iii/issues/8907) (Error when adding initial balance: bcadd(): Argument #2 ($num2) must be of type string, int given) reported by @wnklmnn
- [Issue 8911](https://github.com/firefly-iii/firefly-iii/issues/8911) (Docker container startup very slow) reported by @daften
- [PR 8929](https://github.com/firefly-iii/firefly-iii/pull/8929) (icon title chgd from Deposit to Transfer) reported by @stevewasiura
- [PR 8930](https://github.com/firefly-iii/firefly-iii/pull/8930) (icon title chgd from Deposit to Transfer) reported by @stevewasiura
- [PR 8951](https://github.com/firefly-iii/firefly-iii/pull/8951) (add icon for delete action) reported by @stevewasiura
- [PR 8957](https://github.com/firefly-iii/firefly-iii/pull/8957) (Remove nesting level for markdown) reported by @JeroenED
- [Issue 8958](https://github.com/firefly-iii/firefly-iii/issues/8958) (Weird line appears above the UI when clicking on matching transactions for a rule) reported by @avee87
- [Issue 8893](https://github.com/firefly-iii/firefly-iii/issues/8893) (API: `reconciled: false` does not have precedence) reported by @dreautall
- [Issue 8954](https://github.com/firefly-iii/firefly-iii/issues/8954) (Wrong calculation of transaction without category) reported by @anarion80
- [Issue 8927](https://github.com/firefly-iii/firefly-iii/issues/8927) (Converting deposit to transfer can set incorrect transaction currency) reported by @avee87
- Various issues in release train.
- There is a confirmation again before you delete data using the page in your profile
### Security
- Two (undisclosed) MFA bypass errors, reported by @Skelmis. Disclosure will follow in a few weeks.
### API
- Expand v2 chart API
## 6.1.16 - 2024-05-20
### Added

View File

@@ -84,6 +84,7 @@
"bacon/bacon-qr-code": "2.*",
"diglactic/laravel-breadcrumbs": "^9",
"gdbots/query-parser": "^3.0",
"genealabs/laravel-model-caching": "^11.0",
"guzzlehttp/guzzle": "^7.8",
"jc5/google2fa-laravel": "^2.0",
"jc5/recovery": "^2",
@@ -107,8 +108,8 @@
"spatie/laravel-ignition": "^2",
"spatie/period": "^2.4",
"symfony/expression-language": "^7.0",
"symfony/http-client": "^7.0",
"symfony/mailgun-mailer": "^7.0"
"symfony/http-client": "^7.1",
"symfony/mailgun-mailer": "^7.1"
},
"require-dev": {
"barryvdh/laravel-debugbar": "^3.9",

1150
composer.lock generated

File diff suppressed because it is too large Load Diff

View File

@@ -225,7 +225,7 @@ return [
'show_copy' => false, // Show copy button next to the query,
'slow_threshold' => false, // Only track queries that last longer than this time in ms
'memory_usage' => false, // Show queries memory usage
'soft_limit' => 100, // After the soft limit, no parameters/backtrace are captured
'soft_limit' => 250, // After the soft limit, no parameters/backtrace are captured
'hard_limit' => 500, // After the hard limit, queries are ignored
],
'mail' => [

View File

@@ -114,10 +114,10 @@ return [
'telemetry' => false,
'webhooks' => true,
'handle_debts' => true,
'expression_engine' => false,
'expression_engine' => true,
// see cer.php for exchange rates feature flag.
],
'version' => 'develop/2024-05-30',
'version' => 'develop/2024-07-29',
'api_version' => '2.1.0',
'db_version' => 24,
@@ -503,13 +503,13 @@ return [
'remove_tag' => RemoveTag::class,
'remove_all_tags' => RemoveAllTags::class,
'set_description' => SetDescription::class,
'append_description' => AppendDescription::class,
'prepend_description' => PrependDescription::class,
// 'append_description' => AppendDescription::class,
// 'prepend_description' => PrependDescription::class,
'set_source_account' => SetSourceAccount::class,
'set_destination_account' => SetDestinationAccount::class,
'set_notes' => SetNotes::class,
'append_notes' => AppendNotes::class,
'prepend_notes' => PrependNotes::class,
// 'append_notes' => AppendNotes::class,
// 'prepend_notes' => PrependNotes::class,
'clear_notes' => ClearNotes::class,
'link_to_bill' => LinkToBill::class,
'convert_withdrawal' => ConvertToWithdrawal::class,
@@ -518,10 +518,10 @@ return [
'switch_accounts' => SwitchAccounts::class,
'update_piggy' => UpdatePiggybank::class,
'delete_transaction' => DeleteTransaction::class,
'append_descr_to_notes' => AppendDescriptionToNotes::class,
'append_notes_to_descr' => AppendNotesToDescription::class,
'move_descr_to_notes' => MoveDescriptionToNotes::class,
'move_notes_to_descr' => MoveNotesToDescription::class,
// 'append_descr_to_notes' => AppendDescriptionToNotes::class,
// 'append_notes_to_descr' => AppendNotesToDescription::class,
// 'move_descr_to_notes' => MoveDescriptionToNotes::class,
// 'move_notes_to_descr' => MoveNotesToDescription::class,
'set_source_to_cash' => SetSourceToCashAccount::class,
'set_destination_to_cash' => SetDestinationToCashAccount::class,
'set_amount' => SetAmount::class,

View File

@@ -2,7 +2,7 @@
declare(strict_types=1);
use FireflyIII\JsonApi\V3\Server;
use FireflyIII\JsonApi\V2\Server;
return [
/*
@@ -30,6 +30,6 @@ return [
| class name of the server class.
*/
'servers' => [
'v3' => Server::class,
'v2' => Server::class,
],
];

View File

@@ -0,0 +1,10 @@
<?php
declare(strict_types=1);
return [
'cache-prefix' => '',
'enabled' => env('MODEL_CACHE_ENABLED', true),
'use-database-keying' => env('MODEL_CACHE_USE_DATABASE_KEYING', true),
'store' => env('MODEL_CACHE_STORE'),
];

View File

@@ -42,6 +42,7 @@ class TransactionCurrencySeeder extends Seeder
$currencies[] = ['code' => 'PLN', 'name' => 'Polish złoty', 'symbol' => 'zł', 'decimal_places' => 2];
$currencies[] = ['code' => 'TRY', 'name' => 'Turkish lira', 'symbol' => '₺', 'decimal_places' => 2];
$currencies[] = ['code' => 'DKK', 'name' => 'Dansk krone', 'symbol' => 'kr.', 'decimal_places' => 2];
$currencies[] = ['code' => 'RON', 'name' => 'Romanian leu', 'symbol' => 'lei', 'decimal_places' => 2];
// american currencies
$currencies[] = ['code' => 'USD', 'name' => 'US Dollar', 'symbol' => '$', 'decimal_places' => 2];

1764
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@@ -15,7 +15,7 @@
},
"devDependencies": {
"@johmun/vue-tags-input": "^2",
"@vue/compiler-sfc": "^3.3.4",
"@vue/compiler-sfc": "^3.4.34",
"axios": "^1.3",
"bootstrap-sass": "^3",
"cross-env": "^7.0",

View File

@@ -9,17 +9,17 @@
},
"devDependencies": {
"axios": "^1.6.8",
"laravel-vite-plugin": "^1.0.2",
"laravel-vite-plugin": "^1.0.5",
"patch-package": "^8.0.0",
"sass": "^1.75.0",
"sass": "^1.77.8",
"vite": "^5",
"vite-plugin-manifest-sri": "^0.2.0"
},
"dependencies": {
"@ag-grid-community/client-side-row-model": "^31.0.3",
"@ag-grid-community/core": "^31.0.3",
"@ag-grid-community/infinite-row-model": "^31.0.3",
"@ag-grid-community/styles": "^31.0.3",
"@ag-grid-community/client-side-row-model": "^32.0.2",
"@ag-grid-community/core": "^32.0.2",
"@ag-grid-community/infinite-row-model": "^32.0.2",
"@ag-grid-community/styles": "^32.0.0",
"@fortawesome/fontawesome-free": "^6.4.0",
"@popperjs/core": "^2.11.8",
"admin-lte": "^4.0.0-alpha3",

View File

@@ -268,6 +268,7 @@ return [
'auto_budget_period_mandatory' => 'The auto budget period is a mandatory field.',
// no access to administration:
'no_auth_user_group' => 'You have to be logged in to access this administration.',
'no_access_user_group' => 'You do not have the correct access rights for this administration.',
'administration_owner_rename' => 'You can\'t rename your standard administration.',
];

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,444 @@
{
"af_NA": "Afrikaans (Namibia)",
"af_ZA": "Afrikaans (South Africa)",
"ak_GH": "Akan (Ghana)",
"sq_AL": "Albanian (Albania)",
"sq_XK": "Albanian (Kosovo)",
"sq_MK": "Albanian (Macedonia)",
"am_ET": "Amharic (Ethiopia)",
"ar_DZ": "Arabic (Algeria)",
"ar_BH": "Arabic (Bahrain)",
"ar_TD": "Arabic (Chad)",
"ar_KM": "Arabic (Comoros)",
"ar_DJ": "Arabic (Djibouti)",
"ar_EG": "Arabic (Egypt)",
"ar_ER": "Arabic (Eritrea)",
"ar_IQ": "Arabic (Iraq)",
"ar_IL": "Arabic (Israel)",
"ar_JO": "Arabic (Jordan)",
"ar_KW": "Arabic (Kuwait)",
"ar_LB": "Arabic (Lebanon)",
"ar_LY": "Arabic (Libya)",
"ar_MR": "Arabic (Mauritania)",
"ar_MA": "Arabic (Morocco)",
"ar_OM": "Arabic (Oman)",
"ar_PS": "Arabic (Palestinian Territories)",
"ar_QA": "Arabic (Qatar)",
"ar_SA": "Arabic (Saudi Arabia)",
"ar_SO": "Arabic (Somalia)",
"ar_SS": "Arabic (South Sudan)",
"ar_SD": "Arabic (Sudan)",
"ar_SY": "Arabic (Syria)",
"ar_TN": "Arabic (Tunisia)",
"ar_AE": "Arabic (United Arab Emirates)",
"ar_EH": "Arabic (Western Sahara)",
"ar_YE": "Arabic (Yemen)",
"hy_AM": "Armenian (Armenia)",
"as_IN": "Assamese (India)",
"az_AZ": "Azerbaijani (Azerbaijan)",
"az_Cyrl_AZ": "Azerbaijani (Cyrillic, Azerbaijan)",
"az_Cyrl": "Azerbaijani (Cyrillic)",
"az_Latn_AZ": "Azerbaijani (Latin, Azerbaijan)",
"az_Latn": "Azerbaijani (Latin)",
"bm_Latn_ML": "Bambara (Latin, Mali)",
"bm_Latn": "Bambara (Latin)",
"eu_ES": "Basque (Spain)",
"be_BY": "Belarusian (Belarus)",
"bn_BD": "Bengali (Bangladesh)",
"bn_IN": "Bengali (India)",
"bs_BA": "Bosnian (Bosnia & Herzegovina)",
"bs_Cyrl_BA": "Bosnian (Cyrillic, Bosnia & Herzegovina)",
"bs_Cyrl": "Bosnian (Cyrillic)",
"bs_Latn_BA": "Bosnian (Latin, Bosnia & Herzegovina)",
"bs_Latn": "Bosnian (Latin)",
"br_FR": "Breton (France)",
"bg_BG": "Bulgarian (Bulgaria)",
"my_MM": "Burmese (Myanmar (Burma))",
"ca_AD": "Catalan (Andorra)",
"ca_FR": "Catalan (France)",
"ca_IT": "Catalan (Italy)",
"ca_ES": "Catalan (Spain)",
"zh_CN": "Chinese (China)",
"zh_HK": "Chinese (Hong Kong SAR China)",
"zh_MO": "Chinese (Macau SAR China)",
"zh_Hans_CN": "Chinese (Simplified, China)",
"zh_Hans_HK": "Chinese (Simplified, Hong Kong SAR China)",
"zh_Hans_MO": "Chinese (Simplified, Macau SAR China)",
"zh_Hans_SG": "Chinese (Simplified, Singapore)",
"zh_Hans": "Chinese (Simplified)",
"zh_SG": "Chinese (Singapore)",
"zh_TW": "Chinese (Taiwan)",
"zh_Hant_HK": "Chinese (Traditional, Hong Kong SAR China)",
"zh_Hant_MO": "Chinese (Traditional, Macau SAR China)",
"zh_Hant_TW": "Chinese (Traditional, Taiwan)",
"zh_Hant": "Chinese (Traditional)",
"kw_GB": "Cornish (United Kingdom)",
"hr_BA": "Croatian (Bosnia & Herzegovina)",
"hr_HR": "Croatian (Croatia)",
"cs_CZ": "Czech (Czech Republic)",
"da_DK": "Danish (Denmark)",
"da_GL": "Danish (Greenland)",
"nl_AW": "Dutch (Aruba)",
"nl_BE": "Dutch (Belgium)",
"nl_BQ": "Dutch (Caribbean Netherlands)",
"nl_CW": "Dutch (Cura\u00e7ao)",
"nl_NL": "Dutch (Netherlands)",
"nl_SX": "Dutch (Sint Maarten)",
"nl_SR": "Dutch (Suriname)",
"dz_BT": "Dzongkha (Bhutan)",
"en_AS": "English (American Samoa)",
"en_AI": "English (Anguilla)",
"en_AG": "English (Antigua & Barbuda)",
"en_AU": "English (Australia)",
"en_BS": "English (Bahamas)",
"en_BB": "English (Barbados)",
"en_BE": "English (Belgium)",
"en_BZ": "English (Belize)",
"en_BM": "English (Bermuda)",
"en_BW": "English (Botswana)",
"en_IO": "English (British Indian Ocean Territory)",
"en_VG": "English (British Virgin Islands)",
"en_CM": "English (Cameroon)",
"en_CA": "English (Canada)",
"en_KY": "English (Cayman Islands)",
"en_CX": "English (Christmas Island)",
"en_CC": "English (Cocos (Keeling) Islands)",
"en_CK": "English (Cook Islands)",
"en_DG": "English (Diego Garcia)",
"en_DM": "English (Dominica)",
"en_ER": "English (Eritrea)",
"en_FK": "English (Falkland Islands)",
"en_FJ": "English (Fiji)",
"en_GM": "English (Gambia)",
"en_GH": "English (Ghana)",
"en_GI": "English (Gibraltar)",
"en_GD": "English (Grenada)",
"en_GU": "English (Guam)",
"en_GG": "English (Guernsey)",
"en_GY": "English (Guyana)",
"en_HK": "English (Hong Kong SAR China)",
"en_IN": "English (India)",
"en_IE": "English (Ireland)",
"en_IM": "English (Isle of Man)",
"en_JM": "English (Jamaica)",
"en_JE": "English (Jersey)",
"en_KE": "English (Kenya)",
"en_KI": "English (Kiribati)",
"en_LS": "English (Lesotho)",
"en_LR": "English (Liberia)",
"en_MO": "English (Macau SAR China)",
"en_MG": "English (Madagascar)",
"en_MW": "English (Malawi)",
"en_MY": "English (Malaysia)",
"en_MT": "English (Malta)",
"en_MH": "English (Marshall Islands)",
"en_MU": "English (Mauritius)",
"en_FM": "English (Micronesia)",
"en_MS": "English (Montserrat)",
"en_NA": "English (Namibia)",
"en_NR": "English (Nauru)",
"en_NZ": "English (New Zealand)",
"en_NG": "English (Nigeria)",
"en_NU": "English (Niue)",
"en_NF": "English (Norfolk Island)",
"en_MP": "English (Northern Mariana Islands)",
"en_PK": "English (Pakistan)",
"en_PW": "English (Palau)",
"en_PG": "English (Papua New Guinea)",
"en_PH": "English (Philippines)",
"en_PN": "English (Pitcairn Islands)",
"en_PR": "English (Puerto Rico)",
"en_RW": "English (Rwanda)",
"en_WS": "English (Samoa)",
"en_SC": "English (Seychelles)",
"en_SL": "English (Sierra Leone)",
"en_SG": "English (Singapore)",
"en_SX": "English (Sint Maarten)",
"en_SB": "English (Solomon Islands)",
"en_ZA": "English (South Africa)",
"en_SS": "English (South Sudan)",
"en_SH": "English (St. Helena)",
"en_KN": "English (St. Kitts & Nevis)",
"en_LC": "English (St. Lucia)",
"en_VC": "English (St. Vincent & Grenadines)",
"en_SD": "English (Sudan)",
"en_SZ": "English (Swaziland)",
"en_TZ": "English (Tanzania)",
"en_TK": "English (Tokelau)",
"en_TO": "English (Tonga)",
"en_TT": "English (Trinidad & Tobago)",
"en_TC": "English (Turks & Caicos Islands)",
"en_TV": "English (Tuvalu)",
"en_UM": "English (U.S. Outlying Islands)",
"en_VI": "English (U.S. Virgin Islands)",
"en_UG": "English (Uganda)",
"en_GB": "English (United Kingdom)",
"en_US": "English (United States)",
"en_VU": "English (Vanuatu)",
"en_ZM": "English (Zambia)",
"en_ZW": "English (Zimbabwe)",
"et_EE": "Estonian (Estonia)",
"ee_GH": "Ewe (Ghana)",
"ee_TG": "Ewe (Togo)",
"fo_FO": "Faroese (Faroe Islands)",
"fi_FI": "Finnish (Finland)",
"fr_DZ": "French (Algeria)",
"fr_BE": "French (Belgium)",
"fr_BJ": "French (Benin)",
"fr_BF": "French (Burkina Faso)",
"fr_BI": "French (Burundi)",
"fr_CM": "French (Cameroon)",
"fr_CA": "French (Canada)",
"fr_CF": "French (Central African Republic)",
"fr_TD": "French (Chad)",
"fr_KM": "French (Comoros)",
"fr_CG": "French (Congo - Brazzaville)",
"fr_CD": "French (Congo - Kinshasa)",
"fr_CI": "French (C\u00f4te d\u2019Ivoire)",
"fr_DJ": "French (Djibouti)",
"fr_GQ": "French (Equatorial Guinea)",
"fr_FR": "French (France)",
"fr_GF": "French (French Guiana)",
"fr_PF": "French (French Polynesia)",
"fr_GA": "French (Gabon)",
"fr_GP": "French (Guadeloupe)",
"fr_GN": "French (Guinea)",
"fr_HT": "French (Haiti)",
"fr_LU": "French (Luxembourg)",
"fr_MG": "French (Madagascar)",
"fr_ML": "French (Mali)",
"fr_MQ": "French (Martinique)",
"fr_MR": "French (Mauritania)",
"fr_MU": "French (Mauritius)",
"fr_YT": "French (Mayotte)",
"fr_MC": "French (Monaco)",
"fr_MA": "French (Morocco)",
"fr_NC": "French (New Caledonia)",
"fr_NE": "French (Niger)",
"fr_RE": "French (R\u00e9union)",
"fr_RW": "French (Rwanda)",
"fr_SN": "French (Senegal)",
"fr_SC": "French (Seychelles)",
"fr_BL": "French (St. Barth\u00e9lemy)",
"fr_MF": "French (St. Martin)",
"fr_PM": "French (St. Pierre & Miquelon)",
"fr_CH": "French (Switzerland)",
"fr_SY": "French (Syria)",
"fr_TG": "French (Togo)",
"fr_TN": "French (Tunisia)",
"fr_VU": "French (Vanuatu)",
"fr_WF": "French (Wallis & Futuna)",
"ff_CM": "Fulah (Cameroon)",
"ff_GN": "Fulah (Guinea)",
"ff_MR": "Fulah (Mauritania)",
"ff_SN": "Fulah (Senegal)",
"gl_ES": "Galician (Spain)",
"lg_UG": "Ganda (Uganda)",
"ka_GE": "Georgian (Georgia)",
"de_AT": "German (Austria)",
"de_BE": "German (Belgium)",
"de_DE": "German (Germany)",
"de_LI": "German (Liechtenstein)",
"de_LU": "German (Luxembourg)",
"de_CH": "German (Switzerland)",
"el_CY": "Greek (Cyprus)",
"el_GR": "Greek (Greece)",
"gu_IN": "Gujarati (India)",
"ha_GH": "Hausa (Ghana)",
"ha_Latn_GH": "Hausa (Latin, Ghana)",
"ha_Latn_NE": "Hausa (Latin, Niger)",
"ha_Latn_NG": "Hausa (Latin, Nigeria)",
"ha_Latn": "Hausa (Latin)",
"ha_NE": "Hausa (Niger)",
"ha_NG": "Hausa (Nigeria)",
"he_IL": "Hebrew (Israel)",
"hi_IN": "Hindi (India)",
"hu_HU": "Hungarian (Hungary)",
"is_IS": "Icelandic (Iceland)",
"ig_NG": "Igbo (Nigeria)",
"id_ID": "Indonesian (Indonesia)",
"ga_IE": "Irish (Ireland)",
"it_IT": "Italian (Italy)",
"it_SM": "Italian (San Marino)",
"it_CH": "Italian (Switzerland)",
"ja_JP": "Japanese (Japan)",
"kl_GL": "Kalaallisut (Greenland)",
"kn_IN": "Kannada (India)",
"ks_Arab_IN": "Kashmiri (Arabic, India)",
"ks_Arab": "Kashmiri (Arabic)",
"ks_IN": "Kashmiri (India)",
"kk_Cyrl_KZ": "Kazakh (Cyrillic, Kazakhstan)",
"kk_Cyrl": "Kazakh (Cyrillic)",
"kk_KZ": "Kazakh (Kazakhstan)",
"km_KH": "Khmer (Cambodia)",
"ki_KE": "Kikuyu (Kenya)",
"rw_RW": "Kinyarwanda (Rwanda)",
"ko_KP": "Korean (North Korea)",
"ko_KR": "Korean (South Korea)",
"ky_Cyrl_KG": "Kyrgyz (Cyrillic, Kyrgyzstan)",
"ky_Cyrl": "Kyrgyz (Cyrillic)",
"ky_KG": "Kyrgyz (Kyrgyzstan)",
"lo_LA": "Lao (Laos)",
"lv_LV": "Latvian (Latvia)",
"ln_AO": "Lingala (Angola)",
"ln_CF": "Lingala (Central African Republic)",
"ln_CG": "Lingala (Congo - Brazzaville)",
"ln_CD": "Lingala (Congo - Kinshasa)",
"lt_LT": "Lithuanian (Lithuania)",
"lu_CD": "Luba-Katanga (Congo - Kinshasa)",
"lb_LU": "Luxembourgish (Luxembourg)",
"mk_MK": "Macedonian (Macedonia)",
"mg_MG": "Malagasy (Madagascar)",
"ms_BN": "Malay (Brunei)",
"ms_Latn_BN": "Malay (Latin, Brunei)",
"ms_Latn_MY": "Malay (Latin, Malaysia)",
"ms_Latn_SG": "Malay (Latin, Singapore)",
"ms_Latn": "Malay (Latin)",
"ms_MY": "Malay (Malaysia)",
"ms_SG": "Malay (Singapore)",
"ml_IN": "Malayalam (India)",
"mt_MT": "Maltese (Malta)",
"gv_IM": "Manx (Isle of Man)",
"mr_IN": "Marathi (India)",
"mn_Cyrl_MN": "Mongolian (Cyrillic, Mongolia)",
"mn_Cyrl": "Mongolian (Cyrillic)",
"mn_MN": "Mongolian (Mongolia)",
"ne_IN": "Nepali (India)",
"ne_NP": "Nepali (Nepal)",
"nd_ZW": "North Ndebele (Zimbabwe)",
"se_FI": "Northern Sami (Finland)",
"se_NO": "Northern Sami (Norway)",
"se_SE": "Northern Sami (Sweden)",
"no_NO": "Norwegian (Norway)",
"nb_NO": "Norwegian Bokm\u00e5l (Norway)",
"nb_SJ": "Norwegian Bokm\u00e5l (Svalbard & Jan Mayen)",
"nn_NO": "Norwegian Nynorsk (Norway)",
"or_IN": "Oriya (India)",
"om_ET": "Oromo (Ethiopia)",
"om_KE": "Oromo (Kenya)",
"os_GE": "Ossetic (Georgia)",
"os_RU": "Ossetic (Russia)",
"ps_AF": "Pashto (Afghanistan)",
"fa_AF": "Persian (Afghanistan)",
"fa_IR": "Persian (Iran)",
"pl_PL": "Polish (Poland)",
"pt_AO": "Portuguese (Angola)",
"pt_BR": "Portuguese (Brazil)",
"pt_CV": "Portuguese (Cape Verde)",
"pt_GW": "Portuguese (Guinea-Bissau)",
"pt_MO": "Portuguese (Macau SAR China)",
"pt_MZ": "Portuguese (Mozambique)",
"pt_PT": "Portuguese (Portugal)",
"pt_ST": "Portuguese (S\u00e3o Tom\u00e9 & Pr\u00edncipe)",
"pt_TL": "Portuguese (Timor-Leste)",
"pa_Arab_PK": "Punjabi (Arabic, Pakistan)",
"pa_Arab": "Punjabi (Arabic)",
"pa_Guru_IN": "Punjabi (Gurmukhi, India)",
"pa_Guru": "Punjabi (Gurmukhi)",
"pa_IN": "Punjabi (India)",
"pa_PK": "Punjabi (Pakistan)",
"qu_BO": "Quechua (Bolivia)",
"qu_EC": "Quechua (Ecuador)",
"qu_PE": "Quechua (Peru)",
"ro_MD": "Romanian (Moldova)",
"ro_RO": "Romanian (Romania)",
"rm_CH": "Romansh (Switzerland)",
"rn_BI": "Rundi (Burundi)",
"ru_BY": "Russian (Belarus)",
"ru_KZ": "Russian (Kazakhstan)",
"ru_KG": "Russian (Kyrgyzstan)",
"ru_MD": "Russian (Moldova)",
"ru_RU": "Russian (Russia)",
"ru_UA": "Russian (Ukraine)",
"sg_CF": "Sango (Central African Republic)",
"gd_GB": "Scottish Gaelic (United Kingdom)",
"sr_BA": "Serbian (Bosnia & Herzegovina)",
"sr_Cyrl_BA": "Serbian (Cyrillic, Bosnia & Herzegovina)",
"sr_Cyrl_XK": "Serbian (Cyrillic, Kosovo)",
"sr_Cyrl_ME": "Serbian (Cyrillic, Montenegro)",
"sr_Cyrl_RS": "Serbian (Cyrillic, Serbia)",
"sr_Cyrl": "Serbian (Cyrillic)",
"sr_XK": "Serbian (Kosovo)",
"sr_Latn_BA": "Serbian (Latin, Bosnia & Herzegovina)",
"sr_Latn_XK": "Serbian (Latin, Kosovo)",
"sr_Latn_ME": "Serbian (Latin, Montenegro)",
"sr_Latn_RS": "Serbian (Latin, Serbia)",
"sr_Latn": "Serbian (Latin)",
"sr_ME": "Serbian (Montenegro)",
"sr_RS": "Serbian (Serbia)",
"sh_BA": "Serbo-Croatian (Bosnia & Herzegovina)",
"sn_ZW": "Shona (Zimbabwe)",
"ii_CN": "Sichuan Yi (China)",
"si_LK": "Sinhala (Sri Lanka)",
"sk_SK": "Slovak (Slovakia)",
"sl_SI": "Slovenian (Slovenia)",
"so_DJ": "Somali (Djibouti)",
"so_ET": "Somali (Ethiopia)",
"so_KE": "Somali (Kenya)",
"so_SO": "Somali (Somalia)",
"es_AR": "Spanish (Argentina)",
"es_BO": "Spanish (Bolivia)",
"es_IC": "Spanish (Canary Islands)",
"es_EA": "Spanish (Ceuta & Melilla)",
"es_CL": "Spanish (Chile)",
"es_CO": "Spanish (Colombia)",
"es_CR": "Spanish (Costa Rica)",
"es_CU": "Spanish (Cuba)",
"es_DO": "Spanish (Dominican Republic)",
"es_EC": "Spanish (Ecuador)",
"es_SV": "Spanish (El Salvador)",
"es_GQ": "Spanish (Equatorial Guinea)",
"es_GT": "Spanish (Guatemala)",
"es_HN": "Spanish (Honduras)",
"es_MX": "Spanish (Mexico)",
"es_NI": "Spanish (Nicaragua)",
"es_PA": "Spanish (Panama)",
"es_PY": "Spanish (Paraguay)",
"es_PE": "Spanish (Peru)",
"es_PH": "Spanish (Philippines)",
"es_PR": "Spanish (Puerto Rico)",
"es_ES": "Spanish (Spain)",
"es_US": "Spanish (United States)",
"es_UY": "Spanish (Uruguay)",
"es_VE": "Spanish (Venezuela)",
"sw_KE": "Swahili (Kenya)",
"sw_TZ": "Swahili (Tanzania)",
"sw_UG": "Swahili (Uganda)",
"sv_AX": "Swedish (\u00c5land Islands)",
"sv_FI": "Swedish (Finland)",
"sv_SE": "Swedish (Sweden)",
"tl_PH": "Tagalog (Philippines)",
"ta_IN": "Tamil (India)",
"ta_MY": "Tamil (Malaysia)",
"ta_SG": "Tamil (Singapore)",
"ta_LK": "Tamil (Sri Lanka)",
"te_IN": "Telugu (India)",
"th_TH": "Thai (Thailand)",
"bo_CN": "Tibetan (China)",
"bo_IN": "Tibetan (India)",
"ti_ER": "Tigrinya (Eritrea)",
"ti_ET": "Tigrinya (Ethiopia)",
"to_TO": "Tongan (Tonga)",
"tr_CY": "Turkish (Cyprus)",
"tr_TR": "Turkish (Turkey)",
"uk_UA": "Ukrainian (Ukraine)",
"ur_IN": "Urdu (India)",
"ur_PK": "Urdu (Pakistan)",
"ug_Arab_CN": "Uyghur (Arabic, China)",
"ug_Arab": "Uyghur (Arabic)",
"ug_CN": "Uyghur (China)",
"uz_AF": "Uzbek (Afghanistan)",
"uz_Arab_AF": "Uzbek (Arabic, Afghanistan)",
"uz_Arab": "Uzbek (Arabic)",
"uz_Cyrl_UZ": "Uzbek (Cyrillic, Uzbekistan)",
"uz_Cyrl": "Uzbek (Cyrillic)",
"uz_Latn_UZ": "Uzbek (Latin, Uzbekistan)",
"uz_Latn": "Uzbek (Latin)",
"uz_UZ": "Uzbek (Uzbekistan)",
"vi_VN": "Vietnamese (Vietnam)",
"cy_GB": "Welsh (United Kingdom)",
"fy_NL": "Western Frisian (Netherlands)",
"yo_BJ": "Yoruba (Benin)",
"yo_NG": "Yoruba (Nigeria)",
"zu_ZA": "Zulu (South Africa)"
}

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

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