Compare commits

...

219 Commits

Author SHA1 Message Date
James Cole
e00addc0b0 Merge branch 'release/v6.1.7' 2024-01-20 16:30:16 +01:00
James Cole
da7a2cf0c0 Update meta data for new release. 2024-01-20 16:29:00 +01:00
James Cole
2368788405 Fix issue with "createFromFormat". 2024-01-20 08:07:27 +01:00
James Cole
f603415931 Rebuild edit script. 2024-01-20 07:09:26 +01:00
James Cole
523fa42998 Merge branch 'main' into develop 2024-01-20 07:05:27 +01:00
James Cole
e449395f3f Clean up some code. 2024-01-20 07:04:19 +01:00
James Cole
d8d8002f1e Add some debug to non strict search 2024-01-20 06:53:43 +01:00
James Cole
2570ca9573 Fix account type filter 2024-01-20 06:53:30 +01:00
James Cole
e5fdc2cbfd Merge pull request #8429 from firefly-iii/dependabot/npm_and_yarn/vite-4.5.2
Bump vite from 4.5.1 to 4.5.2
2024-01-20 06:53:12 +01:00
dependabot[bot]
0349cdbc1b Bump vite from 4.5.1 to 4.5.2
Bumps [vite](https://github.com/vitejs/vite/tree/HEAD/packages/vite) from 4.5.1 to 4.5.2.
- [Release notes](https://github.com/vitejs/vite/releases)
- [Changelog](https://github.com/vitejs/vite/blob/v4.5.2/packages/vite/CHANGELOG.md)
- [Commits](https://github.com/vitejs/vite/commits/v4.5.2/packages/vite)

---
updated-dependencies:
- dependency-name: vite
  dependency-type: direct:development
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-01-20 05:39:48 +00:00
James Cole
122f0309a6 Fix #8425 2024-01-19 20:23:04 +01:00
James Cole
09bff5ea4e Fix https://github.com/firefly-iii/firefly-iii/issues/8418 2024-01-18 18:57:29 +01:00
James Cole
7ea112c5e7 Fix https://github.com/firefly-iii/firefly-iii/issues/8349 and 2024-01-18 18:57:23 +01:00
James Cole
44df07a5f5 Update, rebuild, and add a new API endpoint. 2024-01-17 20:23:02 +01:00
James Cole
66b0d9d309 Merge pull request #8394 from firefly-iii/dependabot/npm_and_yarn/develop/date-fns-3.2.0 2024-01-15 05:24:53 +01:00
dependabot[bot]
6ac3d3e62c Bump date-fns from 3.1.0 to 3.2.0
Bumps [date-fns](https://github.com/date-fns/date-fns) from 3.1.0 to 3.2.0.
- [Release notes](https://github.com/date-fns/date-fns/releases)
- [Changelog](https://github.com/date-fns/date-fns/blob/main/CHANGELOG.md)
- [Commits](https://github.com/date-fns/date-fns/compare/v3.1.0...v3.2.0)

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

Signed-off-by: dependabot[bot] <support@github.com>
2024-01-15 03:22:07 +00:00
James Cole
925450f84c Fix https://github.com/firefly-iii/firefly-iii/issues/8390 2024-01-14 13:59:09 +01:00
James Cole
62f59c6a19 Update packages 2024-01-14 13:58:16 +01:00
James Cole
7db21612a0 Escape backticks [skip ci] 2024-01-14 11:20:43 +01:00
James Cole
2c0da2cf26 Duh, single quotes [skip ci] 2024-01-14 11:19:47 +01:00
James Cole
79484cc194 Experimental action [skip ci] 2024-01-14 11:18:17 +01:00
James Cole
6f18748c72 Merge branch 'main' into develop 2024-01-14 07:16:21 +01:00
James Cole
577824930f Attempt at newline. 2024-01-14 07:15:08 +01:00
James Cole
d614519ee7 Add necessary params. 2024-01-14 07:12:47 +01:00
James Cole
ae31041f7f Add context 2024-01-14 07:11:39 +01:00
James Cole
62c4d0cf86 new command 2024-01-14 07:07:14 +01:00
James Cole
c2ddabbad2 Expand index. 2024-01-14 07:06:55 +01:00
James Cole
458402aaff Code cleanup. 2024-01-14 05:10:05 +01:00
James Cole
5c81e98218 Add list of transactions. 2024-01-13 20:34:09 +01:00
James Cole
37a46b02f4 Fix https://github.com/firefly-iii/firefly-iii/issues/8374 2024-01-13 08:13:25 +01:00
James Cole
b3e1ecdd02 Merge branch 'main' into develop 2024-01-13 08:13:10 +01:00
James Cole
1780e6dc61 Remove label step, no longer necessary. 2024-01-13 07:55:04 +01:00
James Cole
50f346d092 Add body to secret 2024-01-13 07:54:12 +01:00
James Cole
ccc851090a Manually add comment, lock and redirect user. 2024-01-13 07:50:43 +01:00
James Cole
4605d84cc8 Add more permissions 2024-01-13 07:41:15 +01:00
James Cole
8c7ab50325 Add the action manually. 2024-01-13 07:40:01 +01:00
James Cole
908539836b Use correct string name. 2024-01-13 07:38:21 +01:00
James Cole
9f71cf966c Remove the old step. 2024-01-13 07:36:55 +01:00
James Cole
02ed47c578 Update job. Do it manually. 2024-01-13 07:36:09 +01:00
James Cole
1ddbaf0884 Merge branch 'main' into develop 2024-01-13 07:24:23 +01:00
James Cole
d3ed8c6f0f New action for issues. 2024-01-13 07:24:11 +01:00
James Cole
4f1ac2ac6f Minor code cleanup 2024-01-12 19:03:51 +01:00
James Cole
1e733f4c8b Fix https://github.com/firefly-iii/firefly-iii/issues/8377 2024-01-12 18:57:38 +01:00
James Cole
8e2546da9d Update translations. 2024-01-10 20:29:00 +01:00
James Cole
3a8162d3c5 Add button for https://github.com/firefly-iii/firefly-iii/issues/8369 2024-01-10 05:34:20 +01:00
James Cole
f7ceb75316 Merge pull request #8370 from luzpaz/typos
Fix various typos
2024-01-10 05:31:16 +01:00
luzpaz
744e193faa Fix various typos
Found via `codespell -q 3 -S "./resources/lang,./resources/assets/js/locales" -L hastable`
2024-01-10 01:12:48 +00:00
James Cole
12b0e11592 From error to debug. 2024-01-09 21:05:17 +01:00
James Cole
717f3a9e3d From info to debug 2024-01-09 21:04:12 +01:00
James Cole
b9f0682f04 Add audit entries. 2024-01-09 21:03:26 +01:00
James Cole
8792465fd5 Add validation warnings in audit logs. 2024-01-09 20:58:18 +01:00
James Cole
6fbf9a119d Change priority on audit messages. 2024-01-09 20:48:17 +01:00
James Cole
0dfa21a92e Merge branch 'main' into develop 2024-01-08 20:39:02 +01:00
James Cole
136fe8e8eb Update label-actions.yml
Signed-off-by: James Cole <james@firefly-iii.org>
2024-01-08 20:32:31 +01:00
James Cole
d510c4e31d Rebuild frontend v2 2024-01-08 20:31:35 +01:00
James Cole
c066bcc4ce Update label-actions.yml
Signed-off-by: James Cole <james@firefly-iii.org>
2024-01-08 20:30:47 +01:00
James Cole
c9e7ae1f08 Update label-actions.yml
Signed-off-by: James Cole <james@firefly-iii.org>
2024-01-08 20:25:25 +01:00
James Cole
6a9b4f4d55 Update label-actions.yml
Signed-off-by: James Cole <james@firefly-iii.org>
2024-01-08 20:20:22 +01:00
James Cole
2b5054b905 Merge branch 'develop' of github.com:firefly-iii/firefly-iii into develop 2024-01-08 20:11:39 +01:00
James Cole
0a45a2485b Small edit and show updates 2024-01-08 20:11:27 +01:00
James Cole
fcc0294d07 Smaller max size 2024-01-08 12:56:57 +01:00
James Cole
ad981c2bf0 Fix breadcrumb bg color. 2024-01-07 19:55:56 +01:00
James Cole
75a32b2f94 Expand v2 layout with experimental view. 2024-01-07 12:51:42 +01:00
James Cole
70b60f756b Rebuild frontend [skip ci] 2024-01-07 07:02:53 +01:00
James Cole
0d2ae8ae23 Clean up languages [skip ci] 2024-01-07 07:02:28 +01:00
James Cole
8043c86942 Update readme. 2024-01-06 19:22:38 +01:00
James Cole
4c30a7bc55 Expand edit form. 2024-01-06 17:24:54 +01:00
James Cole
f615b9c252 Fix https://github.com/firefly-iii/firefly-iii/issues/8352 2024-01-06 14:44:50 +01:00
James Cole
c19b36a391 Fix https://github.com/firefly-iii/firefly-iii/issues/8352 2024-01-06 14:40:06 +01:00
James Cole
935634e487 Sanity check on number. 2024-01-06 14:23:20 +01:00
James Cole
2c3f032a2b Merge branch 'release/v6.1.6' 2024-01-06 11:13:41 +01:00
James Cole
7e62b75b12 Merge tag 'v6.1.6' into develop
v6.1.6
2024-01-06 11:13:41 +01:00
James Cole
de57ab0874 Update meta files for new release. 2024-01-06 11:11:18 +01:00
James Cole
6fb4aaecd3 Fix a very dumb bug. 2024-01-06 11:09:40 +01:00
James Cole
45fdbf5a11 Merge tag 'v6.1.5' into develop
v6.1.5
2024-01-06 10:59:05 +01:00
James Cole
c6615a7b17 Merge branch 'release/v6.1.5' 2024-01-06 10:59:02 +01:00
James Cole
0efb3d2dcf Fix currency validation. 2024-01-06 08:33:38 +01:00
James Cole
b8a58f83ee New packages. 2024-01-06 07:59:46 +01:00
James Cole
110228e65e Fix phpstan issue. 2024-01-06 07:49:50 +01:00
James Cole
8ad27e0eda Update meta files for new release. 2024-01-06 07:42:00 +01:00
James Cole
2e0d90c685 Expand edit transaction form. 2024-01-06 07:26:03 +01:00
James Cole
bd2ecb13b8 Change time for rule. 2024-01-05 18:09:19 +01:00
James Cole
5725570dbb Add marker. Seems fastest solution. 2024-01-05 14:47:44 +01:00
James Cole
11f77685e4 Experimental code cleanup. 2024-01-05 14:29:59 +01:00
James Cole
0521c46d27 test 2024-01-05 14:15:26 +01:00
James Cole
50d6225590 test 2024-01-05 14:15:02 +01:00
James Cole
df55f7de79 test 2024-01-05 14:13:44 +01:00
James Cole
5152ae9622 test 2024-01-05 14:11:06 +01:00
James Cole
075d0da63d test 2024-01-05 14:10:07 +01:00
James Cole
d804df2a2f test 2024-01-05 14:09:47 +01:00
James Cole
ff0f8beb81 Of course phpstan has an opinion on this lol 2024-01-05 14:07:13 +01:00
James Cole
c00be92f97 Finalize create transaction form. 2024-01-05 14:04:44 +01:00
James Cole
88f6221424 Small code fix. 2024-01-05 11:09:52 +01:00
James Cole
f9463e02a2 Fix null pointer 2024-01-05 10:55:46 +01:00
James Cole
25a23801be Fix error mail 2024-01-05 10:55:07 +01:00
James Cole
fe7bb02dc5 Clean up min/max sizes of requests. 2024-01-05 09:48:59 +01:00
James Cole
68edcfc4e8 Clean up files and add alias 2024-01-05 08:12:17 +01:00
James Cole
5f8a24a684 Add newline. 2024-01-04 15:43:51 +01:00
James Cole
0a5d62605a Code cleanup and new translations. 2024-01-04 15:42:00 +01:00
James Cole
1873be8d95 Merge branch 'develop' of github.com:firefly-iii/firefly-iii into develop 2024-01-04 15:41:18 +01:00
James Cole
01892c3828 Merge pull request #8348 from lemuelroberto/develop
Update outdated documentation URLs in .env.example
2024-01-04 15:41:00 +01:00
Lemuel Roberto Bonifácio
b87e60c72f Update outdated documentation URLs in .env.example 2024-01-04 11:32:36 -03:00
James Cole
3a083f88b5 Clean up code. 2024-01-04 14:59:55 +01:00
James Cole
566bb2f097 Expand create transaction form. 2024-01-04 14:59:37 +01:00
James Cole
1ba7847d84 Add more details in message. 2024-01-04 11:46:23 +01:00
James Cole
c32044a8eb Smaller notes 2024-01-04 11:41:03 +01:00
James Cole
72a2d417af Change log levels. 2024-01-04 08:35:58 +01:00
James Cole
09c18d6d44 More audit logs. 2024-01-04 08:34:57 +01:00
James Cole
84ae6a633e Add some audit logs. 2024-01-04 08:32:42 +01:00
James Cole
82749cea07 Sanity check in date. 2024-01-04 07:51:37 +01:00
James Cole
23aa0e3ba3 Add some audit log info. 2024-01-04 07:48:51 +01:00
James Cole
8be27a2201 Small code cleanup 2024-01-04 07:44:52 +01:00
James Cole
ff98f3cc3e Expand create transaction form. 2024-01-04 07:26:45 +01:00
James Cole
01c4d25646 Better currency validation for foreign amount 2024-01-04 07:26:12 +01:00
James Cole
292b9ac9d0 Fix wording for https://github.com/firefly-iii/firefly-iii/issues/8328 2024-01-04 07:25:24 +01:00
James Cole
6bdae03961 Extra fix for https://github.com/firefly-iii/firefly-iii/issues/8328 2024-01-04 06:22:47 +01:00
James Cole
7426c6aac3 Split form in parts, add "edit" page. 2024-01-03 19:34:50 +01:00
James Cole
211526c032 Expand new transaction form. 2024-01-03 17:43:05 +01:00
James Cole
e6fe08dd61 Update translations. 2024-01-03 13:05:54 +01:00
James Cole
7bba67130a Merge pull request #8335 from maureenferreira/patch-2
Update intro.php
2024-01-03 07:28:43 +00:00
maureenferreira
7186d8ddfd Update intro.php
Signed-off-by: maureenferreira <142938968+maureenferreira@users.noreply.github.com>
2024-01-03 00:19:18 -06:00
James Cole
1a6bc6decd Merge branch 'release/v6.1.4' 2024-01-02 22:29:55 +01:00
James Cole
5b11c86113 Merge tag 'v6.1.4' into develop
v6.1.4
2024-01-02 22:29:55 +01:00
James Cole
98b95ab891 Fix issue #8328 2024-01-02 22:28:58 +01:00
James Cole
c3068d10bf Merge tag 'v6.1.3' into develop
v6.1.3
2024-01-02 21:23:34 +01:00
James Cole
fa1a1b084b Merge branch 'release/v6.1.3' 2024-01-02 21:23:33 +01:00
James Cole
387e44b8b9 Update changelog. 2024-01-02 21:23:14 +01:00
James Cole
6dafa89a15 Fix https://github.com/firefly-iii/firefly-iii/issues/8326 2024-01-02 21:22:42 +01:00
James Cole
5b5b8008b0 Merge tag 'v6.1.2' into develop
v6.1.2
2024-01-02 20:26:54 +01:00
James Cole
38a955e663 Merge branch 'release/v6.1.2' 2024-01-02 20:26:52 +01:00
James Cole
62921df702 cleanup changelog 2024-01-02 20:24:31 +01:00
James Cole
c7c2b85882 Update packages. 2024-01-02 20:23:39 +01:00
James Cole
bc26ee5cde Code for new release. 2024-01-02 20:19:09 +01:00
James Cole
9eca31529c Fix https://github.com/firefly-iii/firefly-iii/issues/8322 2024-01-02 16:47:54 +01:00
James Cole
25e3abeeb8 Fix https://github.com/firefly-iii/firefly-iii/issues/8320 2024-01-02 16:29:47 +01:00
James Cole
53d6281ba4 Fix https://github.com/firefly-iii/firefly-iii/issues/8320 2024-01-02 15:52:56 +01:00
James Cole
4b9fd949ad Fix https://github.com/firefly-iii/firefly-iii/issues/8321 2024-01-02 15:51:34 +01:00
James Cole
786b4c18a1 Other minification. 2024-01-02 15:41:14 +01:00
James Cole
97b65ac44c Temporary log level elevation. 2024-01-02 14:37:56 +01:00
James Cole
102da7b21e New numerical validation. 2024-01-02 14:33:17 +01:00
James Cole
85bde79fd1 Fix issue validating budget amounts. 2024-01-02 07:08:15 +01:00
James Cole
09a25957d0 Switch to mime. 2024-01-01 16:58:00 +01:00
James Cole
fd7a2181a4 Code cleanup 2024-01-01 15:51:23 +01:00
James Cole
2ede3b420b Base64 encode logs 2024-01-01 15:24:15 +01:00
James Cole
4bed30347d Report uploads 2024-01-01 15:19:20 +01:00
James Cole
ffdcab3220 Report uploads 2024-01-01 15:18:09 +01:00
James Cole
956108399b Various code cleanup and fixed alignments. 2024-01-01 15:17:11 +01:00
James Cole
61c38f2a99 Various code cleanup and fixed alignments. 2024-01-01 14:48:04 +01:00
James Cole
f3773ebfc2 Various code cleanup and fixed alignments. 2024-01-01 14:45:51 +01:00
James Cole
f963ac63f1 Various code cleanup and fixed alignments. 2024-01-01 14:43:56 +01:00
James Cole
1368aafe5f Various code cleanup and fixed alignments. 2024-01-01 14:42:24 +01:00
James Cole
657262f179 Various code cleanup and fixed alignments. 2024-01-01 14:41:31 +01:00
James Cole
8b9dce70bb Various code cleanup and fixed alignments. 2024-01-01 14:38:01 +01:00
James Cole
30bbd0b3a4 Various code cleanup and fixed alignments. 2024-01-01 14:36:31 +01:00
James Cole
d4488f041b Some alignment 2024-01-01 14:35:00 +01:00
James Cole
fa8dc1ae4b Fix bad validation in variable. 2024-01-01 14:13:49 +01:00
James Cole
c2b60edca3 Fix bad validation in variable. 2024-01-01 14:13:06 +01:00
James Cole
949ca4f79e Fix issue with tag search. 2024-01-01 11:31:14 +01:00
James Cole
ab0b03dd14 Audit validation errors. 2024-01-01 10:15:19 +01:00
James Cole
5b41e58025 Add some audit debug. 2024-01-01 10:12:47 +01:00
James Cole
88bf76fa27 Add some audit things. 2024-01-01 10:06:44 +01:00
James Cole
3ad155882a Nice disable warning. 2024-01-01 09:46:13 +01:00
James Cole
4747e28621 Disable old upgrade command. 2024-01-01 09:45:21 +01:00
James Cole
5664695a92 Various code changes. 2024-01-01 08:17:15 +01:00
James Cole
fdcd31652a Fix limits 2024-01-01 07:24:17 +01:00
James Cole
e5397b6659 Merge pull request #8314 from firefly-iii/dependabot/npm_and_yarn/develop/axios-1.6.3 2024-01-01 07:11:53 +01:00
James Cole
51e5b9a994 Merge pull request #8313 from firefly-iii/dependabot/npm_and_yarn/develop/sass-1.69.6 2024-01-01 07:11:42 +01:00
James Cole
dc95632834 Merge pull request #8312 from firefly-iii/dependabot/composer/develop/symfony/http-client-7.0.2 2024-01-01 07:11:02 +01:00
dependabot[bot]
3e888382c9 chore(deps-dev): bump axios from 1.6.2 to 1.6.3
Bumps [axios](https://github.com/axios/axios) from 1.6.2 to 1.6.3.
- [Release notes](https://github.com/axios/axios/releases)
- [Changelog](https://github.com/axios/axios/blob/v1.x/CHANGELOG.md)
- [Commits](https://github.com/axios/axios/compare/v1.6.2...v1.6.3)

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

Signed-off-by: dependabot[bot] <support@github.com>
2024-01-01 03:54:25 +00:00
dependabot[bot]
de8d6f8439 chore(deps-dev): bump sass from 1.69.5 to 1.69.6
Bumps [sass](https://github.com/sass/dart-sass) from 1.69.5 to 1.69.6.
- [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.69.5...1.69.6)

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

Signed-off-by: dependabot[bot] <support@github.com>
2024-01-01 03:54:09 +00:00
dependabot[bot]
60543b8f1d chore(deps): bump symfony/http-client from 7.0.0 to 7.0.2
Bumps [symfony/http-client](https://github.com/symfony/http-client) from 7.0.0 to 7.0.2.
- [Release notes](https://github.com/symfony/http-client/releases)
- [Changelog](https://github.com/symfony/http-client/blob/7.0/CHANGELOG.md)
- [Commits](https://github.com/symfony/http-client/compare/v7.0.0...v7.0.2)

---
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-01-01 03:05:43 +00:00
James Cole
268cec6d08 Must be above zero. 2023-12-31 18:00:55 +01:00
James Cole
94aea91927 Add audit data 2023-12-31 17:58:02 +01:00
James Cole
135a6993aa Fix tag length 2023-12-31 17:40:57 +01:00
James Cole
16079f496a Remove tag length. 2023-12-31 17:38:41 +01:00
James Cole
e318e8e9cf Catch amounts. 2023-12-31 17:29:00 +01:00
James Cole
51ca8277bb Fix amount thing. 2023-12-31 17:18:54 +01:00
James Cole
a49cf1fd3d Check submission sizes. 2023-12-31 06:20:29 +01:00
James Cole
81a11ee5b4 Size filter for large notes. 2023-12-31 06:09:36 +01:00
James Cole
b778424b7e Fix markdown links. 2023-12-30 19:42:10 +01:00
James Cole
d408d7cc20 Fix bad index 2023-12-30 16:22:13 +01:00
James Cole
228870ceac Code and API cleanup. 2023-12-30 14:39:44 +01:00
James Cole
ae1939cd1b Add some missing methods. 2023-12-30 13:31:13 +01:00
James Cole
f7a4bd5d12 Link 2023-12-30 13:10:42 +01:00
James Cole
eec1888f87 Add button but indicate it's disabled. 2023-12-30 13:10:06 +01:00
James Cole
a42470e5b4 Remove webhooks. 2023-12-30 13:08:00 +01:00
James Cole
098f1fe0f6 Suppress warning for method 2023-12-30 12:59:09 +01:00
James Cole
2e5bc750d1 Disable attachment API for demo users 2023-12-30 12:54:21 +01:00
James Cole
d777a1f2b8 Add audit log entries. 2023-12-30 10:14:35 +01:00
James Cole
5178e19cea Clean up code, clarify 404. 2023-12-30 09:56:03 +01:00
James Cole
be8aaa68af Fix some sums. 2023-12-29 20:50:03 +01:00
James Cole
1e31a1184a Skip non-existing tags. 2023-12-29 20:41:54 +01:00
James Cole
c269be7f07 Skip irrelevant tags. 2023-12-29 20:39:49 +01:00
James Cole
6bf42ba237 No tag. 2023-12-29 20:37:47 +01:00
James Cole
1901648a05 Clean up and add some debug info. 2023-12-29 20:33:39 +01:00
James Cole
789a6cebcd Fix bad route. 2023-12-29 20:27:16 +01:00
James Cole
4230349c07 Fix https://github.com/firefly-iii/firefly-iii/issues/8304 2023-12-29 20:25:32 +01:00
James Cole
33b95b9371 Catch some amounts 2023-12-29 19:59:19 +01:00
James Cole
e47110607c Small change in audit logger [skip ci] 2023-12-29 12:09:06 +01:00
James Cole
1e3665e54f Make log message debug level [skip ci] 2023-12-29 12:07:09 +01:00
James Cole
47147066d2 Add audit things. 2023-12-29 12:06:23 +01:00
James Cole
5b8f67e992 Change loglevel to debug again. 2023-12-29 12:00:15 +01:00
James Cole
fb1a66d872 Fix translations. 2023-12-29 10:19:12 +01:00
James Cole
e594b9304a Fix bad if/then. 2023-12-29 09:16:13 +01:00
James Cole
0d7fd36c38 Catch division by zero. 2023-12-29 09:05:44 +01:00
James Cole
bdba786322 Fix bad conversion 2023-12-29 09:02:49 +01:00
James Cole
507e0fb54c Catch query things. 2023-12-29 09:01:42 +01:00
James Cole
e4d91aa337 Disable API endpoints. 2023-12-29 08:42:03 +01:00
James Cole
4e6fc8e2a2 Remove most debug info. 2023-12-29 08:39:15 +01:00
James Cole
244ffb2450 Start throwing 404's 2023-12-29 08:35:54 +01:00
James Cole
7aa3aef508 Even more debug 2023-12-29 08:30:50 +01:00
James Cole
c16f7d214f More debug info. 2023-12-29 08:25:01 +01:00
James Cole
c08d44ea48 Add some debug info. 2023-12-29 08:21:14 +01:00
James Cole
6381d04e2b Add lots of audit logs. 2023-12-29 08:19:04 +01:00
James Cole
ec43d10e35 Max size for notes. 2023-12-28 10:35:35 +01:00
James Cole
b32d9aab34 Dumb nullpointer 2023-12-27 20:11:50 +01:00
James Cole
de5cb4c165 Catch division by zero. https://github.com/firefly-iii/firefly-iii/issues/8297 2023-12-27 19:36:28 +01:00
James Cole
609edb9dff Add basic catch for big date ranges. 2023-12-27 15:48:04 +01:00
James Cole
636b3921fa Merge tag 'v6.1.1' into develop
v6.1.1
2023-12-26 11:37:22 +01:00
1213 changed files with 82883 additions and 75334 deletions

27
.ci/all.sh Executable file
View File

@@ -0,0 +1,27 @@
#!/usr/bin/env bash
#
# all.sh
# 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/>.
#
SCRIPT_DIR="$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )"
$SCRIPT_DIR/phpcs.sh
$SCRIPT_DIR/phpstan.sh
$SCRIPT_DIR/phpmd.sh

View File

@@ -57,7 +57,14 @@ return $config->setRules([
'statement_indentation' => true,
'type_declaration_spaces' => false,
'cast_spaces' => false,
'binary_operator_spaces' => false,
'binary_operator_spaces' => [
'default' => 'at_least_single_space',
'operators' => [
'=>' => 'align_single_space_by_scope',
'=' => 'align_single_space_minimal_by_scope',
'??=' => 'align_single_space_minimal_by_scope',
],
],
'void_return' => true,
])
->setFinder($finder);

View File

@@ -226,21 +226,22 @@
},
{
"name": "friendsofphp/php-cs-fixer",
"version": "v3.42.0",
"version": "v3.48.0",
"source": {
"type": "git",
"url": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer.git",
"reference": "632ef1be3447a9b890bef06147475facee535d0f"
"reference": "a92472c6fb66349de25211f31c77eceae3df024e"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/PHP-CS-Fixer/PHP-CS-Fixer/zipball/632ef1be3447a9b890bef06147475facee535d0f",
"reference": "632ef1be3447a9b890bef06147475facee535d0f",
"url": "https://api.github.com/repos/PHP-CS-Fixer/PHP-CS-Fixer/zipball/a92472c6fb66349de25211f31c77eceae3df024e",
"reference": "a92472c6fb66349de25211f31c77eceae3df024e",
"shasum": ""
},
"require": {
"composer/semver": "^3.4",
"composer/xdebug-handler": "^3.0.3",
"ext-filter": "*",
"ext-json": "*",
"ext-tokenizer": "*",
"php": "^7.4 || ^8.0",
@@ -265,7 +266,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",
"phpunit/phpunit": "^9.6 || ^10.5.5",
"symfony/yaml": "^5.4 || ^6.0 || ^7.0"
},
"suggest": {
@@ -304,7 +305,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.42.0"
"source": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/tree/v3.48.0"
},
"funding": [
{
@@ -312,7 +313,7 @@
"type": "github"
}
],
"time": "2023-12-24T14:38:51+00:00"
"time": "2024-01-19T21:44:39+00:00"
},
{
"name": "psr/container",
@@ -536,16 +537,16 @@
},
{
"name": "symfony/console",
"version": "v7.0.1",
"version": "v7.0.2",
"source": {
"type": "git",
"url": "https://github.com/symfony/console.git",
"reference": "cdce5c684b2f920bb1343deecdfba356ffad83d5"
"reference": "f8587c4cdc5acad67af71c37db34ef03af91e59c"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/console/zipball/cdce5c684b2f920bb1343deecdfba356ffad83d5",
"reference": "cdce5c684b2f920bb1343deecdfba356ffad83d5",
"url": "https://api.github.com/repos/symfony/console/zipball/f8587c4cdc5acad67af71c37db34ef03af91e59c",
"reference": "f8587c4cdc5acad67af71c37db34ef03af91e59c",
"shasum": ""
},
"require": {
@@ -609,7 +610,7 @@
"terminal"
],
"support": {
"source": "https://github.com/symfony/console/tree/v7.0.1"
"source": "https://github.com/symfony/console/tree/v7.0.2"
},
"funding": [
{
@@ -625,7 +626,7 @@
"type": "tidelift"
}
],
"time": "2023-12-01T15:10:06+00:00"
"time": "2023-12-10T16:54:46+00:00"
},
{
"name": "symfony/deprecation-contracts",
@@ -696,16 +697,16 @@
},
{
"name": "symfony/event-dispatcher",
"version": "v7.0.0",
"version": "v7.0.2",
"source": {
"type": "git",
"url": "https://github.com/symfony/event-dispatcher.git",
"reference": "c459b40ffe67c49af6fd392aac374c9edf8a027e"
"reference": "098b62ae81fdd6cbf941f355059f617db28f4f9a"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/c459b40ffe67c49af6fd392aac374c9edf8a027e",
"reference": "c459b40ffe67c49af6fd392aac374c9edf8a027e",
"url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/098b62ae81fdd6cbf941f355059f617db28f4f9a",
"reference": "098b62ae81fdd6cbf941f355059f617db28f4f9a",
"shasum": ""
},
"require": {
@@ -756,7 +757,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.0"
"source": "https://github.com/symfony/event-dispatcher/tree/v7.0.2"
},
"funding": [
{
@@ -772,7 +773,7 @@
"type": "tidelift"
}
],
"time": "2023-07-27T16:29:09+00:00"
"time": "2023-12-27T22:24:19+00:00"
},
{
"name": "symfony/event-dispatcher-contracts",
@@ -1538,16 +1539,16 @@
},
{
"name": "symfony/process",
"version": "v7.0.0",
"version": "v7.0.2",
"source": {
"type": "git",
"url": "https://github.com/symfony/process.git",
"reference": "13bdb1670c7f510494e04fcb2bfa29af63db9c0d"
"reference": "acd3eb5cb02382c1cb0287ba29b2908cc6ffa83a"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/process/zipball/13bdb1670c7f510494e04fcb2bfa29af63db9c0d",
"reference": "13bdb1670c7f510494e04fcb2bfa29af63db9c0d",
"url": "https://api.github.com/repos/symfony/process/zipball/acd3eb5cb02382c1cb0287ba29b2908cc6ffa83a",
"reference": "acd3eb5cb02382c1cb0287ba29b2908cc6ffa83a",
"shasum": ""
},
"require": {
@@ -1579,7 +1580,7 @@
"description": "Executes commands in sub-processes",
"homepage": "https://symfony.com",
"support": {
"source": "https://github.com/symfony/process/tree/v7.0.0"
"source": "https://github.com/symfony/process/tree/v7.0.2"
},
"funding": [
{
@@ -1595,25 +1596,25 @@
"type": "tidelift"
}
],
"time": "2023-11-20T16:43:42+00:00"
"time": "2023-12-24T09:15:37+00:00"
},
{
"name": "symfony/service-contracts",
"version": "v3.4.0",
"version": "v3.4.1",
"source": {
"type": "git",
"url": "https://github.com/symfony/service-contracts.git",
"reference": "b3313c2dbffaf71c8de2934e2ea56ed2291a3838"
"reference": "fe07cbc8d837f60caf7018068e350cc5163681a0"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/service-contracts/zipball/b3313c2dbffaf71c8de2934e2ea56ed2291a3838",
"reference": "b3313c2dbffaf71c8de2934e2ea56ed2291a3838",
"url": "https://api.github.com/repos/symfony/service-contracts/zipball/fe07cbc8d837f60caf7018068e350cc5163681a0",
"reference": "fe07cbc8d837f60caf7018068e350cc5163681a0",
"shasum": ""
},
"require": {
"php": ">=8.1",
"psr/container": "^2.0"
"psr/container": "^1.1|^2.0"
},
"conflict": {
"ext-psr": "<1.1|>=2"
@@ -1661,7 +1662,7 @@
"standards"
],
"support": {
"source": "https://github.com/symfony/service-contracts/tree/v3.4.0"
"source": "https://github.com/symfony/service-contracts/tree/v3.4.1"
},
"funding": [
{
@@ -1677,7 +1678,7 @@
"type": "tidelift"
}
],
"time": "2023-07-30T20:28:31+00:00"
"time": "2023-12-26T14:02:43+00:00"
},
{
"name": "symfony/stopwatch",
@@ -1743,16 +1744,16 @@
},
{
"name": "symfony/string",
"version": "v7.0.0",
"version": "v7.0.2",
"source": {
"type": "git",
"url": "https://github.com/symfony/string.git",
"reference": "92bd2bfbba476d4a1838e5e12168bef2fd1e6620"
"reference": "cc78f14f91f5e53b42044d0620961c48028ff9f5"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/string/zipball/92bd2bfbba476d4a1838e5e12168bef2fd1e6620",
"reference": "92bd2bfbba476d4a1838e5e12168bef2fd1e6620",
"url": "https://api.github.com/repos/symfony/string/zipball/cc78f14f91f5e53b42044d0620961c48028ff9f5",
"reference": "cc78f14f91f5e53b42044d0620961c48028ff9f5",
"shasum": ""
},
"require": {
@@ -1809,7 +1810,7 @@
"utf8"
],
"support": {
"source": "https://github.com/symfony/string/tree/v7.0.0"
"source": "https://github.com/symfony/string/tree/v7.0.2"
},
"funding": [
{
@@ -1825,7 +1826,7 @@
"type": "tidelift"
}
],
"time": "2023-11-29T08:40:23+00:00"
"time": "2023-12-10T16:54:46+00:00"
}
],
"packages-dev": [],

View File

@@ -470,16 +470,16 @@
},
{
"name": "symfony/dependency-injection",
"version": "v7.0.1",
"version": "v7.0.2",
"source": {
"type": "git",
"url": "https://github.com/symfony/dependency-injection.git",
"reference": "f6667642954bce638733f254c39e5b5700b47ba4"
"reference": "bd25ef7c937b9da12510bdc4f1c66728f19620e3"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/dependency-injection/zipball/f6667642954bce638733f254c39e5b5700b47ba4",
"reference": "f6667642954bce638733f254c39e5b5700b47ba4",
"url": "https://api.github.com/repos/symfony/dependency-injection/zipball/bd25ef7c937b9da12510bdc4f1c66728f19620e3",
"reference": "bd25ef7c937b9da12510bdc4f1c66728f19620e3",
"shasum": ""
},
"require": {
@@ -530,7 +530,7 @@
"description": "Allows you to standardize and centralize the way objects are constructed in your application",
"homepage": "https://symfony.com",
"support": {
"source": "https://github.com/symfony/dependency-injection/tree/v7.0.1"
"source": "https://github.com/symfony/dependency-injection/tree/v7.0.2"
},
"funding": [
{
@@ -546,7 +546,7 @@
"type": "tidelift"
}
],
"time": "2023-12-01T15:10:06+00:00"
"time": "2023-12-28T19:18:20+00:00"
},
{
"name": "symfony/deprecation-contracts",
@@ -845,21 +845,21 @@
},
{
"name": "symfony/service-contracts",
"version": "v3.4.0",
"version": "v3.4.1",
"source": {
"type": "git",
"url": "https://github.com/symfony/service-contracts.git",
"reference": "b3313c2dbffaf71c8de2934e2ea56ed2291a3838"
"reference": "fe07cbc8d837f60caf7018068e350cc5163681a0"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/service-contracts/zipball/b3313c2dbffaf71c8de2934e2ea56ed2291a3838",
"reference": "b3313c2dbffaf71c8de2934e2ea56ed2291a3838",
"url": "https://api.github.com/repos/symfony/service-contracts/zipball/fe07cbc8d837f60caf7018068e350cc5163681a0",
"reference": "fe07cbc8d837f60caf7018068e350cc5163681a0",
"shasum": ""
},
"require": {
"php": ">=8.1",
"psr/container": "^2.0"
"psr/container": "^1.1|^2.0"
},
"conflict": {
"ext-psr": "<1.1|>=2"
@@ -907,7 +907,7 @@
"standards"
],
"support": {
"source": "https://github.com/symfony/service-contracts/tree/v3.4.0"
"source": "https://github.com/symfony/service-contracts/tree/v3.4.1"
},
"funding": [
{
@@ -923,20 +923,20 @@
"type": "tidelift"
}
],
"time": "2023-07-30T20:28:31+00:00"
"time": "2023-12-26T14:02:43+00:00"
},
{
"name": "symfony/var-exporter",
"version": "v7.0.1",
"version": "v7.0.2",
"source": {
"type": "git",
"url": "https://github.com/symfony/var-exporter.git",
"reference": "a3d7c877414fcd59ab7075ecdc3b8f9c00f7bcc3"
"reference": "345c62fefe92243c3a06fc0cc65f2ec1a47e0764"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/var-exporter/zipball/a3d7c877414fcd59ab7075ecdc3b8f9c00f7bcc3",
"reference": "a3d7c877414fcd59ab7075ecdc3b8f9c00f7bcc3",
"url": "https://api.github.com/repos/symfony/var-exporter/zipball/345c62fefe92243c3a06fc0cc65f2ec1a47e0764",
"reference": "345c62fefe92243c3a06fc0cc65f2ec1a47e0764",
"shasum": ""
},
"require": {
@@ -981,7 +981,7 @@
"serialize"
],
"support": {
"source": "https://github.com/symfony/var-exporter/tree/v7.0.1"
"source": "https://github.com/symfony/var-exporter/tree/v7.0.2"
},
"funding": [
{
@@ -997,7 +997,7 @@
"type": "tidelift"
}
],
"time": "2023-11-30T11:38:21+00:00"
"time": "2023-12-27T08:42:13+00:00"
}
],
"aliases": [],

View File

@@ -78,7 +78,7 @@ PAPERTRAIL_HOST=
PAPERTRAIL_PORT=
# Database credentials. Make sure the database exists. I recommend a dedicated user for Firefly III
# For other database types, please see the FAQ: https://docs.firefly-iii.org/firefly-iii/faq/self-hosted/#i-want-to-use-sqlite
# For other database types, please see the FAQ: https://docs.firefly-iii.org/references/faq/install/#i-want-to-use-sqlite
# If you use Docker or similar, you can set these variables from a file by appending them with _FILE
# Use "pgsql" for PostgreSQL
# Use "mysql" for MySQL and MariaDB.
@@ -122,7 +122,7 @@ SESSION_DRIVER=file
# If you use Docker or similar, you can set REDIS_HOST_FILE, REDIS_PASSWORD_FILE or
# REDIS_PORT_FILE to set the value from a file instead of from an environment variable
# can be tcp, unix or http
# can be tcp or unix. http is not supported
REDIS_SCHEME=tcp
# use only when using 'unix' for REDIS_SCHEME. Leave empty otherwise.
@@ -150,7 +150,7 @@ COOKIE_SECURE=false
COOKIE_SAMESITE=lax
# If you want Firefly III to email you, update these settings
# For instructions, see: https://docs.firefly-iii.org/firefly-iii/advanced-installation/email/#email
# For instructions, see: https://docs.firefly-iii.org/how-to/firefly-iii/advanced/notifications/#email
# If you use Docker or similar, you can set these variables from a file by appending them with _FILE
MAIL_MAILER=log
MAIL_HOST=null
@@ -214,7 +214,7 @@ VALID_URL_PROTOCOLS=
# - 'web' (default, uses built in DB)
# - 'remote_user_guard' for Authelia etc
# Read more about these settings in the documentation.
# https://docs.firefly-iii.org/firefly-iii/advanced-installation/authentication
# https://docs.firefly-iii.org/how-to/firefly-iii/advanced/authentication/
#
# LDAP is no longer supported :(
#
@@ -269,7 +269,7 @@ ALLOW_WEBHOOKS=false
# 1. Set this token to any 32-character value (this is important!).
# 2. Use this token in the cron URL instead of a user's command line token that you can find in /profile
#
# For more info: https://docs.firefly-iii.org/firefly-iii/advanced-installation/cron/
# For more info: https://docs.firefly-iii.org/how-to/firefly-iii/advanced/cron/
#
# You can set this variable from a file by appending it with _FILE
#

View File

@@ -8,7 +8,7 @@ body:
options:
- label: I've read the [support guidelines](https://github.com/firefly-iii/firefly-iii/blob/main/.github/support.md)
required: true
- label: My request is not listed as [a very good idea, but unfortunately...](https://docs.firefly-iii.org/firefly-iii/more-information/what-its-not/)
- label: My request is not listed as [a very good idea, but unfortunately...](https://docs.firefly-iii.org/explanation/more-information/what-its-not/)
required: true
- label: I've used [the search](https://github.com/firefly-iii/firefly-iii/issues?q=is%3Aissue) and this has not been requested before.
required: true

View File

@@ -1,3 +1,3 @@
# [Contributing guidelines](https://docs.firefly-iii.org/firefly-iii/support/#contributing-code)
# [Contributing guidelines](https://docs.firefly-iii.org/explanation/support/#contributing-code)
[Contributing guidelines](https://docs.firefly-iii.org/firefly-iii/support/#contributing-code)
[Contributing guidelines](https://docs.firefly-iii.org/explanation/support/#contributing-code)

View File

@@ -35,3 +35,51 @@ triage:
This issue has been marked as being in triage. The root cause is not known yet, or the issue needs more investigation. You can help by sharing debug information (from `/debug`) if you also have this issue or when you haven't already done so.
Thank you for your contributions.
needs-moar-debug:
issues:
comment: |
Hi there! This is an automatic reply. `Share and enjoy`
To learn more about this issue, please share the output of the `/debug` page of your Firefly III installation.
If this page is no available due to the issue you have, please make sure you share at least:
1. Firefly III version
2. Docker, self-hosted, or hosted by a third party?
3. Operating system and browser
Thank you for your contributions.
unlabel: needs-moar-debug
needs-moar-logs:
issues:
comment: |
Hi there! This is an automatic reply. `Share and enjoy`
To learn more about this issue, please share the relevant log files from your Firefly III or data importer installation.
The relevant instructions can be found in the documentation: [How to debug Firefly III?](https://docs.firefly-iii.org/how-to/general/debug/) Once debug mode is activated per these instructions, you can repeat your action and find the logs, depending on your method of installation. All is explained on the page.
Please share the relevant log lines in your issue, either inline or as an attachment. If you feel the logs contain sensitive information, you may also send them to [james@firefly-iii.org](mailto:james@firefly-iii.org). Without these logs, it may not be possible to properly investigate this issue.
Thank you for your contributions.
unlabel: needs-moar-logs
v2-layout-issue:
issues:
comment: |
Hi there! This is an automatic reply. `Share and enjoy`
It seems your issue is about the new v2-layout that is currently in development for Firefly III.
These issues are collected in [a GitHub discussion](https://github.com/firefly-iii/firefly-iii/issues/8361).
Please note that the v2 layout is still very much in development.
Thank you for your contributions.
close: true
close-reason: completed
lock: false
unlabel: v2-layout-issue

2
.github/support.md vendored
View File

@@ -27,7 +27,7 @@ Only then [create a new issue](https://github.com/firefly-iii/firefly-iii/issues
- Issues can be converted into discussions if it's not a bug or feature request.
- Features that won't be implemented will be labelled "
wontfix". [This isn't personal](https://docs.firefly-iii.org/firefly-iii/about-firefly-iii/what-its-not/).
wontfix". [This isn't personal](https://docs.firefly-iii.org/explanation/more-information/what-its-not/).
- Issues can be closed if they're duplicates of other issues.
- Issues can be closed if the answer is in the FAQ.
- Issues will be closed automatically after 14 days.

View File

@@ -56,7 +56,9 @@ jobs:
const workflows = [
'cleanup.yml',
'close-duplicates.yml',
'closed-issues.yml',
'debug-info-actions.yml',
'depsreview.yml',
'label-actions.yml',
'lock.yml',

39
.github/workflows/close-duplicates.yml vendored Normal file
View File

@@ -0,0 +1,39 @@
name: "Issues - Command to close duplicate issues"
# the workflow to execute on is comments that are newly created
on:
issue_comment:
types: [created]
permissions:
issues: write
checks: read
jobs:
close_duplicates:
runs-on: ubuntu-latest
steps:
- uses: github/command@v1.1.0
id: command
with:
allowed_contexts: "issue"
command: ".duplicate"
- name: reply
if: ${{ steps.command.outputs.continue == 'true' }}
run: |
ISSUE_TITLE=$(gh issue view ${{ steps.command.outputs.params }} --json title --jq '.title')
gh issue comment "$NUMBER" --body "Hi there!
This is an automatic reply. \`Share and enjoy\`.
Your issue is probably a duplicate of issue <span>#</span>${{ steps.command.outputs.params }}: [$ISSUE_TITLE](https://github.com/firefly-iii/firefly-iii/issues/${{ steps.command.outputs.params }}). Please refer to issue #${{ steps.command.outputs.params }} for support.
You can close this issue now. If you believe this is not in fact a duplicate, please reply and let us know. Otherwise, this issue will be automatically closed in a few days time.
Thank you for your contributions."
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
GH_REPO: ${{ github.repository }}
NUMBER: ${{ github.event.issue.number }}

View File

@@ -0,0 +1,32 @@
name: 'Issues - Respond to hidden commands'
# the workflow to execute on is comments that are newly created
on:
issues:
types: [opened, edited]
issue_comment:
types: [created]
# permissions needed for reacting to IssueOps commands on issues and PRs
permissions:
contents: read
pull-requests: write
issues: write
checks: read
jobs:
respond:
runs-on: ubuntu-latest
steps:
- run: |
ISSUE_BODY=$(gh issue view $NUMBER --json body)
if [[ $ISSUE_BODY == *".eOxNZAmyGz6CXMyf"* ]]; then
gh issue comment "$NUMBER" --body "$V2_ISSUE_REPLY_BODY"
gh issue close "$NUMBER" --reason completed
fi
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
GH_REPO: ${{ github.repository }}
NUMBER: ${{ github.event.issue.number }}
V2_ISSUE_REPLY_BODY: ${{ secrets.V2_ISSUE_REPLY_BODY }}
LABELS: v2-layout-issue

View File

@@ -18,4 +18,4 @@ jobs:
action:
runs-on: ubuntu-latest
steps:
- uses: dessant/label-actions@v3
- uses: dessant/label-actions@v4

View File

@@ -15,5 +15,5 @@ jobs:
- uses: JC5/lock-threads@main
with:
github-token: ${{ github.token }}
issue-inactive-days: 90
pr-inactive-days: 90
issue-inactive-days: 7
pr-inactive-days: 7

1
.gitignore vendored
View File

@@ -1,6 +1,7 @@
/node_modules
/storage/*.key
/vendor
public/hot
npm-debug.log
yarn-error.log
.env

View File

@@ -76,10 +76,9 @@ class AccountController extends Controller
$types = $data['types'];
$query = $data['query'];
$date = $data['date'] ?? today(config('app.timezone'));
$return = [];
$result = $this->repository->searchAccount((string) $query, $types, $this->parameters->get('limit'));
// TODO this code is duplicated in the V2 Autocomplete controller, which means this code is due to be deprecated.
$defaultCurrency = app('amount')->getDefaultCurrency();

View File

@@ -62,7 +62,6 @@ class TagController extends Controller
public function tags(AutocompleteRequest $request): JsonResponse
{
$data = $request->getData();
$result = $this->repository->searchTags($data['query'], $this->parameters->get('limit'));
$array = [];

View File

@@ -45,6 +45,7 @@ use FireflyIII\Repositories\Tag\TagRepositoryInterface;
use FireflyIII\Services\Internal\Destroy\AccountDestroyService;
use FireflyIII\Services\Internal\Destroy\JournalDestroyService;
use Illuminate\Http\JsonResponse;
use Illuminate\Support\Facades\Log;
/**
* Class DestroyController
@@ -175,12 +176,14 @@ class DestroyController extends Controller
$count = $account->transactions()->count();
if (true === $this->unused && 0 === $count) {
app('log')->info(sprintf('Deleted unused account #%d "%s"', $account->id, $account->name));
Log::channel('audit')->info(sprintf('Deleted unused account #%d "%s"', $account->id, $account->name));
$service->destroy($account, null);
continue;
}
if (false === $this->unused) {
app('log')->info(sprintf('Deleting account #%d "%s"', $account->id, $account->name));
Log::channel('audit')->warning(sprintf('Deleted account #%d "%s"', $account->id, $account->name));
$service->destroy($account, null);
}
}

View File

@@ -75,28 +75,28 @@ class TagController extends Controller
$genericSet = $collector->getExtractedJournals();
foreach ($genericSet as $journal) {
$currencyId = (int)$journal['currency_id'];
$foreignCurrencyId = (int)$journal['foreign_currency_id'];
$currencyId = (int) $journal['currency_id'];
$foreignCurrencyId = (int) $journal['foreign_currency_id'];
if (0 !== $currencyId) {
$response[$currencyId] ??= [
'difference' => '0',
'difference_float' => 0,
'currency_id' => (string)$currencyId,
'currency_id' => (string) $currencyId,
'currency_code' => $journal['currency_code'],
];
$response[$currencyId]['difference'] = bcadd($response[$currencyId]['difference'], $journal['amount']);
$response[$currencyId]['difference_float'] = (float)$response[$currencyId]['difference']; // float but on purpose.
$response[$currencyId]['difference_float'] = (float) $response[$currencyId]['difference']; // float but on purpose.
}
if (0 !== $foreignCurrencyId) {
$response[$foreignCurrencyId] ??= [
'difference' => '0',
'difference_float' => 0,
'currency_id' => (string)$foreignCurrencyId,
'currency_id' => (string) $foreignCurrencyId,
'currency_code' => $journal['foreign_currency_code'],
];
$response[$foreignCurrencyId]['difference'] = bcadd($response[$foreignCurrencyId]['difference'], $journal['foreign_amount']);
$response[$foreignCurrencyId]['difference_float'] = (float)$response[$foreignCurrencyId]['difference']; // float but on purpose.
$response[$foreignCurrencyId]['difference_float'] = (float) $response[$foreignCurrencyId]['difference']; // float but on purpose.
}
}
@@ -130,8 +130,8 @@ class TagController extends Controller
/** @var array $journal */
foreach ($genericSet as $journal) {
$currencyId = (int)$journal['currency_id'];
$foreignCurrencyId = (int)$journal['foreign_currency_id'];
$currencyId = (int) $journal['currency_id'];
$foreignCurrencyId = (int) $journal['foreign_currency_id'];
/** @var array $tag */
foreach ($journal['tags'] as $tag) {
@@ -142,15 +142,15 @@ class TagController extends Controller
// on currency ID
if (0 !== $currencyId) {
$response[$key] ??= [
'id' => (string)$tagId,
'id' => (string) $tagId,
'name' => $tag['name'],
'difference' => '0',
'difference_float' => 0,
'currency_id' => (string)$currencyId,
'currency_id' => (string) $currencyId,
'currency_code' => $journal['currency_code'],
];
$response[$key]['difference'] = bcadd($response[$key]['difference'], $journal['amount']);
$response[$key]['difference_float'] = (float)$response[$key]['difference']; // float but on purpose.
$response[$key]['difference_float'] = (float) $response[$key]['difference']; // float but on purpose.
}
// on foreign ID
@@ -158,11 +158,11 @@ class TagController extends Controller
$response[$foreignKey] = $journal[$foreignKey] ?? [
'difference' => '0',
'difference_float' => 0,
'currency_id' => (string)$foreignCurrencyId,
'currency_id' => (string) $foreignCurrencyId,
'currency_code' => $journal['foreign_currency_code'],
];
$response[$foreignKey]['difference'] = bcadd($response[$foreignKey]['difference'], $journal['foreign_amount']);
$response[$foreignKey]['difference_float'] = (float)$response[$foreignKey]['difference']; // float but on purpose.
$response[$foreignKey]['difference_float'] = (float) $response[$foreignKey]['difference']; // float but on purpose.
}
}
}

View File

@@ -29,6 +29,8 @@ use FireflyIII\Models\Attachment;
use FireflyIII\Repositories\Attachment\AttachmentRepositoryInterface;
use FireflyIII\User;
use Illuminate\Http\JsonResponse;
use Illuminate\Support\Facades\Log;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
/**
* Class DestroyController
@@ -64,6 +66,12 @@ class DestroyController extends Controller
*/
public function destroy(Attachment $attachment): JsonResponse
{
if(true === auth()->user()->hasRole('demo')) {
Log::channel('audit')->warning(sprintf('Demo user tries to access attachment API in %s', __METHOD__));
throw new NotFoundHttpException();
}
$this->repository->destroy($attachment);
app('preferences')->mark();

View File

@@ -33,9 +33,11 @@ use FireflyIII\User;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Response as LaravelResponse;
use Illuminate\Pagination\LengthAwarePaginator;
use Illuminate\Support\Facades\Log;
use League\Fractal\Pagination\IlluminatePaginatorAdapter;
use League\Fractal\Resource\Collection as FractalCollection;
use League\Fractal\Resource\Item;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
/**
* Class ShowController
@@ -73,6 +75,11 @@ class ShowController extends Controller
*/
public function download(Attachment $attachment): LaravelResponse
{
if(true === auth()->user()->hasRole('demo')) {
Log::channel('audit')->warning(sprintf('Demo user tries to access attachment API in %s', __METHOD__));
throw new NotFoundHttpException();
}
if (false === $attachment->uploaded) {
throw new FireflyException('200000: File has not been uploaded (yet).');
}
@@ -116,6 +123,12 @@ class ShowController extends Controller
*/
public function index(): JsonResponse
{
if(true === auth()->user()->hasRole('demo')) {
Log::channel('audit')->warning(sprintf('Demo user tries to access attachment API in %s', __METHOD__));
throw new NotFoundHttpException();
}
$manager = $this->getManager();
// types to get, page size:
@@ -148,6 +161,11 @@ class ShowController extends Controller
*/
public function show(Attachment $attachment): JsonResponse
{
if(true === auth()->user()->hasRole('demo')) {
Log::channel('audit')->warning(sprintf('Demo user tries to access attachment API in %s', __METHOD__));
throw new NotFoundHttpException();
}
$manager = $this->getManager();
/** @var AttachmentTransformer $transformer */

View File

@@ -34,7 +34,9 @@ use FireflyIII\Transformers\AttachmentTransformer;
use FireflyIII\User;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Log;
use League\Fractal\Resource\Item;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
/**
* Class StoreController
@@ -72,6 +74,11 @@ class StoreController extends Controller
*/
public function store(StoreRequest $request): JsonResponse
{
if(true === auth()->user()->hasRole('demo')) {
Log::channel('audit')->warning(sprintf('Demo user tries to access attachment API in %s', __METHOD__));
throw new NotFoundHttpException();
}
app('log')->debug(sprintf('Now in %s', __METHOD__));
$data = $request->getAll();
$attachment = $this->repository->store($data);
@@ -91,6 +98,12 @@ class StoreController extends Controller
*/
public function upload(Request $request, Attachment $attachment): JsonResponse
{
if(true === auth()->user()->hasRole('demo')) {
Log::channel('audit')->warning(sprintf('Demo user tries to access attachment API in %s', __METHOD__));
throw new NotFoundHttpException();
}
/** @var AttachmentHelperInterface $helper */
$helper = app(AttachmentHelperInterface::class);
$body = $request->getContent();

View File

@@ -31,7 +31,9 @@ use FireflyIII\Repositories\Attachment\AttachmentRepositoryInterface;
use FireflyIII\Transformers\AttachmentTransformer;
use FireflyIII\User;
use Illuminate\Http\JsonResponse;
use Illuminate\Support\Facades\Log;
use League\Fractal\Resource\Item;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
/**
* Class UpdateController
@@ -67,6 +69,11 @@ class UpdateController extends Controller
*/
public function update(UpdateRequest $request, Attachment $attachment): JsonResponse
{
if(true === auth()->user()->hasRole('demo')) {
Log::channel('audit')->warning(sprintf('Demo user tries to access attachment API in %s', __METHOD__));
throw new NotFoundHttpException();
}
$data = $request->getAll();
$this->repository->update($attachment, $data);
$manager = $this->getManager();

View File

@@ -32,9 +32,11 @@ use FireflyIII\Repositories\Webhook\WebhookRepositoryInterface;
use FireflyIII\Transformers\WebhookAttemptTransformer;
use Illuminate\Http\JsonResponse;
use Illuminate\Pagination\LengthAwarePaginator;
use Illuminate\Support\Facades\Log;
use League\Fractal\Pagination\IlluminatePaginatorAdapter;
use League\Fractal\Resource\Collection as FractalCollection;
use League\Fractal\Resource\Item;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
/**
* Class AttemptController
@@ -68,6 +70,12 @@ class AttemptController extends Controller
if ($message->webhook_id !== $webhook->id) {
throw new FireflyException('200040: Webhook and webhook message are no match');
}
if(false === config('firefly.allow_webhooks')) {
Log::channel('audit')->warning(sprintf('User lists webhook attempts of webhook #%d and message #%d, but webhooks are DISABLED.', $webhook->id, $message->id));
throw new NotFoundHttpException('Webhooks are not enabled.');
}
Log::channel('audit')->info(sprintf('User lists webhook attempts of webhook #%d and message #%d.', $webhook->id, $message->id));
$manager = $this->getManager();
$pageSize = $this->parameters->get('limit');
@@ -106,6 +114,14 @@ class AttemptController extends Controller
throw new FireflyException('200041: Webhook message and webhook attempt are no match');
}
if(false === config('firefly.allow_webhooks')) {
Log::channel('audit')->warning(sprintf('User views single webhook attempt #%d of webhook #%d and message #%d, but webhooks are DISABLED', $attempt->id, $webhook->id, $message->id));
throw new NotFoundHttpException('Webhooks are not enabled.');
}
Log::channel('audit')->info(sprintf('User views single webhook attempt #%d of webhook #%d and message #%d.', $attempt->id, $webhook->id, $message->id));
$manager = $this->getManager();
/** @var WebhookAttemptTransformer $transformer */

View File

@@ -31,6 +31,8 @@ use FireflyIII\Models\WebhookAttempt;
use FireflyIII\Models\WebhookMessage;
use FireflyIII\Repositories\Webhook\WebhookRepositoryInterface;
use Illuminate\Http\JsonResponse;
use Illuminate\Support\Facades\Log;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
/**
* Class DestroyController
@@ -60,6 +62,13 @@ class DestroyController extends Controller
*/
public function destroy(Webhook $webhook): JsonResponse
{
if(false === config('firefly.allow_webhooks')) {
Log::channel('audit')->warning(sprintf('User tries to destroy webhook #%d. but webhooks are DISABLED.', $webhook->id));
throw new NotFoundHttpException('Webhooks are not enabled.');
}
Log::channel('audit')->info(sprintf('User destroys webhook #%d.', $webhook->id));
$this->repository->destroy($webhook);
app('preferences')->mark();
@@ -83,6 +92,14 @@ class DestroyController extends Controller
throw new FireflyException('200041: Webhook message and webhook attempt are no match');
}
if (false === config('firefly.allow_webhooks')) {
Log::channel('audit')->warning(sprintf('User tries to destroy webhook #%d, message #%d, attempt #%d, but webhooks are DISABLED.', $webhook->id, $message->id, $attempt->id));
throw new NotFoundHttpException('Webhooks are not enabled.');
}
Log::channel('audit')->info(sprintf('User destroys webhook #%d, message #%d, attempt #%d.', $webhook->id, $message->id, $attempt->id));
$this->repository->destroyAttempt($attempt);
app('preferences')->mark();
@@ -102,6 +119,14 @@ class DestroyController extends Controller
if ($message->webhook_id !== $webhook->id) {
throw new FireflyException('200040: Webhook and webhook message are no match');
}
if(false === config('firefly.allow_webhooks')) {
Log::channel('audit')->warning(sprintf('User tries to destroy webhook #%d, message #%d, but webhooks are DISABLED.', $webhook->id, $message->id));
throw new NotFoundHttpException('Webhooks are not enabled.');
}
Log::channel('audit')->info(sprintf('User destroys webhook #%d, message #%d.', $webhook->id, $message->id));
$this->repository->destroyMessage($message);
app('preferences')->mark();

View File

@@ -31,9 +31,11 @@ use FireflyIII\Repositories\Webhook\WebhookRepositoryInterface;
use FireflyIII\Transformers\WebhookMessageTransformer;
use Illuminate\Http\JsonResponse;
use Illuminate\Pagination\LengthAwarePaginator;
use Illuminate\Support\Facades\Log;
use League\Fractal\Pagination\IlluminatePaginatorAdapter;
use League\Fractal\Resource\Collection as FractalCollection;
use League\Fractal\Resource\Item;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
/**
* Class MessageController
@@ -64,6 +66,12 @@ class MessageController extends Controller
*/
public function index(Webhook $webhook): JsonResponse
{
if(false === config('firefly.allow_webhooks')) {
Log::channel('audit')->warning(sprintf('User tries to view messages of webhook #%d, but webhooks are DISABLED.', $webhook->id));
throw new NotFoundHttpException('Webhooks are not enabled.');
}
Log::channel('audit')->info(sprintf('User views messages of webhook #%d.', $webhook->id));
$manager = $this->getManager();
$pageSize = $this->parameters->get('limit');
$collection = $this->repository->getMessages($webhook);
@@ -98,6 +106,13 @@ class MessageController extends Controller
if ($message->webhook_id !== $webhook->id) {
throw new FireflyException('200040: Webhook and webhook message are no match');
}
if(false === config('firefly.allow_webhooks')) {
Log::channel('audit')->warning(sprintf('User tries to view message #%d of webhook #%d, but webhooks are DISABLED.', $message->id, $webhook->id));
throw new NotFoundHttpException('Webhooks are not enabled.');
}
Log::channel('audit')->info(sprintf('User views message #%d of webhook #%d.', $message->id, $webhook->id));
$manager = $this->getManager();

View File

@@ -34,9 +34,11 @@ use FireflyIII\Transformers\WebhookTransformer;
use Illuminate\Http\JsonResponse;
use Illuminate\Pagination\LengthAwarePaginator;
use Illuminate\Support\Collection;
use Illuminate\Support\Facades\Log;
use League\Fractal\Pagination\IlluminatePaginatorAdapter;
use League\Fractal\Resource\Collection as FractalCollection;
use League\Fractal\Resource\Item;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
/**
* Class ShowController
@@ -69,6 +71,13 @@ class ShowController extends Controller
*/
public function index(): JsonResponse
{
if(false === config('firefly.allow_webhooks')) {
Log::channel('audit')->info('User tries to view all webhooks, but webhooks are DISABLED.');
throw new NotFoundHttpException('Webhooks are not enabled.');
}
Log::channel('audit')->info('User views all webhooks.');
$manager = $this->getManager();
$collection = $this->repository->all();
$pageSize = $this->parameters->get('limit');
@@ -97,6 +106,13 @@ class ShowController extends Controller
*/
public function show(Webhook $webhook): JsonResponse
{
if(false === config('firefly.allow_webhooks')) {
Log::channel('audit')->info(sprintf('User tries to view webhook #%d, but webhooks are DISABLED.', $webhook->id));
throw new NotFoundHttpException('Webhooks are not enabled.');
}
Log::channel('audit')->info(sprintf('User views webhook #%d.', $webhook->id));
$manager = $this->getManager();
/** @var WebhookTransformer $transformer */
@@ -115,7 +131,14 @@ class ShowController extends Controller
*/
public function triggerTransaction(Webhook $webhook, TransactionGroup $group): JsonResponse
{
if(false === config('firefly.allow_webhooks')) {
Log::channel('audit')->info(sprintf('User tries to trigger webhook #%d on transaction group #%d, but webhooks are DISABLED.', $webhook->id, $group->id));
throw new NotFoundHttpException('Webhooks are not enabled.');
}
app('log')->debug(sprintf('Now in triggerTransaction(%d, %d)', $webhook->id, $group->id));
Log::channel('audit')->info(sprintf('User triggers webhook #%d on transaction group #%d.', $webhook->id, $group->id));
/** @var MessageGeneratorInterface $engine */
$engine = app(MessageGeneratorInterface::class);

View File

@@ -28,7 +28,9 @@ use FireflyIII\Api\V1\Requests\Models\Webhook\CreateRequest;
use FireflyIII\Repositories\Webhook\WebhookRepositoryInterface;
use FireflyIII\Transformers\WebhookTransformer;
use Illuminate\Http\JsonResponse;
use Illuminate\Support\Facades\Log;
use League\Fractal\Resource\Item;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
/**
* Class StoreController
@@ -58,9 +60,17 @@ class StoreController extends Controller
public function store(CreateRequest $request): JsonResponse
{
$data = $request->getData();
if(false === config('firefly.allow_webhooks')) {
Log::channel('audit')->info('User tries to store new webhook, but webhooks are DISABLED.', $data);
throw new NotFoundHttpException('Webhooks are not enabled.');
}
$webhook = $this->repository->store($data);
$manager = $this->getManager();
Log::channel('audit')->info('User stores new webhook', $data);
/** @var WebhookTransformer $transformer */
$transformer = app(WebhookTransformer::class);
$transformer->setParameters($this->parameters);

View File

@@ -28,6 +28,8 @@ use FireflyIII\Jobs\SendWebhookMessage;
use FireflyIII\Models\Webhook;
use FireflyIII\Repositories\Webhook\WebhookRepositoryInterface;
use Illuminate\Http\JsonResponse;
use Illuminate\Support\Facades\Log;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
/**
* Class SubmitController
@@ -55,6 +57,13 @@ class SubmitController extends Controller
*/
public function submit(Webhook $webhook): JsonResponse
{
if(false === config('firefly.allow_webhooks')) {
Log::channel('audit')->info(sprintf('User tries to submit webhook #%d, but webhooks are DISABLED.', $webhook->id));
throw new NotFoundHttpException('Webhooks are not enabled.');
}
Log::channel('audit')->info(sprintf('User submits webhook #%d', $webhook->id));
// count messages that can be sent.
$messages = $this->repository->getReadyMessages($webhook);
if (0 === $messages->count()) {

View File

@@ -29,7 +29,9 @@ use FireflyIII\Models\Webhook;
use FireflyIII\Repositories\Webhook\WebhookRepositoryInterface;
use FireflyIII\Transformers\WebhookTransformer;
use Illuminate\Http\JsonResponse;
use Illuminate\Support\Facades\Log;
use League\Fractal\Resource\Item;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
/**
* Class UpdateController
@@ -58,9 +60,17 @@ class UpdateController extends Controller
public function update(Webhook $webhook, UpdateRequest $request): JsonResponse
{
$data = $request->getData();
if(false === config('firefly.allow_webhooks')) {
Log::channel('audit')->info(sprintf('User tries to update webhook #%d, but webhooks are DISABLED.', $webhook->id), $data);
throw new NotFoundHttpException('Webhooks are not enabled.');
}
$webhook = $this->repository->update($webhook, $data);
$manager = $this->getManager();
Log::channel('audit')->info(sprintf('User updates webhook #%d', $webhook->id), $data);
/** @var WebhookTransformer $transformer */
$transformer = app(WebhookTransformer::class);
$transformer->setParameters($this->parameters);

View File

@@ -28,6 +28,7 @@ use FireflyIII\Repositories\Account\AccountRepositoryInterface;
use FireflyIII\Support\Request\ChecksLogin;
use FireflyIII\Support\Request\ConvertsDataTypes;
use Illuminate\Foundation\Http\FormRequest;
use Illuminate\Support\Facades\Log;
use Illuminate\Validation\Validator;
/**
@@ -59,9 +60,7 @@ class MoveTransactionsRequest extends FormRequest
/**
* Configure the validator instance with special rules for after the basic validation rules.
*
* @param validator $validator
* TODO this is duplicate
* TODO this is duplicate.
*/
public function withValidator(Validator $validator): void
{
@@ -74,6 +73,9 @@ class MoveTransactionsRequest extends FormRequest
}
}
);
if($validator->fails()) {
Log::channel('audit')->error(sprintf('Validation errors in %s', __CLASS__), $validator->errors()->toArray());
}
}
private function validateMove(Validator $validator): void
@@ -81,12 +83,12 @@ class MoveTransactionsRequest extends FormRequest
$data = $validator->getData();
$repository = app(AccountRepositoryInterface::class);
$repository->setUser(auth()->user());
$original = $repository->find((int)$data['original_account']);
$destination = $repository->find((int)$data['destination_account']);
$original = $repository->find((int) $data['original_account']);
$destination = $repository->find((int) $data['destination_account']);
// not the same type:
if ($original->accountType->type !== $destination->accountType->type) {
$validator->errors()->add('title', (string)trans('validation.same_account_type'));
$validator->errors()->add('title', (string) trans('validation.same_account_type'));
return;
}
@@ -96,7 +98,7 @@ class MoveTransactionsRequest extends FormRequest
// check different scenario's.
if (null === $originalCurrency xor null === $destinationCurrency) {
$validator->errors()->add('title', (string)trans('validation.same_account_currency'));
$validator->errors()->add('title', (string) trans('validation.same_account_currency'));
return;
}
@@ -105,7 +107,7 @@ class MoveTransactionsRequest extends FormRequest
return;
}
if ($originalCurrency->code !== $destinationCurrency->code) {
$validator->errors()->add('title', (string)trans('validation.same_account_currency'));
$validator->errors()->add('title', (string) trans('validation.same_account_currency'));
}
}
}

View File

@@ -30,6 +30,7 @@ use FireflyIII\Support\Request\ChecksLogin;
use FireflyIII\Support\Request\ConvertsDataTypes;
use FireflyIII\Validation\Api\Data\Bulk\ValidatesBulkTransactionQuery;
use Illuminate\Foundation\Http\FormRequest;
use Illuminate\Support\Facades\Log;
use Illuminate\Validation\Validator;
/**
@@ -72,5 +73,8 @@ class TransactionRequest extends FormRequest
$this->validateTransactionQuery($validator);
}
);
if($validator->fails()) {
Log::channel('audit')->error(sprintf('Validation errors in %s', __CLASS__), $validator->errors()->toArray());
}
}
}

View File

@@ -24,6 +24,7 @@ declare(strict_types=1);
namespace FireflyIII\Api\V1\Requests\Data;
use FireflyIII\Exceptions\FireflyException;
use FireflyIII\Support\Request\ChecksLogin;
use FireflyIII\Support\Request\ConvertsDataTypes;
use Illuminate\Foundation\Http\FormRequest;
@@ -43,9 +44,15 @@ class DateRequest extends FormRequest
*/
public function getAll(): array
{
$start = $this->getCarbonDate('start');
$end = $this->getCarbonDate('end');
if($start->diffInYears($end) > 5) {
throw new FireflyException('Date range out of range.');
}
return [
'start' => $this->getCarbonDate('start'),
'end' => $this->getCarbonDate('end'),
'start' => $start,
'end' => $end,
];
}

View File

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

View File

@@ -26,6 +26,7 @@ namespace FireflyIII\Api\V1\Requests\Models\Account;
use FireflyIII\Models\Location;
use FireflyIII\Rules\IsBoolean;
use FireflyIII\Rules\IsValidPositiveAmount;
use FireflyIII\Rules\UniqueAccountNumber;
use FireflyIII\Rules\UniqueIban;
use FireflyIII\Support\Request\AppendsLocationData;
@@ -100,7 +101,7 @@ class StoreRequest extends FormRequest
'type' => 'required|max:1024|min:1|'.sprintf('in:%s', $types),
'iban' => ['iban', 'nullable', new UniqueIban(null, $type)],
'bic' => 'bic|nullable',
'account_number' => ['between:1,255', 'nullable', new UniqueAccountNumber(null, $type)],
'account_number' => ['min:1', 'max:255', 'nullable', new UniqueAccountNumber(null, $type)],
'opening_balance' => 'numeric|required_with:opening_balance_date|nullable',
'opening_balance_date' => 'date|required_with:opening_balance|nullable',
'virtual_balance' => 'numeric|nullable',
@@ -113,12 +114,12 @@ class StoreRequest extends FormRequest
'credit_card_type' => sprintf('nullable|in:%s|required_if:account_role,ccAsset', $ccPaymentTypes),
'monthly_payment_date' => 'nullable|date|required_if:account_role,ccAsset|required_if:credit_card_type,monthlyFull',
'liability_type' => 'nullable|required_if:type,liability|required_if:type,liabilities|in:loan,debt,mortgage',
'liability_amount' => 'required_with:liability_start_date|min:0|numeric|max:1000000000',
'liability_amount' => ['required_with:liability_start_date', new IsValidPositiveAmount()],
'liability_start_date' => 'required_with:liability_amount|date',
'liability_direction' => 'nullable|required_if:type,liability|required_if:type,liabilities|in:credit,debit',
'interest' => 'between:0,100|numeric',
'interest' => 'min:0|max:100|numeric',
'interest_period' => sprintf('nullable|in:%s', implode(',', config('firefly.interest_periods'))),
'notes' => 'min:0|max:65536',
'notes' => 'min:0|max:32768',
];
return Location::requestRules($rules);

View File

@@ -91,7 +91,7 @@ class UpdateRequest extends FormRequest
'type' => sprintf('in:%s', $types),
'iban' => ['iban', 'nullable', new UniqueIban($account, $this->convertString('type'))],
'bic' => 'bic|nullable',
'account_number' => ['between:1,255', 'nullable', new UniqueAccountNumber($account, $this->convertString('type'))],
'account_number' => ['min:1', 'max:255', 'nullable', new UniqueAccountNumber($account, $this->convertString('type'))],
'opening_balance' => 'numeric|required_with:opening_balance_date|nullable',
'opening_balance_date' => 'date|required_with:opening_balance|nullable',
'virtual_balance' => 'numeric|nullable',
@@ -105,9 +105,9 @@ class UpdateRequest extends FormRequest
'monthly_payment_date' => 'date|nullable|required_if:account_role,ccAsset|required_if:credit_card_type,monthlyFull',
'liability_type' => 'required_if:type,liability|in:loan,debt,mortgage',
'liability_direction' => 'required_if:type,liability|in:credit,debit',
'interest' => 'required_if:type,liability|between:0,100|numeric',
'interest' => 'required_if:type,liability|min:0|max:100|numeric',
'interest_period' => 'required_if:type,liability|in:daily,monthly,yearly',
'notes' => 'min:0|max:65536',
'notes' => 'min:0|max:32768',
];
return Location::requestRules($rules);

View File

@@ -66,9 +66,9 @@ class StoreRequest extends FormRequest
$model = $this->convertString('attachable_type');
return [
'filename' => 'required|between:1,255',
'title' => 'between:1,255',
'notes' => 'between:1,65000',
'filename' => 'required|min:1|max:255',
'title' => ['min:1', 'max:255'],
'notes' => 'min:1|max:32768',
'attachable_type' => sprintf('required|in:%s', $models),
'attachable_id' => ['required', 'numeric', new IsValidAttachmentModel($model)],
];

View File

@@ -68,9 +68,9 @@ class UpdateRequest extends FormRequest
$model = $this->convertString('attachable_type');
return [
'filename' => 'between:1,255',
'title' => 'between:1,255',
'notes' => 'between:1,65000',
'filename' => ['min:1', 'max:255'],
'title' => ['min:1', 'max:255'],
'notes' => 'min:1|max:32768',
'attachable_type' => sprintf('in:%s', $models),
'attachable_id' => ['numeric', new IsValidAttachmentModel($model)],
];

View File

@@ -24,9 +24,11 @@ declare(strict_types=1);
namespace FireflyIII\Api\V1\Requests\Models\AvailableBudget;
use Carbon\Carbon;
use FireflyIII\Rules\IsValidPositiveAmount;
use FireflyIII\Support\Request\ChecksLogin;
use FireflyIII\Support\Request\ConvertsDataTypes;
use Illuminate\Foundation\Http\FormRequest;
use Illuminate\Support\Facades\Log;
use Illuminate\Validation\Validator;
/**
@@ -62,7 +64,7 @@ class Request extends FormRequest
return [
'currency_id' => 'numeric|exists:transaction_currencies,id',
'currency_code' => 'min:3|max:51|exists:transaction_currencies,code',
'amount' => 'numeric|gt:0',
'amount' => ['nullable', new IsValidPositiveAmount()],
'start' => 'date',
'end' => 'date',
];
@@ -86,5 +88,8 @@ class Request extends FormRequest
}
}
);
if($validator->fails()) {
Log::channel('audit')->error(sprintf('Validation errors in %s', __CLASS__), $validator->errors()->toArray());
}
}
}

View File

@@ -25,9 +25,11 @@ declare(strict_types=1);
namespace FireflyIII\Api\V1\Requests\Models\Bill;
use FireflyIII\Rules\IsBoolean;
use FireflyIII\Rules\IsValidPositiveAmount;
use FireflyIII\Support\Request\ChecksLogin;
use FireflyIII\Support\Request\ConvertsDataTypes;
use Illuminate\Foundation\Http\FormRequest;
use Illuminate\Support\Facades\Log;
use Illuminate\Validation\Validator;
/**
@@ -71,18 +73,18 @@ class StoreRequest extends FormRequest
public function rules(): array
{
return [
'name' => 'between:1,255|uniqueObjectForUser:bills,name',
'amount_min' => 'numeric|gt:0|required',
'amount_max' => 'numeric|gt:0|required',
'name' => 'min:1|max:255|uniqueObjectForUser:bills,name',
'amount_min' => ['required', new IsValidPositiveAmount()],
'amount_max' => ['required', new IsValidPositiveAmount()],
'currency_id' => 'numeric|exists:transaction_currencies,id',
'currency_code' => 'min:3|max:51|exists:transaction_currencies,code',
'date' => 'date|required',
'end_date' => 'date|after:date',
'extension_date' => 'date|after:date',
'repeat_freq' => 'in:weekly,monthly,quarterly,half-year,yearly|required',
'skip' => 'between:0,31',
'skip' => 'min:0|max:31|numeric',
'active' => [new IsBoolean()],
'notes' => 'between:1,65536',
'notes' => 'min:1|max:32768',
];
}
@@ -102,5 +104,8 @@ class StoreRequest extends FormRequest
}
}
);
if($validator->fails()) {
Log::channel('audit')->error(sprintf('Validation errors in %s', __CLASS__), $validator->errors()->toArray());
}
}
}

View File

@@ -26,9 +26,11 @@ namespace FireflyIII\Api\V1\Requests\Models\Bill;
use FireflyIII\Models\Bill;
use FireflyIII\Rules\IsBoolean;
use FireflyIII\Rules\IsValidPositiveAmount;
use FireflyIII\Support\Request\ChecksLogin;
use FireflyIII\Support\Request\ConvertsDataTypes;
use Illuminate\Foundation\Http\FormRequest;
use Illuminate\Support\Facades\Log;
use Illuminate\Validation\Validator;
/**
@@ -74,18 +76,18 @@ class UpdateRequest extends FormRequest
$bill = $this->route()->parameter('bill');
return [
'name' => sprintf('between:1,255|uniqueObjectForUser:bills,name,%d', $bill->id),
'amount_min' => 'numeric|gt:0',
'amount_max' => 'numeric|gt:0',
'name' => sprintf('min:1|max:255|uniqueObjectForUser:bills,name,%d', $bill->id),
'amount_min' => ['nullable', new IsValidPositiveAmount()],
'amount_max' => ['nullable', new IsValidPositiveAmount()],
'currency_id' => 'numeric|exists:transaction_currencies,id',
'currency_code' => 'min:3|max:51|exists:transaction_currencies,code',
'date' => 'date',
'end_date' => 'date|after:date',
'extension_date' => 'date|after:date',
'repeat_freq' => 'in:weekly,monthly,quarterly,half-year,yearly',
'skip' => 'between:0,31',
'skip' => 'min:0|max:31|numeric',
'active' => [new IsBoolean()],
'notes' => 'between:1,65536',
'notes' => 'min:1|max:32768',
];
}
@@ -107,5 +109,8 @@ class UpdateRequest extends FormRequest
}
}
);
if($validator->fails()) {
Log::channel('audit')->error(sprintf('Validation errors in %s', __CLASS__), $validator->errors()->toArray());
}
}
}

View File

@@ -24,10 +24,12 @@ declare(strict_types=1);
namespace FireflyIII\Api\V1\Requests\Models\Budget;
use FireflyIII\Rules\IsBoolean;
use FireflyIII\Rules\IsValidPositiveAmount;
use FireflyIII\Support\Request\ChecksLogin;
use FireflyIII\Support\Request\ConvertsDataTypes;
use FireflyIII\Validation\AutoBudget\ValidatesAutoBudgetRequest;
use Illuminate\Foundation\Http\FormRequest;
use Illuminate\Support\Facades\Log;
use Illuminate\Validation\Validator;
/**
@@ -67,14 +69,14 @@ class StoreRequest extends FormRequest
public function rules(): array
{
return [
'name' => 'required|between:1,100|uniqueObjectForUser:budgets,name',
'name' => 'required|min:1|max:255|uniqueObjectForUser:budgets,name',
'active' => [new IsBoolean()],
'currency_id' => 'exists:transaction_currencies,id',
'currency_code' => 'exists:transaction_currencies,code',
'notes' => 'nullable|between:1,65536',
'notes' => 'nullable|min:1|max:32768',
// auto budget info
'auto_budget_type' => 'in:reset,rollover,adjusted,none',
'auto_budget_amount' => 'numeric|min:0|max:1000000000|required_if:auto_budget_type,reset|required_if:auto_budget_type,rollover|required_if:auto_budget_type,adjusted',
'auto_budget_amount' => ['required_if:auto_budget_type,reset', 'required_if:auto_budget_type,rollover', 'required_if:auto_budget_type,adjusted', new IsValidPositiveAmount()],
'auto_budget_period' => 'in:daily,weekly,monthly,quarterly,half_year,yearly|required_if:auto_budget_type,reset|required_if:auto_budget_type,rollover|required_if:auto_budget_type,adjusted',
];
}
@@ -90,5 +92,8 @@ class StoreRequest extends FormRequest
$this->validateAutoBudgetAmount($validator);
}
);
if($validator->fails()) {
Log::channel('audit')->error(sprintf('Validation errors in %s', __CLASS__), $validator->errors()->toArray());
}
}
}

View File

@@ -25,10 +25,12 @@ namespace FireflyIII\Api\V1\Requests\Models\Budget;
use FireflyIII\Models\Budget;
use FireflyIII\Rules\IsBoolean;
use FireflyIII\Rules\IsValidPositiveAmount;
use FireflyIII\Support\Request\ChecksLogin;
use FireflyIII\Support\Request\ConvertsDataTypes;
use FireflyIII\Validation\AutoBudget\ValidatesAutoBudgetRequest;
use Illuminate\Foundation\Http\FormRequest;
use Illuminate\Support\Facades\Log;
use Illuminate\Validation\Validator;
/**
@@ -80,13 +82,13 @@ class UpdateRequest extends FormRequest
$budget = $this->route()->parameter('budget');
return [
'name' => sprintf('between:1,100|uniqueObjectForUser:budgets,name,%d', $budget->id),
'name' => sprintf('min:1|max:100|uniqueObjectForUser:budgets,name,%d', $budget->id),
'active' => [new IsBoolean()],
'notes' => 'nullable|between:1,65536',
'notes' => 'nullable|min:1|max:32768',
'auto_budget_type' => 'in:reset,rollover,adjusted,none',
'auto_budget_currency_id' => 'exists:transaction_currencies,id',
'auto_budget_currency_code' => 'exists:transaction_currencies,code',
'auto_budget_amount' => 'min:0|max:1000000000',
'auto_budget_amount' => ['nullable', new IsValidPositiveAmount()],
'auto_budget_period' => 'in:daily,weekly,monthly,quarterly,half_year,yearly',
];
}
@@ -102,5 +104,8 @@ class UpdateRequest extends FormRequest
$this->validateAutoBudgetAmount($validator);
}
);
if($validator->fails()) {
Log::channel('audit')->error(sprintf('Validation errors in %s', __CLASS__), $validator->errors()->toArray());
}
}
}

View File

@@ -23,6 +23,7 @@ declare(strict_types=1);
namespace FireflyIII\Api\V1\Requests\Models\BudgetLimit;
use FireflyIII\Rules\IsValidPositiveAmount;
use FireflyIII\Support\Request\ChecksLogin;
use FireflyIII\Support\Request\ConvertsDataTypes;
use Illuminate\Foundation\Http\FormRequest;
@@ -57,7 +58,7 @@ class StoreRequest extends FormRequest
return [
'start' => 'required|before:end|date',
'end' => 'required|after:start|date',
'amount' => 'required|gt:0',
'amount' => ['required', new IsValidPositiveAmount()],
'currency_id' => 'numeric|exists:transaction_currencies,id',
'currency_code' => 'min:3|max:51|exists:transaction_currencies,code',
];

View File

@@ -24,9 +24,11 @@ declare(strict_types=1);
namespace FireflyIII\Api\V1\Requests\Models\BudgetLimit;
use Carbon\Carbon;
use FireflyIII\Rules\IsValidPositiveAmount;
use FireflyIII\Support\Request\ChecksLogin;
use FireflyIII\Support\Request\ConvertsDataTypes;
use Illuminate\Foundation\Http\FormRequest;
use Illuminate\Support\Facades\Log;
use Illuminate\Validation\Validator;
/**
@@ -61,7 +63,7 @@ class UpdateRequest extends FormRequest
return [
'start' => 'date',
'end' => 'date',
'amount' => 'gt:0',
'amount' => ['nullable', new IsValidPositiveAmount()],
'currency_id' => 'numeric|exists:transaction_currencies,id',
'currency_code' => 'min:3|max:51|exists:transaction_currencies,code',
];
@@ -69,9 +71,7 @@ class UpdateRequest extends FormRequest
/**
* Configure the validator instance with special rules for after the basic validation rules.
*
* @param Validator $validator
* TODO duplicate code
* TODO duplicate code.
*/
public function withValidator(Validator $validator): void
{
@@ -83,10 +83,13 @@ class UpdateRequest extends FormRequest
$start = new Carbon($data['start']);
$end = new Carbon($data['end']);
if ($end->isBefore($start)) {
$validator->errors()->add('end', (string)trans('validation.date_after'));
$validator->errors()->add('end', (string) trans('validation.date_after'));
}
}
}
);
if($validator->fails()) {
Log::channel('audit')->error(sprintf('Validation errors in %s', __CLASS__), $validator->errors()->toArray());
}
}
}

View File

@@ -52,7 +52,7 @@ class StoreRequest extends FormRequest
public function rules(): array
{
return [
'name' => 'required|between:1,100|uniqueObjectForUser:categories,name',
'name' => 'required|min:1|max:100|uniqueObjectForUser:categories,name',
];
}
}

View File

@@ -58,7 +58,7 @@ class UpdateRequest extends FormRequest
$category = $this->route()->parameter('category');
return [
'name' => sprintf('between:1,100|uniqueObjectForUser:categories,name,%d', $category->id),
'name' => sprintf('min:1|max:100|uniqueObjectForUser:categories,name,%d', $category->id),
];
}
}

View File

@@ -23,6 +23,7 @@ declare(strict_types=1);
namespace FireflyIII\Api\V1\Requests\Models\PiggyBank;
use FireflyIII\Rules\IsValidPositiveAmount;
use FireflyIII\Support\Request\ChecksLogin;
use FireflyIII\Support\Request\ConvertsDataTypes;
use Illuminate\Foundation\Http\FormRequest;
@@ -63,12 +64,12 @@ class StoreRequest extends FormRequest
public function rules(): array
{
return [
'name' => 'required|between:1,255|uniquePiggyBankForUser',
'current_amount' => ['numeric', 'gte:0', 'lte:target_amount'],
'name' => 'required|min:1|max:255|uniquePiggyBankForUser',
'current_amount' => ['nullable', new IsValidPositiveAmount()],
'account_id' => 'required|numeric|belongsToUser:accounts,id',
'object_group_id' => 'numeric|belongsToUser:object_groups,id',
'object_group_title' => 'between:1,255',
'target_amount' => ['numeric', 'gte:0', 'lte:target_amount', 'required'],
'object_group_title' => ['min:1', 'max:255'],
'target_amount' => ['required', new IsValidPositiveAmount()],
'start_date' => 'date|nullable',
'target_date' => 'date|nullable|after:start_date',
'notes' => 'max:65000',

View File

@@ -25,6 +25,7 @@ namespace FireflyIII\Api\V1\Requests\Models\PiggyBank;
use FireflyIII\Models\PiggyBank;
use FireflyIII\Rules\IsAssetAccountId;
use FireflyIII\Rules\IsValidPositiveAmount;
use FireflyIII\Rules\LessThanPiggyTarget;
use FireflyIII\Support\Request\ChecksLogin;
use FireflyIII\Support\Request\ConvertsDataTypes;
@@ -68,9 +69,9 @@ class UpdateRequest extends FormRequest
$piggyBank = $this->route()->parameter('piggyBank');
return [
'name' => 'between:1,255|uniquePiggyBankForUser:'.$piggyBank->id,
'current_amount' => ['numeric', 'gte:0', new LessThanPiggyTarget()],
'target_amount' => 'numeric|gte:0',
'name' => 'min:1|max:255|uniquePiggyBankForUser:'.$piggyBank->id,
'current_amount' => ['nullable', new LessThanPiggyTarget(), new IsValidPositiveAmount()],
'target_amount' => ['nullable', new IsValidPositiveAmount()],
'start_date' => 'date|nullable',
'target_date' => 'date|nullable|after:start_date',
'notes' => 'max:65000',

View File

@@ -25,6 +25,7 @@ namespace FireflyIII\Api\V1\Requests\Models\Recurrence;
use FireflyIII\Rules\BelongsUser;
use FireflyIII\Rules\IsBoolean;
use FireflyIII\Rules\IsValidPositiveAmount;
use FireflyIII\Support\Request\ChecksLogin;
use FireflyIII\Support\Request\ConvertsDataTypes;
use FireflyIII\Support\Request\GetRecurrenceData;
@@ -32,6 +33,7 @@ use FireflyIII\Validation\CurrencyValidation;
use FireflyIII\Validation\RecurrenceValidation;
use FireflyIII\Validation\TransactionValidation;
use Illuminate\Foundation\Http\FormRequest;
use Illuminate\Support\Facades\Log;
use Illuminate\Validation\Validator;
/**
@@ -78,39 +80,39 @@ class StoreRequest extends FormRequest
{
return [
'type' => 'required|in:withdrawal,transfer,deposit',
'title' => 'required|between:1,255|uniqueObjectForUser:recurrences,title',
'description' => 'between:1,65000',
'title' => 'required|min:1|max:255|uniqueObjectForUser:recurrences,title',
'description' => 'min:1|max:32768',
'first_date' => 'required|date',
'apply_rules' => [new IsBoolean()],
'active' => [new IsBoolean()],
'repeat_until' => 'nullable|date',
'nr_of_repetitions' => 'nullable|numeric|between:1,31',
'nr_of_repetitions' => 'nullable|numeric|min:1|max:31',
'repetitions.*.type' => 'required|in:daily,weekly,ndom,monthly,yearly',
'repetitions.*.moment' => 'between:0,10',
'repetitions.*.skip' => 'nullable|numeric|between:0,31',
'repetitions.*.moment' => 'min:0|max:10',
'repetitions.*.skip' => 'nullable|numeric|min:0|max:31',
'repetitions.*.weekend' => 'numeric|min:1|max:4',
'transactions.*.description' => 'required|between:1,255',
'transactions.*.amount' => 'required|numeric|gt:0',
'transactions.*.foreign_amount' => 'nullable|numeric|gt:0',
'transactions.*.description' => 'required|min:1|max:255',
'transactions.*.amount' => ['required', new IsValidPositiveAmount()],
'transactions.*.foreign_amount' => ['nullable', new IsValidPositiveAmount()],
'transactions.*.currency_id' => 'nullable|numeric|exists:transaction_currencies,id',
'transactions.*.currency_code' => 'nullable|min:3|max:51|exists:transaction_currencies,code',
'transactions.*.foreign_currency_id' => 'nullable|numeric|exists:transaction_currencies,id',
'transactions.*.foreign_currency_code' => 'nullable|min:3|max:51|exists:transaction_currencies,code',
'transactions.*.source_id' => ['numeric', 'nullable', new BelongsUser()],
'transactions.*.source_name' => 'between:1,255|nullable',
'transactions.*.source_name' => 'min:1|max:255|nullable',
'transactions.*.destination_id' => ['numeric', 'nullable', new BelongsUser()],
'transactions.*.destination_name' => 'between:1,255|nullable',
'transactions.*.destination_name' => 'min:1|max:255|nullable',
// new and updated fields:
'transactions.*.budget_id' => ['nullable', 'mustExist:budgets,id', new BelongsUser()],
'transactions.*.budget_name' => ['between:1,255', 'nullable', new BelongsUser()],
'transactions.*.budget_name' => ['min:1', 'max:255', 'nullable', new BelongsUser()],
'transactions.*.category_id' => ['nullable', 'mustExist:categories,id', new BelongsUser()],
'transactions.*.category_name' => 'between:1,255|nullable',
'transactions.*.category_name' => 'min:1|max:255|nullable',
'transactions.*.piggy_bank_id' => ['nullable', 'numeric', 'mustExist:piggy_banks,id', new BelongsUser()],
'transactions.*.piggy_bank_name' => ['between:1,255', 'nullable', new BelongsUser()],
'transactions.*.tags' => 'nullable|between:1,64000',
'transactions.*.piggy_bank_name' => ['min:1', 'max:255', 'nullable', new BelongsUser()],
'transactions.*.tags' => 'nullable|min:1|max:255',
];
}
@@ -130,6 +132,9 @@ class StoreRequest extends FormRequest
$this->validateAccountInformation($validator);
}
);
if($validator->fails()) {
Log::channel('audit')->error(sprintf('Validation errors in %s', __CLASS__), $validator->errors()->toArray());
}
}
/**

View File

@@ -26,6 +26,7 @@ namespace FireflyIII\Api\V1\Requests\Models\Recurrence;
use FireflyIII\Models\Recurrence;
use FireflyIII\Rules\BelongsUser;
use FireflyIII\Rules\IsBoolean;
use FireflyIII\Rules\IsValidPositiveAmount;
use FireflyIII\Support\Request\ChecksLogin;
use FireflyIII\Support\Request\ConvertsDataTypes;
use FireflyIII\Support\Request\GetRecurrenceData;
@@ -33,6 +34,7 @@ use FireflyIII\Validation\CurrencyValidation;
use FireflyIII\Validation\RecurrenceValidation;
use FireflyIII\Validation\TransactionValidation;
use Illuminate\Foundation\Http\FormRequest;
use Illuminate\Support\Facades\Log;
use Illuminate\Validation\Validator;
/**
@@ -85,39 +87,39 @@ class UpdateRequest extends FormRequest
$recurrence = $this->route()->parameter('recurrence');
return [
'title' => sprintf('between:1,255|uniqueObjectForUser:recurrences,title,%d', $recurrence->id),
'description' => 'between:1,65000',
'title' => sprintf('min:1|max:255|uniqueObjectForUser:recurrences,title,%d', $recurrence->id),
'description' => 'min:1|max:32768',
'first_date' => 'date',
'apply_rules' => [new IsBoolean()],
'active' => [new IsBoolean()],
'repeat_until' => 'nullable|date',
'nr_of_repetitions' => 'nullable|numeric|between:1,31',
'nr_of_repetitions' => 'nullable|numeric|min:1|max:31',
'repetitions.*.type' => 'in:daily,weekly,ndom,monthly,yearly',
'repetitions.*.moment' => 'between:0,10',
'repetitions.*.skip' => 'nullable|numeric|between:0,31',
'repetitions.*.moment' => 'min:0|max:10|numeric',
'repetitions.*.skip' => 'nullable|numeric|min:0|max:31',
'repetitions.*.weekend' => 'nullable|numeric|min:1|max:4',
'transactions.*.description' => 'between:1,255',
'transactions.*.amount' => 'numeric|gt:0',
'transactions.*.foreign_amount' => 'nullable|numeric|gt:0',
'transactions.*.description' => ['min:1', 'max:255'],
'transactions.*.amount' => [new IsValidPositiveAmount()],
'transactions.*.foreign_amount' => ['nullable', new IsValidPositiveAmount()],
'transactions.*.currency_id' => 'nullable|numeric|exists:transaction_currencies,id',
'transactions.*.currency_code' => 'nullable|min:3|max:51|exists:transaction_currencies,code',
'transactions.*.foreign_currency_id' => 'nullable|numeric|exists:transaction_currencies,id',
'transactions.*.foreign_currency_code' => 'nullable|min:3|max:51|exists:transaction_currencies,code',
'transactions.*.source_id' => ['numeric', 'nullable', new BelongsUser()],
'transactions.*.source_name' => 'between:1,255|nullable',
'transactions.*.source_name' => 'min:1|max:255|nullable',
'transactions.*.destination_id' => ['numeric', 'nullable', new BelongsUser()],
'transactions.*.destination_name' => 'between:1,255|nullable',
'transactions.*.destination_name' => 'min:1|max:255|nullable',
// new and updated fields:
'transactions.*.budget_id' => ['nullable', 'mustExist:budgets,id', new BelongsUser()],
'transactions.*.budget_name' => ['between:1,255', 'nullable', new BelongsUser()],
'transactions.*.budget_name' => ['min:1', 'max:255', 'nullable', new BelongsUser()],
'transactions.*.category_id' => ['nullable', 'mustExist:categories,id', new BelongsUser()],
'transactions.*.category_name' => 'between:1,255|nullable',
'transactions.*.category_name' => 'min:1|max:255|nullable',
'transactions.*.piggy_bank_id' => ['nullable', 'numeric', 'mustExist:piggy_banks,id', new BelongsUser()],
'transactions.*.piggy_bank_name' => ['between:1,255', 'nullable', new BelongsUser()],
'transactions.*.tags' => 'nullable|between:1,64000',
'transactions.*.piggy_bank_name' => ['min:1', 'max:255', 'nullable', new BelongsUser()],
'transactions.*.tags' => 'nullable|min:1|max:255',
];
}
@@ -140,6 +142,9 @@ class UpdateRequest extends FormRequest
$this->valUpdateAccountInfo($validator);
}
);
if($validator->fails()) {
Log::channel('audit')->error(sprintf('Validation errors in %s', __CLASS__), $validator->errors()->toArray());
}
}
/**
@@ -164,15 +169,15 @@ class UpdateRequest extends FormRequest
}
if (array_key_exists('moment', $repetition)) {
$current['moment'] = (string)$repetition['moment'];
$current['moment'] = (string) $repetition['moment'];
}
if (array_key_exists('skip', $repetition)) {
$current['skip'] = (int)$repetition['skip'];
$current['skip'] = (int) $repetition['skip'];
}
if (array_key_exists('weekend', $repetition)) {
$current['weekend'] = (int)$repetition['weekend'];
$current['weekend'] = (int) $repetition['weekend'];
}
$return[] = $current;
}

View File

@@ -28,6 +28,7 @@ use FireflyIII\Support\Request\ChecksLogin;
use FireflyIII\Support\Request\ConvertsDataTypes;
use FireflyIII\Support\Request\GetRuleConfiguration;
use Illuminate\Foundation\Http\FormRequest;
use Illuminate\Support\Facades\Log;
use Illuminate\Validation\Validator;
/**
@@ -76,10 +77,10 @@ class StoreRequest extends FormRequest
$contextActions = implode(',', config('firefly.context-rule-actions'));
return [
'title' => 'required|between:1,100|uniqueObjectForUser:rules,title',
'description' => 'between:1,5000|nullable',
'title' => 'required|min:1|max:100|uniqueObjectForUser:rules,title',
'description' => 'min:1|max:32768|nullable',
'rule_group_id' => 'belongsToUser:rule_groups|required_without:rule_group_title',
'rule_group_title' => 'nullable|between:1,255|required_without:rule_group_id|belongsToUser:rule_groups,title',
'rule_group_title' => 'nullable|min:1|max:255|required_without:rule_group_id|belongsToUser:rule_groups,title',
'trigger' => 'required|in:store-journal,update-journal',
'triggers.*.type' => 'required|in:'.implode(',', $validTriggers),
'triggers.*.value' => 'required_if:actions.*.type,'.$contextTriggers.'|min:1|ruleTriggerValue|max:1024',
@@ -108,6 +109,9 @@ class StoreRequest extends FormRequest
$this->atLeastOneActiveAction($validator);
}
);
if($validator->fails()) {
Log::channel('audit')->error(sprintf('Validation errors in %s', __CLASS__), $validator->errors()->toArray());
}
}
/**

View File

@@ -29,6 +29,7 @@ use FireflyIII\Support\Request\ChecksLogin;
use FireflyIII\Support\Request\ConvertsDataTypes;
use FireflyIII\Support\Request\GetRuleConfiguration;
use Illuminate\Foundation\Http\FormRequest;
use Illuminate\Support\Facades\Log;
use Illuminate\Validation\Validator;
/**
@@ -85,10 +86,10 @@ class UpdateRequest extends FormRequest
$contextActions = implode(',', config('firefly.context-rule-actions'));
return [
'title' => sprintf('between:1,100|uniqueObjectForUser:rules,title,%d', $rule->id),
'description' => 'between:1,5000|nullable',
'title' => sprintf('min:1|max:100|uniqueObjectForUser:rules,title,%d', $rule->id),
'description' => 'min:1|max:32768|nullable',
'rule_group_id' => 'belongsToUser:rule_groups',
'rule_group_title' => 'nullable|between:1,255|belongsToUser:rule_groups,title',
'rule_group_title' => 'nullable|min:1|max:255|belongsToUser:rule_groups,title',
'trigger' => 'in:store-journal,update-journal',
'triggers.*.type' => 'required|in:'.implode(',', $validTriggers),
'triggers.*.value' => 'required_if:actions.*.type,'.$contextTriggers.'|min:1|ruleTriggerValue|max:1024',
@@ -101,7 +102,7 @@ class UpdateRequest extends FormRequest
'strict' => [new IsBoolean()],
'stop_processing' => [new IsBoolean()],
'active' => [new IsBoolean()],
'order' => 'numeric|between:1,1337',
'order' => 'numeric|min:1|max:2048',
];
}
@@ -118,6 +119,9 @@ class UpdateRequest extends FormRequest
$this->atLeastOneValidAction($validator);
}
);
if($validator->fails()) {
Log::channel('audit')->error(sprintf('Validation errors in %s', __CLASS__), $validator->errors()->toArray());
}
}
/**

View File

@@ -64,8 +64,8 @@ class StoreRequest extends FormRequest
public function rules(): array
{
return [
'title' => 'required|between:1,100|uniqueObjectForUser:rule_groups,title',
'description' => 'between:1,5000|nullable',
'title' => 'required|min:1|max:100|uniqueObjectForUser:rule_groups,title',
'description' => 'min:1|max:32768|nullable',
'active' => [new IsBoolean()],
];
}

View File

@@ -62,8 +62,8 @@ class UpdateRequest extends FormRequest
$ruleGroup = $this->route()->parameter('ruleGroup');
return [
'title' => 'between:1,100|uniqueObjectForUser:rule_groups,title,'.$ruleGroup->id,
'description' => 'between:1,5000|nullable',
'title' => 'min:1|max:100|uniqueObjectForUser:rule_groups,title,'.$ruleGroup->id,
'description' => 'min:1|max:32768|nullable',
'active' => [new IsBoolean()],
];
}

View File

@@ -60,7 +60,7 @@ class StoreRequest extends FormRequest
{
$rules = [
'tag' => 'required|min:1|uniqueObjectForUser:tags,tag|max:1024',
'description' => 'min:1|nullable|max:65536',
'description' => 'min:1|nullable|max:32768',
'date' => 'date|nullable',
];

View File

@@ -66,7 +66,7 @@ class UpdateRequest extends FormRequest
// TODO check if uniqueObjectForUser is obsolete
$rules = [
'tag' => 'min:1|max:1024|uniqueObjectForUser:tags,tag,'.$tag->id,
'description' => 'min:1|nullable|max:65536',
'description' => 'min:1|nullable|max:32768',
'date' => 'date|nullable',
];

View File

@@ -27,6 +27,8 @@ namespace FireflyIII\Api\V1\Requests\Models\Transaction;
use FireflyIII\Rules\BelongsUser;
use FireflyIII\Rules\IsBoolean;
use FireflyIII\Rules\IsDateOrTime;
use FireflyIII\Rules\IsValidPositiveAmount;
use FireflyIII\Rules\IsValidZeroOrMoreAmount;
use FireflyIII\Support\NullArrayObject;
use FireflyIII\Support\Request\AppendsLocationData;
use FireflyIII\Support\Request\ChecksLogin;
@@ -35,6 +37,7 @@ use FireflyIII\Validation\CurrencyValidation;
use FireflyIII\Validation\GroupValidation;
use FireflyIII\Validation\TransactionValidation;
use Illuminate\Foundation\Http\FormRequest;
use Illuminate\Support\Facades\Log;
use Illuminate\Validation\Validator;
/**
@@ -76,7 +79,7 @@ class StoreRequest extends FormRequest
return [
// basic fields for group:
'group_title' => 'between:1,1000|nullable',
'group_title' => 'min:1|max:1000|nullable',
'error_if_duplicate_hash' => [new IsBoolean()],
'apply_rules' => [new IsBoolean()],
@@ -92,40 +95,41 @@ class StoreRequest extends FormRequest
'transactions.*.foreign_currency_code' => 'min:3|max:51|exists:transaction_currencies,code|nullable',
// amount
'transactions.*.amount' => 'required|numeric|gt:0',
'transactions.*.foreign_amount' => 'numeric',
'transactions.*.amount' => ['required', new IsValidPositiveAmount()],
'transactions.*.foreign_amount' => ['nullable', new IsValidZeroOrMoreAmount()],
// description
'transactions.*.description' => 'nullable|between:1,1000',
'transactions.*.description' => 'nullable|min:1|max:1000',
// source of transaction
'transactions.*.source_id' => ['numeric', 'nullable', new BelongsUser()],
'transactions.*.source_name' => 'between:1,255|nullable',
'transactions.*.source_iban' => 'between:1,255|nullable|iban',
'transactions.*.source_number' => 'between:1,255|nullable',
'transactions.*.source_bic' => 'between:1,255|nullable|bic',
'transactions.*.source_name' => 'min:1|max:255|nullable',
'transactions.*.source_iban' => 'min:1|max:255|nullable|iban',
'transactions.*.source_number' => 'min:1|max:255|nullable',
'transactions.*.source_bic' => 'min:1|max:255|nullable|bic',
// destination of transaction
'transactions.*.destination_id' => ['numeric', 'nullable', new BelongsUser()],
'transactions.*.destination_name' => 'between:1,255|nullable',
'transactions.*.destination_iban' => 'between:1,255|nullable|iban',
'transactions.*.destination_number' => 'between:1,255|nullable',
'transactions.*.destination_bic' => 'between:1,255|nullable|bic',
'transactions.*.destination_name' => 'min:1|max:255|nullable',
'transactions.*.destination_iban' => 'min:1|max:255|nullable|iban',
'transactions.*.destination_number' => 'min:1|max:255|nullable',
'transactions.*.destination_bic' => 'min:1|max:255|nullable|bic',
// budget, category, bill and piggy
'transactions.*.budget_id' => ['mustExist:budgets,id', new BelongsUser()],
'transactions.*.budget_name' => ['between:1,255', 'nullable', new BelongsUser()],
'transactions.*.budget_name' => ['min:1', 'max:255', 'nullable', new BelongsUser()],
'transactions.*.category_id' => ['mustExist:categories,id', new BelongsUser(), 'nullable'],
'transactions.*.category_name' => 'between:1,255|nullable',
'transactions.*.category_name' => 'min:1|max:255|nullable',
'transactions.*.bill_id' => ['numeric', 'nullable', 'mustExist:bills,id', new BelongsUser()],
'transactions.*.bill_name' => ['between:1,255', 'nullable', new BelongsUser()],
'transactions.*.bill_name' => ['min:1', 'max:255', 'nullable', new BelongsUser()],
'transactions.*.piggy_bank_id' => ['numeric', 'nullable', 'mustExist:piggy_banks,id', new BelongsUser()],
'transactions.*.piggy_bank_name' => ['between:1,255', 'nullable', new BelongsUser()],
'transactions.*.piggy_bank_name' => ['min:1', 'max:255', 'nullable', new BelongsUser()],
// other interesting fields
'transactions.*.reconciled' => [new IsBoolean()],
'transactions.*.notes' => 'min:1|max:50000|nullable',
'transactions.*.tags' => 'between:0,255',
'transactions.*.notes' => 'min:1|max:32768|nullable',
'transactions.*.tags' => 'min:0|max:255',
'transactions.*.tags.*' => 'min:0|max:255',
// meta info fields
'transactions.*.internal_reference' => 'min:1|max:255|nullable',
@@ -188,6 +192,9 @@ class StoreRequest extends FormRequest
$this->validateGroupDescription($validator);
}
);
if($validator->fails()) {
Log::channel('audit')->error(sprintf('Validation errors in %s', __CLASS__), $validator->errors()->toArray());
}
}
/**

View File

@@ -29,11 +29,14 @@ use FireflyIII\Models\TransactionGroup;
use FireflyIII\Rules\BelongsUser;
use FireflyIII\Rules\IsBoolean;
use FireflyIII\Rules\IsDateOrTime;
use FireflyIII\Rules\IsValidPositiveAmount;
use FireflyIII\Rules\IsValidZeroOrMoreAmount;
use FireflyIII\Support\Request\ChecksLogin;
use FireflyIII\Support\Request\ConvertsDataTypes;
use FireflyIII\Validation\GroupValidation;
use FireflyIII\Validation\TransactionValidation;
use Illuminate\Foundation\Http\FormRequest;
use Illuminate\Support\Facades\Log;
use Illuminate\Validation\Validator;
/**
@@ -97,7 +100,7 @@ class UpdateRequest extends FormRequest
return [
// basic fields for group:
'group_title' => 'between:1,1000|nullable',
'group_title' => 'min:1|max:1000|nullable',
'apply_rules' => [new IsBoolean()],
// transaction rules (in array for splits):
@@ -115,32 +118,33 @@ class UpdateRequest extends FormRequest
'transactions.*.foreign_currency_code' => 'nullable|min:3|max:51|exists:transaction_currencies,code',
// amount
'transactions.*.amount' => 'numeric|gt:0|max:100000000000',
'transactions.*.foreign_amount' => 'nullable|numeric|gte:0',
'transactions.*.amount' => ['nullable', new IsValidPositiveAmount()],
'transactions.*.foreign_amount' => ['nullable', new IsValidZeroOrMoreAmount()],
// description
'transactions.*.description' => 'nullable|between:1,1000',
'transactions.*.description' => 'nullable|min:1|max:1000',
// source of transaction
'transactions.*.source_id' => ['numeric', 'nullable', new BelongsUser()],
'transactions.*.source_name' => 'between:1,255|nullable',
'transactions.*.source_name' => 'min:1|max:255|nullable',
// destination of transaction
'transactions.*.destination_id' => ['numeric', 'nullable', new BelongsUser()],
'transactions.*.destination_name' => 'between:1,255|nullable',
'transactions.*.destination_name' => 'min:1|max:255|nullable',
// budget, category, bill and piggy
'transactions.*.budget_id' => ['mustExist:budgets,id', new BelongsUser(), 'nullable'],
'transactions.*.budget_name' => ['between:1,255', 'nullable', new BelongsUser()],
'transactions.*.budget_name' => ['min:1', 'max:255', 'nullable', new BelongsUser()],
'transactions.*.category_id' => ['mustExist:categories,id', new BelongsUser(), 'nullable'],
'transactions.*.category_name' => 'between:1,255|nullable',
'transactions.*.category_name' => 'min:1|max:255|nullable',
'transactions.*.bill_id' => ['numeric', 'nullable', 'mustExist:bills,id', new BelongsUser()],
'transactions.*.bill_name' => ['between:1,255', 'nullable', new BelongsUser()],
'transactions.*.bill_name' => ['min:1', 'max:255', 'nullable', new BelongsUser()],
// other interesting fields
'transactions.*.reconciled' => [new IsBoolean()],
'transactions.*.notes' => 'min:1|max:50000|nullable',
'transactions.*.tags' => 'between:0,255|nullable',
'transactions.*.notes' => 'min:1|max:32768|nullable',
'transactions.*.tags' => 'min:0|max:255|nullable',
'transactions.*.tags.*' => 'min:0|max:255',
// meta info fields
'transactions.*.internal_reference' => 'min:1|max:255|nullable',
@@ -202,6 +206,9 @@ class UpdateRequest extends FormRequest
$this->validateAccountInformationUpdate($validator, $transactionGroup);
}
);
if($validator->fails()) {
Log::channel('audit')->error(sprintf('Validation errors in %s', __CLASS__), $validator->errors()->toArray());
}
}
/**

View File

@@ -66,10 +66,10 @@ class StoreRequest extends FormRequest
public function rules(): array
{
return [
'name' => 'required|between:1,255|unique:transaction_currencies,name',
'code' => 'required|between:3,51|unique:transaction_currencies,code',
'symbol' => 'required|between:1,51|unique:transaction_currencies,symbol',
'decimal_places' => 'between:0,20|numeric|min:0|max:12',
'name' => 'required|min:1|max:255|unique:transaction_currencies,name',
'code' => 'required|min:3|max:32|unique:transaction_currencies,code',
'symbol' => 'required|min:1|max:32|unique:transaction_currencies,symbol',
'decimal_places' => 'numeric|min:0|max:12',
'enabled' => [new IsBoolean()],
'default' => [new IsBoolean()],
];

View File

@@ -42,7 +42,7 @@ class UpdateRequest extends FormRequest
*/
public function getAll(): array
{
// return nothing that isn't explicitely in the array:
// return nothing that isn't explicitly in the array:
$fields = [
'name' => ['name', 'convertString'],
'code' => ['code', 'convertString'],
@@ -64,10 +64,10 @@ class UpdateRequest extends FormRequest
$currency = $this->route()->parameter('currency_code');
return [
'name' => sprintf('between:1,255|unique:transaction_currencies,name,%d', $currency->id),
'code' => sprintf('between:3,51|unique:transaction_currencies,code,%d', $currency->id),
'symbol' => sprintf('between:1,51|unique:transaction_currencies,symbol,%d', $currency->id),
'decimal_places' => 'between:0,20|numeric|min:0|max:12',
'name' => sprintf('min:1|max:255|unique:transaction_currencies,name,%d', $currency->id),
'code' => sprintf('min:3|max:32|unique:transaction_currencies,code,%d', $currency->id),
'symbol' => sprintf('min:1|max:32|unique:transaction_currencies,symbol,%d', $currency->id),
'decimal_places' => 'numeric|min:0|max:12',
'enabled' => [new IsBoolean()],
'default' => [new IsBoolean()],
];

View File

@@ -29,6 +29,7 @@ use FireflyIII\Support\Request\ChecksLogin;
use FireflyIII\Support\Request\ConvertsDataTypes;
use FireflyIII\User;
use Illuminate\Foundation\Http\FormRequest;
use Illuminate\Support\Facades\Log;
use Illuminate\Validation\Validator;
/**
@@ -63,7 +64,7 @@ class StoreRequest extends FormRequest
'link_type_name' => 'exists:link_types,name|required_without:link_type_id',
'inward_id' => 'required|belongsToUser:transaction_journals,id|different:outward_id',
'outward_id' => 'required|belongsToUser:transaction_journals,id|different:inward_id',
'notes' => 'between:0,65000',
'notes' => 'min:1|max:32768|nullable',
];
}
@@ -77,6 +78,9 @@ class StoreRequest extends FormRequest
$this->validateExistingLink($validator);
}
);
if($validator->fails()) {
Log::channel('audit')->error(sprintf('Validation errors in %s', __CLASS__), $validator->errors()->toArray());
}
}
private function validateExistingLink(Validator $validator): void

View File

@@ -29,6 +29,7 @@ use FireflyIII\Repositories\LinkType\LinkTypeRepositoryInterface;
use FireflyIII\Support\Request\ChecksLogin;
use FireflyIII\Support\Request\ConvertsDataTypes;
use Illuminate\Foundation\Http\FormRequest;
use Illuminate\Support\Facades\Log;
use Illuminate\Validation\Validator;
/**
@@ -63,7 +64,7 @@ class UpdateRequest extends FormRequest
'link_type_name' => 'exists:link_types,name',
'inward_id' => 'belongsToUser:transaction_journals,id|different:outward_id',
'outward_id' => 'belongsToUser:transaction_journals,id|different:inward_id',
'notes' => 'between:0,65000',
'notes' => 'min:1|max:32768|nullable',
];
}
@@ -77,6 +78,9 @@ class UpdateRequest extends FormRequest
$this->validateUpdate($validator);
}
);
if($validator->fails()) {
Log::channel('audit')->error(sprintf('Validation errors in %s', __CLASS__), $validator->errors()->toArray());
}
}
private function validateUpdate(Validator $validator): void

View File

@@ -72,7 +72,7 @@ class CreateRequest extends FormRequest
$validProtocols = config('firefly.valid_url_protocols');
return [
'title' => 'required|between:1,512|uniqueObjectForUser:webhooks,title',
'title' => 'required|min:1|max:255|uniqueObjectForUser:webhooks,title',
'active' => [new IsBoolean()],
'trigger' => sprintf('required|in:%s', $triggers),
'response' => sprintf('required|in:%s', $responses),

View File

@@ -85,7 +85,7 @@ class UpdateRequest extends FormRequest
$webhook = $this->route()->parameter('webhook');
return [
'title' => sprintf('between:1,512|uniqueObjectForUser:webhooks,title,%d', $webhook->id),
'title' => sprintf('min:1|max:255|uniqueObjectForUser:webhooks,title,%d', $webhook->id),
'active' => [new IsBoolean()],
'trigger' => sprintf('in:%s', $triggers),
'response' => sprintf('in:%s', $responses),

View File

@@ -65,7 +65,7 @@ class UpdateRequest extends FormRequest
return ['value' => ['required', new IsBoolean()]];
}
if ('configuration.permission_update_check' === $name) {
return ['value' => 'required|numeric|between:-1,1'];
return ['value' => 'required|numeric|min:-1|max:1'];
}
if ('configuration.last_update_check' === $name) {
return ['value' => 'required|numeric|min:464272080'];

View File

@@ -29,6 +29,7 @@ use FireflyIII\Support\Request\ChecksLogin;
use FireflyIII\Support\Request\ConvertsDataTypes;
use FireflyIII\User;
use Illuminate\Foundation\Http\FormRequest;
use Illuminate\Support\Facades\Log;
use Illuminate\Validation\Validator;
/**
@@ -97,5 +98,8 @@ class UserUpdateRequest extends FormRequest
}
}
);
if($validator->fails()) {
Log::channel('audit')->error(sprintf('Validation errors in %s', __CLASS__), $validator->errors()->toArray());
}
}
}

View File

@@ -0,0 +1,83 @@
<?php
/*
* CategoryController.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\Autocomplete;
use FireflyIII\Api\V2\Controllers\Controller;
use FireflyIII\Api\V2\Request\Autocomplete\AutocompleteRequest;
use FireflyIII\Models\Category;
use FireflyIII\Repositories\UserGroups\Category\CategoryRepositoryInterface;
use Illuminate\Http\JsonResponse;
/**
* Class CategoryController
*/
class CategoryController extends Controller
{
private CategoryRepositoryInterface $repository;
/**
* AccountController constructor.
*/
public function __construct()
{
parent::__construct();
$this->middleware(
function ($request, $next) {
$this->repository = app(CategoryRepositoryInterface::class);
$userGroup = $this->validateUserGroup($request);
if (null !== $userGroup) {
$this->repository->setUserGroup($userGroup);
}
return $next($request);
}
);
}
/**
* Documentation for this endpoint:
* TODO list of checks
* 1. use dates from ParameterBag
* 2. Request validates dates
* 3. Request includes user_group_id
* 4. Endpoint is documented.
* 5. Collector uses user_group_id
*/
public function categories(AutocompleteRequest $request): JsonResponse
{
$data = $request->getData();
$result = $this->repository->searchCategory($data['query'], $this->parameters->get('limit'));
$filtered = $result->map(
static function (Category $item) {
return [
'id' => (string) $item->id,
'name' => $item->name,
];
}
);
return response()->json($filtered);
}
}

View File

@@ -0,0 +1,85 @@
<?php
/*
* CategoryController.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\Autocomplete;
use FireflyIII\Api\V2\Controllers\Controller;
use FireflyIII\Api\V2\Request\Autocomplete\AutocompleteRequest;
use FireflyIII\Models\Tag;
use FireflyIII\Repositories\UserGroups\Tag\TagRepositoryInterface;
use Illuminate\Http\JsonResponse;
/**
* Class TagController
*/
class TagController extends Controller
{
private TagRepositoryInterface $repository;
/**
* AccountController constructor.
*/
public function __construct()
{
parent::__construct();
$this->middleware(
function ($request, $next) {
$this->repository = app(TagRepositoryInterface::class);
$userGroup = $this->validateUserGroup($request);
if (null !== $userGroup) {
$this->repository->setUserGroup($userGroup);
}
return $next($request);
}
);
}
/**
* Documentation for this endpoint:
* TODO list of checks
* 1. use dates from ParameterBag
* 2. Request validates dates
* 3. Request includes user_group_id
* 4. Endpoint is documented.
* 5. Collector uses user_group_id
*/
public function tags(AutocompleteRequest $request): JsonResponse
{
$data = $request->getData();
$result = $this->repository->searchTag($data['query'], $data['limit']);
$filtered = $result->map(
static function (Tag $item) {
return [
'id' => (string) $item->id,
'name' => $item->tag,
'value' => (string) $item->id,
'label' => $item->tag,
];
}
);
return response()->json($filtered);
}
}

View File

@@ -134,10 +134,10 @@ class AccountController extends Controller
'currency_decimal_places' => $currency->decimal_places,
// the default currency of the user (could be the same!)
'native_id' => (string)$default->id,
'native_code' => $default->code,
'native_symbol' => $default->symbol,
'native_decimal_places' => $default->decimal_places,
'native_currency_id' => (string)$default->id,
'native_currency_code' => $default->code,
'native_currency_symbol' => $default->symbol,
'native_currency_decimal_places' => $default->decimal_places,
'start' => $start->toAtomString(),
'end' => $end->toAtomString(),
'period' => '1D',

View File

@@ -39,6 +39,7 @@ use FireflyIII\Support\Http\Api\ExchangeRateConverter;
use FireflyIII\Support\Http\Api\ValidatesUserGroupTrait;
use Illuminate\Http\JsonResponse;
use Illuminate\Support\Collection;
use Illuminate\Support\Facades\Log;
/**
* Class BudgetController
@@ -76,11 +77,7 @@ class BudgetController extends Controller
}
/**
* @param DateRequest $request
*
* TODO see autocomplete/accountcontroller
*
* @throws FireflyException
*/
public function dashboard(DateRequest $request): JsonResponse
{
@@ -127,14 +124,14 @@ class BudgetController extends Controller
foreach ($rows as $row) {
$current = [
'label' => $budget->name,
'currency_id' => (string)$row['currency_id'],
'currency_id' => (string) $row['currency_id'],
'currency_code' => $row['currency_code'],
'currency_name' => $row['currency_name'],
'currency_decimal_places' => $row['currency_decimal_places'],
'native_id' => (string)$row['native_id'],
'native_code' => $row['native_code'],
'native_name' => $row['native_name'],
'native_decimal_places' => $row['native_decimal_places'],
'native_currency_id' => (string) $row['native_currency_id'],
'native_currency_code' => $row['native_currency_code'],
'native_currency_name' => $row['native_currency_name'],
'native_currency_decimal_places' => $row['native_currency_decimal_places'],
'period' => null,
'start' => $row['start'],
'end' => $row['end'],
@@ -169,7 +166,8 @@ class BudgetController extends Controller
}
/**
* Shared between the "noBudgetLimits" function and "processLimit". Will take a single set of expenses and return its info.
* Shared between the "noBudgetLimits" function and "processLimit". Will take a single set of expenses and return
* its info.
*
* @param array<int, array<int, string>> $array
*
@@ -177,6 +175,7 @@ class BudgetController extends Controller
*/
private function processExpenses(int $budgetId, array $array, Carbon $start, Carbon $end): array
{
Log::debug(sprintf('Created new ExchangeRateConverter in %s', __METHOD__));
$converter = new ExchangeRateConverter();
$return = [];
@@ -190,16 +189,16 @@ class BudgetController extends Controller
foreach ($array as $currencyId => $block) {
$this->currencies[$currencyId] ??= TransactionCurrency::find($currencyId);
$return[$currencyId] ??= [
'currency_id' => (string)$currencyId,
'currency_id' => (string) $currencyId,
'currency_code' => $block['currency_code'],
'currency_name' => $block['currency_name'],
'currency_symbol' => $block['currency_symbol'],
'currency_decimal_places' => (int)$block['currency_decimal_places'],
'native_id' => (string)$this->currency->id,
'native_code' => $this->currency->code,
'native_name' => $this->currency->name,
'native_symbol' => $this->currency->symbol,
'native_decimal_places' => $this->currency->decimal_places,
'currency_decimal_places' => (int) $block['currency_decimal_places'],
'native_currency_id' => (string) $this->currency->id,
'native_currency_code' => $this->currency->code,
'native_currency_name' => $this->currency->name,
'native_currency_symbol' => $this->currency->symbol,
'native_currency_decimal_places' => $this->currency->decimal_places,
'start' => $start->toAtomString(),
'end' => $end->toAtomString(),
'spent' => '0',
@@ -258,6 +257,7 @@ class BudgetController extends Controller
*/
private function processLimit(Budget $budget, BudgetLimit $limit): array
{
Log::debug(sprintf('Created new ExchangeRateConverter in %s', __METHOD__));
$end = clone $limit->end_date;
$end->endOfDay();
$spent = $this->opsRepository->listExpenses($limit->start_date, $end, null, new Collection([$budget]));

View File

@@ -37,6 +37,7 @@ use FireflyIII\Support\Http\Api\CleansChartData;
use FireflyIII\Support\Http\Api\ExchangeRateConverter;
use FireflyIII\Support\Http\Api\ValidatesUserGroupTrait;
use Illuminate\Http\JsonResponse;
use Illuminate\Support\Facades\Log;
/**
* Class BudgetController
@@ -76,6 +77,8 @@ class CategoryController extends Controller
*/
public function dashboard(DateRequest $request): JsonResponse
{
Log::debug(sprintf('Created new ExchangeRateConverter in %s', __METHOD__));
/** @var Carbon $start */
$start = $this->parameters->get('start');
@@ -115,11 +118,11 @@ class CategoryController extends Controller
'currency_name' => $currency->name,
'currency_symbol' => $currency->symbol,
'currency_decimal_places' => $currency->decimal_places,
'native_id' => (string)$default->id,
'native_code' => $default->code,
'native_name' => $default->name,
'native_symbol' => $default->symbol,
'native_decimal_places' => $default->decimal_places,
'native_currency_id' => (string)$default->id,
'native_currency_code' => $default->code,
'native_currency_name' => $default->name,
'native_currency_symbol' => $default->symbol,
'native_currency_decimal_places' => $default->decimal_places,
'period' => null,
'start' => $start->toAtomString(),
'end' => $end->toAtomString(),

View File

@@ -28,6 +28,7 @@ use FireflyIII\Api\V2\Controllers\Controller;
use FireflyIII\Api\V2\Request\Generic\DateRequest;
use FireflyIII\Models\Budget;
use FireflyIII\Repositories\Budget\BudgetRepositoryInterface;
use FireflyIII\Transformers\V2\BudgetTransformer;
use Illuminate\Http\JsonResponse;
/**
@@ -50,6 +51,20 @@ class ShowController extends Controller
);
}
/**
* Show a budget.
*/
public function show(Budget $budget): JsonResponse
{
$transformer = new BudgetTransformer();
$transformer->setParameters($this->parameters);
return response()
->api($this->jsonApiObject('budgets', $budget, $transformer))
->header('Content-Type', self::CONTENT_TYPE)
;
}
/**
* 2023-10-29 removed the cerSum reference, not sure where this is used atm
* so removed from api.php. Also applies to "spent" method.

View File

@@ -0,0 +1,65 @@
<?php
/*
* IndexController.php
* Copyright (c) 2023 james@firefly-iii.org
*
* This file is part of Firefly III (https://github.com/firefly-iii).
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
declare(strict_types=1);
namespace FireflyIII\Api\V2\Controllers\Model\BudgetLimit;
use FireflyIII\Api\V2\Controllers\Controller;
use FireflyIII\Models\Budget;
use FireflyIII\Repositories\Budget\BudgetLimitRepositoryInterface;
use FireflyIII\Transformers\V2\BudgetLimitTransformer;
use Illuminate\Http\JsonResponse;
use Illuminate\Pagination\LengthAwarePaginator;
class IndexController extends Controller
{
private BudgetLimitRepositoryInterface $repository;
public function __construct()
{
parent::__construct();
$this->middleware(
function ($request, $next) {
$this->repository = app(BudgetLimitRepositoryInterface::class);
return $next($request);
}
);
}
/**
* This endpoint is documented at:
* TODO add URL
*/
public function index(Budget $budget): JsonResponse
{
$pageSize = $this->parameters->get('limit');
$collection = $this->repository->getBudgetLimits($budget);
$total = $collection->count();
$collection->slice($pageSize * $this->parameters->get('page'), $pageSize);
$paginator = new LengthAwarePaginator($collection, $total, $pageSize, $this->parameters->get('page'));
$transformer = new BudgetLimitTransformer();
return response()->api($this->jsonApiList('budget-limits', $paginator, $transformer))->header('Content-Type', self::CONTENT_TYPE);
}
}

View File

@@ -0,0 +1,43 @@
<?php
/*
* ShowController.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\Model\Transaction;
use FireflyIII\Api\V2\Controllers\Controller;
use FireflyIII\Models\TransactionGroup;
use FireflyIII\Transformers\V2\TransactionGroupTransformer;
use Illuminate\Http\JsonResponse;
class ShowController extends Controller
{
/**
* TODO this endpoint is not yet reachable.
*/
public function show(TransactionGroup $transactionGroup): JsonResponse
{
$transformer = new TransactionGroupTransformer();
$transformer->setParameters($this->parameters);
return response()->api($this->jsonApiObject('transactions', $transactionGroup, $transformer))->header('Content-Type', self::CONTENT_TYPE);
}
}

View File

@@ -0,0 +1,93 @@
<?php
/*
* UpdateController.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\Model\Transaction;
use FireflyIII\Api\V2\Controllers\Controller;
use FireflyIII\Api\V2\Request\Model\Transaction\UpdateRequest;
use FireflyIII\Events\UpdatedTransactionGroup;
use FireflyIII\Exceptions\FireflyException;
use FireflyIII\Helpers\Collector\GroupCollectorInterface;
use FireflyIII\Models\TransactionGroup;
use FireflyIII\Repositories\TransactionGroup\TransactionGroupRepositoryInterface;
use FireflyIII\Transformers\V2\TransactionGroupTransformer;
use FireflyIII\User;
use Illuminate\Http\JsonResponse;
class UpdateController extends Controller
{
private TransactionGroupRepositoryInterface $groupRepository;
/**
* TransactionController constructor.
*/
public function __construct()
{
parent::__construct();
$this->middleware(
function ($request, $next) {
$this->groupRepository = app(TransactionGroupRepositoryInterface::class);
return $next($request);
}
);
}
/**
* This endpoint is documented at:
* https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/transactions/updateTransaction
*
* Update a transaction.
*
* @throws FireflyException
*/
public function update(UpdateRequest $request, TransactionGroup $transactionGroup): JsonResponse
{
app('log')->debug('Now in update routine for transaction group [v2]!');
$data = $request->getAll();
$transactionGroup = $this->groupRepository->update($transactionGroup, $data);
$applyRules = $data['apply_rules'] ?? true;
$fireWebhooks = $data['fire_webhooks'] ?? true;
event(new UpdatedTransactionGroup($transactionGroup, $applyRules, $fireWebhooks));
app('preferences')->mark();
/** @var User $admin */
$admin = auth()->user();
// use new group collector:
/** @var GroupCollectorInterface $collector */
$collector = app(GroupCollectorInterface::class);
$collector->setUser($admin)->setTransactionGroup($transactionGroup);
$selectedGroup = $collector->getGroups()->first();
if (null === $selectedGroup) {
throw new FireflyException('200032: Cannot find transaction. Possibly, a rule deleted this transaction after its creation.');
}
$transformer = new TransactionGroupTransformer();
$transformer->setParameters($this->parameters);
return response()->api($this->jsonApiObject('transactions', $selectedGroup, $transformer))->header('Content-Type', self::CONTENT_TYPE);
}
}

View File

@@ -45,6 +45,7 @@ use FireflyIII\Support\Http\Api\SummaryBalanceGrouped;
use FireflyIII\Support\Http\Api\ValidatesUserGroupTrait;
use FireflyIII\User;
use Illuminate\Http\JsonResponse;
use Illuminate\Support\Facades\Log;
/**
* Class BasicController
@@ -205,10 +206,10 @@ class BasicController extends Controller
$return[] = [
'key' => 'bills-paid-in-native',
'value' => $nativeAmount,
'currency_id' => (string)$info['native_id'],
'currency_code' => $info['native_code'],
'currency_symbol' => $info['native_symbol'],
'currency_decimal_places' => $info['native_decimal_places'],
'currency_id' => (string)$info['native_currency_id'],
'currency_code' => $info['native_currency_code'],
'currency_symbol' => $info['native_currency_symbol'],
'currency_decimal_places' => $info['native_currency_decimal_places'],
];
}
@@ -229,10 +230,10 @@ class BasicController extends Controller
$return[] = [
'key' => 'bills-unpaid-in-native',
'value' => $nativeAmount,
'currency_id' => (string)$info['native_id'],
'currency_code' => $info['native_code'],
'currency_symbol' => $info['native_symbol'],
'currency_decimal_places' => $info['native_decimal_places'],
'currency_id' => (string)$info['native_currency_id'],
'currency_code' => $info['native_currency_code'],
'currency_symbol' => $info['native_currency_symbol'],
'currency_decimal_places' => $info['native_currency_decimal_places'],
];
}
@@ -244,6 +245,7 @@ class BasicController extends Controller
*/
private function getLeftToSpendInfo(Carbon $start, Carbon $end): array
{
Log::debug(sprintf('Created new ExchangeRateConverter in %s', __METHOD__));
app('log')->debug('Now in getLeftToSpendInfo');
$return = [];
$today = today(config('app.timezone'));

View File

@@ -28,6 +28,7 @@ use FireflyIII\Support\Http\Api\ValidatesUserGroupTrait;
use FireflyIII\Support\Request\ChecksLogin;
use FireflyIII\Support\Request\ConvertsDataTypes;
use Illuminate\Foundation\Http\FormRequest;
use Illuminate\Support\Facades\Log;
use Illuminate\Validation\Validator;
/**
@@ -79,5 +80,8 @@ class BalanceChartRequest extends FormRequest
}
}
);
if($validator->fails()) {
Log::channel('audit')->error(sprintf('Validation errors in %s', __CLASS__), $validator->errors()->toArray());
}
}
}

View File

@@ -27,6 +27,7 @@ use FireflyIII\Support\Http\Api\ValidatesUserGroupTrait;
use FireflyIII\Support\Request\ChecksLogin;
use FireflyIII\Support\Request\ConvertsDataTypes;
use Illuminate\Foundation\Http\FormRequest;
use Illuminate\Support\Facades\Log;
use Illuminate\Validation\Validator;
/**
@@ -77,5 +78,8 @@ class DashboardChartRequest extends FormRequest
}
}
);
if($validator->fails()) {
Log::channel('audit')->error(sprintf('Validation errors in %s', __CLASS__), $validator->errors()->toArray());
}
}
}

View File

@@ -28,6 +28,7 @@ use FireflyIII\Models\UserGroup;
use FireflyIII\Rules\BelongsUserGroup;
use FireflyIII\Rules\IsBoolean;
use FireflyIII\Rules\IsDateOrTime;
use FireflyIII\Rules\IsValidPositiveAmount;
use FireflyIII\Support\NullArrayObject;
use FireflyIII\Support\Request\AppendsLocationData;
use FireflyIII\Support\Request\ChecksLogin;
@@ -37,6 +38,7 @@ use FireflyIII\Validation\CurrencyValidation;
use FireflyIII\Validation\GroupValidation;
use FireflyIII\Validation\TransactionValidation;
use Illuminate\Foundation\Http\FormRequest;
use Illuminate\Support\Facades\Log;
use Illuminate\Validation\Validator;
/**
@@ -74,7 +76,6 @@ class StoreRequest extends FormRequest
'fire_webhooks' => $this->boolean('fire_webhooks', true),
'transactions' => $this->getTransactionData(),
];
// TODO include location and ability to process it.
}
/**
@@ -91,7 +92,7 @@ class StoreRequest extends FormRequest
return [
// basic fields for group:
'group_title' => 'between:1,1000|nullable',
'group_title' => 'min:1|max:1000|nullable',
'error_if_duplicate_hash' => [new IsBoolean()],
'apply_rules' => [new IsBoolean()],
@@ -107,40 +108,41 @@ class StoreRequest extends FormRequest
'transactions.*.foreign_currency_code' => 'min:3|max:51|exists:transaction_currencies,code|nullable',
// amount
'transactions.*.amount' => 'required|numeric|gt:0',
'transactions.*.foreign_amount' => 'numeric',
'transactions.*.amount' => ['required', new IsValidPositiveAmount()],
'transactions.*.foreign_amount' => ['nullable', new IsValidPositiveAmount()],
// description
'transactions.*.description' => 'nullable|between:1,1000',
'transactions.*.description' => 'nullable|min:1|max:1000',
// source of transaction
'transactions.*.source_id' => ['numeric', 'nullable', new BelongsUserGroup($userGroup)],
'transactions.*.source_name' => 'between:1,255|nullable',
'transactions.*.source_iban' => 'between:1,255|nullable|iban',
'transactions.*.source_number' => 'between:1,255|nullable',
'transactions.*.source_bic' => 'between:1,255|nullable|bic',
'transactions.*.source_name' => 'min:1|max:255|nullable',
'transactions.*.source_iban' => 'min:1|max:255|nullable|iban',
'transactions.*.source_number' => 'min:1|max:255|nullable',
'transactions.*.source_bic' => 'min:1|max:255|nullable|bic',
// destination of transaction
'transactions.*.destination_id' => ['numeric', 'nullable', new BelongsUserGroup($userGroup)],
'transactions.*.destination_name' => 'between:1,255|nullable',
'transactions.*.destination_iban' => 'between:1,255|nullable|iban',
'transactions.*.destination_number' => 'between:1,255|nullable',
'transactions.*.destination_bic' => 'between:1,255|nullable|bic',
'transactions.*.destination_name' => 'min:1|max:255|nullable',
'transactions.*.destination_iban' => 'min:1|max:255|nullable|iban',
'transactions.*.destination_number' => 'min:1|max:255|nullable',
'transactions.*.destination_bic' => 'min:1|max:255|nullable|bic',
// budget, category, bill and piggy
'transactions.*.budget_id' => ['mustExist:budgets,id', new BelongsUserGroup($userGroup)],
'transactions.*.budget_name' => ['between:1,255', 'nullable', new BelongsUserGroup($userGroup)],
'transactions.*.budget_name' => ['min:1', 'max:255', 'nullable', new BelongsUserGroup($userGroup)],
'transactions.*.category_id' => ['mustExist:categories,id', new BelongsUserGroup($userGroup), 'nullable'],
'transactions.*.category_name' => 'between:1,255|nullable',
'transactions.*.category_name' => 'min:1|max:255|nullable',
'transactions.*.bill_id' => ['numeric', 'nullable', 'mustExist:bills,id', new BelongsUserGroup($userGroup)],
'transactions.*.bill_name' => ['between:1,255', 'nullable', new BelongsUserGroup($userGroup)],
'transactions.*.bill_name' => ['min:1', 'max:255', 'nullable', new BelongsUserGroup($userGroup)],
'transactions.*.piggy_bank_id' => ['numeric', 'nullable', 'mustExist:piggy_banks,id', new BelongsUserGroup($userGroup)],
'transactions.*.piggy_bank_name' => ['between:1,255', 'nullable', new BelongsUserGroup($userGroup)],
'transactions.*.piggy_bank_name' => ['min:1', 'max:255', 'nullable', new BelongsUserGroup($userGroup)],
// other interesting fields
'transactions.*.reconciled' => [new IsBoolean()],
'transactions.*.notes' => 'min:1|max:50000|nullable',
'transactions.*.tags' => 'between:0,255',
'transactions.*.notes' => 'min:1|max:32768|nullable',
'transactions.*.tags' => 'min:0|max:255',
'transactions.*.tags.*' => 'min:0|max:255',
// meta info fields
'transactions.*.internal_reference' => 'min:1|max:255|nullable',
@@ -166,6 +168,8 @@ class StoreRequest extends FormRequest
'transactions.*.due_date' => 'date|nullable',
'transactions.*.payment_date' => 'date|nullable',
'transactions.*.invoice_date' => 'date|nullable',
// TODO include location and ability to process it.
];
}
@@ -208,6 +212,9 @@ class StoreRequest extends FormRequest
$this->validateGroupDescription($validator);
}
);
if($validator->fails()) {
Log::channel('audit')->error(sprintf('Validation errors in %s', __CLASS__), $validator->errors()->toArray());
}
}
/**
@@ -222,7 +229,7 @@ class StoreRequest extends FormRequest
*/
foreach ($this->get('transactions') as $transaction) {
$object = new NullArrayObject($transaction);
$return[] = [
$result = [
'type' => $this->clearString($object['type']),
'date' => $this->dateFromValue($object['date']),
'order' => $this->integerFromValue((string)$object['order']),
@@ -300,6 +307,8 @@ class StoreRequest extends FormRequest
'payment_date' => $this->dateFromValue($object['payment_date']),
'invoice_date' => $this->dateFromValue($object['invoice_date']),
];
$result = $this->addFromromTransactionStore($transaction, $result);
$return[] = $result;
}
return $return;

View File

@@ -0,0 +1,366 @@
<?php
/*
* UpdateRequest.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\Request\Model\Transaction;
use FireflyIII\Api\V1\Requests\Models\AvailableBudget\Request;
use FireflyIII\Exceptions\FireflyException;
use FireflyIII\Models\TransactionGroup;
use FireflyIII\Rules\BelongsUser;
use FireflyIII\Rules\IsBoolean;
use FireflyIII\Rules\IsDateOrTime;
use FireflyIII\Rules\IsValidPositiveAmount;
use FireflyIII\Rules\IsValidZeroOrMoreAmount;
use FireflyIII\Support\Request\ChecksLogin;
use FireflyIII\Support\Request\ConvertsDataTypes;
use FireflyIII\Validation\GroupValidation;
use FireflyIII\Validation\TransactionValidation;
use Illuminate\Support\Facades\Log;
use Illuminate\Validation\Validator;
/**
* Class UpdateRequest
*
* TODO it's the same as the v1
*/
class UpdateRequest extends Request
{
use ChecksLogin;
use ConvertsDataTypes;
use GroupValidation;
use TransactionValidation;
private array $arrayFields;
private array $booleanFields;
private array $dateFields;
private array $floatFields;
private array $integerFields;
private array $stringFields;
private array $textareaFields;
/**
* Get all data. Is pretty complex because of all the ??-statements.
*
* @throws FireflyException
*/
public function getAll(): array
{
app('log')->debug(sprintf('Now in %s', __METHOD__));
$this->integerFields = ['order', 'currency_id', 'foreign_currency_id', 'transaction_journal_id', 'source_id', 'destination_id', 'budget_id', 'category_id', 'bill_id', 'recurrence_id'];
$this->dateFields = ['date', 'interest_date', 'book_date', 'process_date', 'due_date', 'payment_date', 'invoice_date'];
$this->textareaFields = ['notes'];
// not really floats, for validation.
$this->floatFields = ['amount', 'foreign_amount'];
$this->stringFields = ['type', 'currency_code', 'foreign_currency_code', 'description', 'source_name', 'source_iban', 'source_number', 'source_bic', 'destination_name', 'destination_iban', 'destination_number', 'destination_bic', 'budget_name', 'category_name', 'bill_name', 'internal_reference', 'external_id', 'bunq_payment_id', 'sepa_cc', 'sepa_ct_op', 'sepa_ct_id', 'sepa_db', 'sepa_country', 'sepa_ep', 'sepa_ci', 'sepa_batch_id', 'external_url'];
$this->booleanFields = ['reconciled'];
$this->arrayFields = ['tags'];
$data = [];
if ($this->has('transactions')) {
$data['transactions'] = $this->getTransactionData();
}
if ($this->has('apply_rules')) {
$data['apply_rules'] = $this->boolean('apply_rules', true);
}
if ($this->has('fire_webhooks')) {
$data['fire_webhooks'] = $this->boolean('fire_webhooks', true);
}
if ($this->has('group_title')) {
$data['group_title'] = $this->convertString('group_title');
}
return $data;
}
/**
* The rules that the incoming request must be matched against.
*/
public function rules(): array
{
app('log')->debug(sprintf('Now in %s', __METHOD__));
$validProtocols = config('firefly.valid_url_protocols');
return [
// basic fields for group:
'group_title' => 'min:1|max:1000|nullable',
'apply_rules' => [new IsBoolean()],
// transaction rules (in array for splits):
'transactions.*.type' => 'in:withdrawal,deposit,transfer,opening-balance,reconciliation',
'transactions.*.date' => [new IsDateOrTime()],
'transactions.*.order' => 'numeric|min:0',
// group id:
'transactions.*.transaction_journal_id' => ['nullable', 'numeric', new BelongsUser()],
// currency info
'transactions.*.currency_id' => 'numeric|exists:transaction_currencies,id|nullable',
'transactions.*.currency_code' => 'min:3|max:51|exists:transaction_currencies,code|nullable',
'transactions.*.foreign_currency_id' => 'nullable|numeric|exists:transaction_currencies,id',
'transactions.*.foreign_currency_code' => 'nullable|min:3|max:51|exists:transaction_currencies,code',
// amount
'transactions.*.amount' => ['nullable', new IsValidPositiveAmount()],
'transactions.*.foreign_amount' => ['nullable', new IsValidZeroOrMoreAmount()],
// description
'transactions.*.description' => 'nullable|min:1|max:1000',
// source of transaction
'transactions.*.source_id' => ['numeric', 'nullable', new BelongsUser()],
'transactions.*.source_name' => 'min:1|max:255|nullable',
// destination of transaction
'transactions.*.destination_id' => ['numeric', 'nullable', new BelongsUser()],
'transactions.*.destination_name' => 'min:1|max:255|nullable',
// budget, category, bill and piggy
'transactions.*.budget_id' => ['mustExist:budgets,id', new BelongsUser(), 'nullable'],
'transactions.*.budget_name' => ['min:1', 'max:255', 'nullable', new BelongsUser()],
'transactions.*.category_id' => ['mustExist:categories,id', new BelongsUser(), 'nullable'],
'transactions.*.category_name' => 'min:1|max:255|nullable',
'transactions.*.bill_id' => ['numeric', 'nullable', 'mustExist:bills,id', new BelongsUser()],
'transactions.*.bill_name' => ['min:1', 'max:255', 'nullable', new BelongsUser()],
// other interesting fields
'transactions.*.reconciled' => [new IsBoolean()],
'transactions.*.notes' => 'min:1|max:32768|nullable',
'transactions.*.tags' => 'min:0|max:255|nullable',
'transactions.*.tags.*' => 'min:0|max:255',
// meta info fields
'transactions.*.internal_reference' => 'min:1|max:255|nullable',
'transactions.*.external_id' => 'min:1|max:255|nullable',
'transactions.*.recurrence_id' => 'min:1|max:255|nullable',
'transactions.*.bunq_payment_id' => 'min:1|max:255|nullable',
'transactions.*.external_url' => sprintf('min:1|max:255|nullable|url:%s', $validProtocols),
// SEPA fields:
'transactions.*.sepa_cc' => 'min:1|max:255|nullable',
'transactions.*.sepa_ct_op' => 'min:1|max:255|nullable',
'transactions.*.sepa_ct_id' => 'min:1|max:255|nullable',
'transactions.*.sepa_db' => 'min:1|max:255|nullable',
'transactions.*.sepa_country' => 'min:1|max:255|nullable',
'transactions.*.sepa_ep' => 'min:1|max:255|nullable',
'transactions.*.sepa_ci' => 'min:1|max:255|nullable',
'transactions.*.sepa_batch_id' => 'min:1|max:255|nullable',
// dates
'transactions.*.interest_date' => 'date|nullable',
'transactions.*.book_date' => 'date|nullable',
'transactions.*.process_date' => 'date|nullable',
'transactions.*.due_date' => 'date|nullable',
'transactions.*.payment_date' => 'date|nullable',
'transactions.*.invoice_date' => 'date|nullable',
];
}
/**
* Configure the validator instance.
*/
public function withValidator(Validator $validator): void
{
app('log')->debug('Now in withValidator');
/** @var TransactionGroup $transactionGroup */
$transactionGroup = $this->route()->parameter('userGroupTransaction');
$validator->after(
function (Validator $validator) use ($transactionGroup): void {
// if more than one, verify that there are journal ID's present.
$this->validateJournalIds($validator, $transactionGroup);
// all transaction types must be equal:
$this->validateTransactionTypesForUpdate($validator);
// user wants to update a reconciled transaction.
// source, destination, amount + foreign_amount cannot be changed
// and must be omitted from the request.
$this->preventUpdateReconciled($validator, $transactionGroup);
// validate source/destination is equal, depending on the transaction journal type.
$this->validateEqualAccountsForUpdate($validator, $transactionGroup);
// see method:
// $this->preventNoAccountInfo($validator, );
// validate that the currency fits the source and/or destination account.
// validate all account info
$this->validateAccountInformationUpdate($validator, $transactionGroup);
}
);
if($validator->fails()) {
Log::channel('audit')->error(sprintf('Validation errors in %s', __CLASS__), $validator->errors()->toArray());
}
}
/**
* Get transaction data.
*
* @throws FireflyException
*/
private function getTransactionData(): array
{
app('log')->debug(sprintf('Now in %s', __METHOD__));
$return = [];
/** @var null|array $transactions */
$transactions = $this->get('transactions');
if (!is_countable($transactions)) {
return $return;
}
/** @var null|array $transaction */
foreach ($transactions as $transaction) {
if (!is_array($transaction)) {
throw new FireflyException('Invalid data submitted: transaction is not array.');
}
// default response is to update nothing in the transaction:
$current = [];
$current = $this->getIntegerData($current, $transaction);
$current = $this->getStringData($current, $transaction);
$current = $this->getNlStringData($current, $transaction);
$current = $this->getDateData($current, $transaction);
$current = $this->getBooleanData($current, $transaction);
$current = $this->getArrayData($current, $transaction);
$current = $this->getFloatData($current, $transaction);
$return[] = $current;
}
return $return;
}
/**
* For each field, add it to the array if a reference is present in the request:
*
* @param array<string, string> $current
* @param array<string, mixed> $transaction
*/
private function getIntegerData(array $current, array $transaction): array
{
foreach ($this->integerFields as $fieldName) {
if (array_key_exists($fieldName, $transaction)) {
$current[$fieldName] = $this->integerFromValue((string) $transaction[$fieldName]);
}
}
return $current;
}
/**
* @param array<string, string> $current
* @param array<string, mixed> $transaction
*/
private function getStringData(array $current, array $transaction): array
{
foreach ($this->stringFields as $fieldName) {
if (array_key_exists($fieldName, $transaction)) {
$current[$fieldName] = $this->clearString((string) $transaction[$fieldName]);
}
}
return $current;
}
/**
* @param array<string, string> $current
* @param array<string, mixed> $transaction
*/
private function getNlStringData(array $current, array $transaction): array
{
foreach ($this->textareaFields as $fieldName) {
if (array_key_exists($fieldName, $transaction)) {
$current[$fieldName] = $this->clearStringKeepNewlines((string) $transaction[$fieldName]); // keep newlines
}
}
return $current;
}
/**
* @param array<string, string> $current
* @param array<string, mixed> $transaction
*/
private function getDateData(array $current, array $transaction): array
{
foreach ($this->dateFields as $fieldName) {
app('log')->debug(sprintf('Now at date field %s', $fieldName));
if (array_key_exists($fieldName, $transaction)) {
app('log')->debug(sprintf('New value: "%s"', (string) $transaction[$fieldName]));
$current[$fieldName] = $this->dateFromValue((string) $transaction[$fieldName]);
}
}
return $current;
}
/**
* @param array<string, string> $current
* @param array<string, mixed> $transaction
*/
private function getBooleanData(array $current, array $transaction): array
{
foreach ($this->booleanFields as $fieldName) {
if (array_key_exists($fieldName, $transaction)) {
$current[$fieldName] = $this->convertBoolean((string) $transaction[$fieldName]);
}
}
return $current;
}
/**
* @param array<string, string> $current
* @param array<string, mixed> $transaction
*/
private function getArrayData(array $current, array $transaction): array
{
foreach ($this->arrayFields as $fieldName) {
if (array_key_exists($fieldName, $transaction)) {
$current[$fieldName] = $this->arrayFromValue($transaction[$fieldName]);
}
}
return $current;
}
/**
* @param array<string, string> $current
* @param array<string, mixed> $transaction
*/
private function getFloatData(array $current, array $transaction): array
{
foreach ($this->floatFields as $fieldName) {
if (array_key_exists($fieldName, $transaction)) {
$value = $transaction[$fieldName];
if (is_float($value)) {
$current[$fieldName] = sprintf('%.12f', $value);
}
if (!is_float($value)) {
$current[$fieldName] = (string) $value;
}
}
}
return $current;
}
}

View File

@@ -49,7 +49,7 @@ class StoreRequest extends FormRequest
public function rules(): array
{
return [
'title' => 'unique:user_groups,title|required|min:2|max:255',
'title' => 'unique:user_groups,title|required|min:1|max:255',
];
}
}

View File

@@ -53,7 +53,7 @@ class UpdateRequest extends FormRequest
$userGroup = $this->route()->parameter('userGroup');
return [
'title' => sprintf('required|min:2|max:255|unique:user_groups,title,%d', $userGroup->id),
'title' => sprintf('required|min:1|max:255|unique:user_groups,title,%d', $userGroup->id),
];
}
}

View File

@@ -71,7 +71,6 @@ class EnableCurrencies extends Command
$found = [$defaultCurrency->id];
// get all meta entries
/** @var Collection $meta */
$meta = AccountMeta::leftJoin('accounts', 'accounts.id', '=', 'account_meta.account_id')
->where('accounts.user_group_id', $userGroup->id)
->where('account_meta.name', 'currency_id')->groupBy('data')->get(['data'])
@@ -108,6 +107,12 @@ class EnableCurrencies extends Command
$found[] = $entry->transaction_currency_id;
}
// also get all currencies already enabled.
$alreadyEnabled = $userGroup->currencies()->get(['transaction_currencies.id'])->pluck('id')->toArray();
foreach ($alreadyEnabled as $currencyId) {
$found[] = $currencyId;
}
$found = array_values(array_unique($found));
$found = array_values(
array_filter(

View File

@@ -32,6 +32,7 @@ use FireflyIII\Support\Cronjobs\BillWarningCronjob;
use FireflyIII\Support\Cronjobs\ExchangeRatesCronjob;
use FireflyIII\Support\Cronjobs\RecurringCronjob;
use Illuminate\Console\Command;
use Illuminate\Support\Facades\Log;
/**
* Class Cron
@@ -103,6 +104,7 @@ class Cron extends Command
private function exchangeRatesCronJob(bool $force, ?Carbon $date): void
{
Log::debug(sprintf('Created new ExchangeRateConverter in %s', __METHOD__));
$exchangeRates = new ExchangeRatesCronjob();
$exchangeRates->setForce($force);
// set date in cron job:

View File

@@ -25,9 +25,6 @@ declare(strict_types=1);
namespace FireflyIII\Console\Commands\Upgrade;
use FireflyIII\Console\Commands\ShowsFriendlyMessages;
use FireflyIII\Models\Recurrence;
use FireflyIII\Models\RecurrenceTransaction;
use FireflyIII\Models\TransactionType;
use Illuminate\Console\Command;
/**
@@ -53,8 +50,7 @@ class MigrateRecurrenceType extends Command
return 0;
}
$this->migrateTypes();
$this->friendlyWarning('This command has been disabled.');
$this->markAsExecuted();
return 0;
@@ -67,38 +63,6 @@ class MigrateRecurrenceType extends Command
return (bool)$configVar?->data;
}
private function migrateTypes(): void
{
$set = Recurrence::get();
/** @var Recurrence $recurrence */
foreach ($set as $recurrence) {
if (TransactionType::INVALID !== $recurrence->transactionType->type) {
$this->migrateRecurrence($recurrence);
}
}
}
private function migrateRecurrence(Recurrence $recurrence): void
{
$originalType = $recurrence->transaction_type_id;
$newType = $this->getInvalidType();
$recurrence->transaction_type_id = $newType->id;
$recurrence->save();
/** @var RecurrenceTransaction $transaction */
foreach ($recurrence->recurrenceTransactions as $transaction) {
$transaction->transaction_type_id = $originalType;
$transaction->save();
}
$this->friendlyInfo(sprintf('Updated recurrence #%d to new transaction type model.', $recurrence->id));
}
private function getInvalidType(): TransactionType
{
return TransactionType::whereType(TransactionType::INVALID)->firstOrCreate(['type' => TransactionType::INVALID]);
}
private function markAsExecuted(): void
{
app('fireflyconfig')->set(self::CONFIG_NAME, true);

View File

@@ -216,6 +216,7 @@ class Handler extends ExceptionHandler
'json' => request()->acceptsJson(),
'method' => request()->method(),
'headers' => $headers,
'post' => 'POST' === request()->method() ? json_encode(request()->all()) : '',
];
// create job that will mail.

View File

@@ -28,6 +28,7 @@ use Carbon\Carbon;
use FireflyIII\Exceptions\DuplicateTransactionException;
use FireflyIII\Exceptions\FireflyException;
use FireflyIII\Models\Account;
use FireflyIII\Models\Location;
use FireflyIII\Models\Transaction;
use FireflyIII\Models\TransactionCurrency;
use FireflyIII\Models\TransactionJournal;
@@ -49,6 +50,8 @@ use Illuminate\Support\Collection;
/**
* Class TransactionJournalFactory
*
* @SuppressWarnings(PHPMD.CouplingBetweenObjects)
*/
class TransactionJournalFactory
{
@@ -318,10 +321,23 @@ class TransactionJournalFactory
$this->storePiggyEvent($journal, $row);
$this->storeTags($journal, $row['tags']);
$this->storeMetaFields($journal, $row);
$this->storeLocation($journal, $row);
return $journal;
}
private function storeLocation(TransactionJournal $journal, NullArrayObject $data): void
{
if (true === $data['store_location']) {
$location = new Location();
$location->longitude = $data['longitude'];
$location->latitude = $data['latitude'];
$location->zoom_level = $data['zoom_level'];
$location->locatable()->associate($journal);
$location->save();
}
}
private function hashArray(NullArrayObject $row): string
{
$dataRow = $row->getArrayCopy();
@@ -355,18 +371,18 @@ class TransactionJournalFactory
/** @var null|TransactionJournalMeta $result */
$result = TransactionJournalMeta::withTrashed()
->leftJoin('transaction_journals', 'transaction_journals.id', '=', 'journal_meta.transaction_journal_id')
->whereNotNull('transaction_journals.id')
->where('transaction_journals.user_id', $this->user->id)
->where('data', json_encode($hash, JSON_THROW_ON_ERROR))
->with(['transactionJournal', 'transactionJournal.transactionGroup'])
->first()
->first(['journal_meta.*'])
;
if (null !== $result) {
app('log')->warning(sprintf('Found a duplicate in errorIfDuplicate because hash %s is not unique!', $hash));
$journal = $result->transactionJournal()->withTrashed()->first();
$group = $journal?->transactionGroup()->withTrashed()->first();
$groupId = $group?->id;
if (null === $group) {
$groupId = 0;
}
$groupId = (int) $group?->id;
throw new DuplicateTransactionException(sprintf('Duplicate of transaction #%d.', $groupId));
}

View File

@@ -220,7 +220,7 @@ class UserEventHandler
public function sendAdminRegistrationNotification(RegisteredUser $event): void
{
$sendMail = (bool)app('fireflyconfig')->get('notification_admin_new_reg', true)->data;
$sendMail = (bool) app('fireflyconfig')->get('notification_admin_new_reg', true)->data;
if ($sendMail) {
/** @var UserRepositoryInterface $repository */
$repository = app(UserRepositoryInterface::class);
@@ -285,7 +285,7 @@ class UserEventHandler
$oldEmail = $event->oldEmail;
$user = $event->user;
$token = app('preferences')->getForUser($user, 'email_change_undo_token', 'invalid');
$hashed = hash('sha256', sprintf('%s%s', (string)config('app.key'), $oldEmail));
$hashed = hash('sha256', sprintf('%s%s', (string) config('app.key'), $oldEmail));
$url = route('profile.undo-email-change', [$token->data, $hashed]);
try {
@@ -347,7 +347,7 @@ class UserEventHandler
*/
public function sendRegistrationMail(RegisteredUser $event): void
{
$sendMail = (bool)app('fireflyconfig')->get('notification_user_new_reg', true)->data;
$sendMail = (bool) app('fireflyconfig')->get('notification_user_new_reg', true)->data;
if ($sendMail) {
try {
Notification::send($event->user, new UserRegistrationNotification());

View File

@@ -182,7 +182,7 @@ trait MetaCollection
public function excludeInternalReference(string $internalReference): GroupCollectorInterface
{
$internalReference = (string) json_encode($internalReference);
$internalReference = (string)json_encode($internalReference);
$internalReference = str_replace('\\', '\\\\', trim($internalReference, '"'));
$this->joinMetaDataTables();
@@ -203,7 +203,7 @@ trait MetaCollection
public function externalIdContains(string $externalId): GroupCollectorInterface
{
$externalId = (string) json_encode($externalId);
$externalId = (string)json_encode($externalId);
$externalId = str_replace('\\', '\\\\', trim($externalId, '"'));
$this->joinMetaDataTables();
@@ -215,7 +215,7 @@ trait MetaCollection
public function externalIdDoesNotContain(string $externalId): GroupCollectorInterface
{
$externalId = (string) json_encode($externalId);
$externalId = (string)json_encode($externalId);
$externalId = str_replace('\\', '\\\\', trim($externalId, '"'));
$this->joinMetaDataTables();
@@ -227,7 +227,7 @@ trait MetaCollection
public function externalIdDoesNotEnd(string $externalId): GroupCollectorInterface
{
$externalId = (string) json_encode($externalId);
$externalId = (string)json_encode($externalId);
$externalId = str_replace('\\', '\\\\', trim($externalId, '"'));
$this->joinMetaDataTables();
@@ -239,7 +239,7 @@ trait MetaCollection
public function externalIdDoesNotStart(string $externalId): GroupCollectorInterface
{
$externalId = (string) json_encode($externalId);
$externalId = (string)json_encode($externalId);
$externalId = str_replace('\\', '\\\\', trim($externalId, '"'));
$this->joinMetaDataTables();
@@ -251,7 +251,7 @@ trait MetaCollection
public function externalIdEnds(string $externalId): GroupCollectorInterface
{
$externalId = (string) json_encode($externalId);
$externalId = (string)json_encode($externalId);
$externalId = str_replace('\\', '\\\\', trim($externalId, '"'));
$this->joinMetaDataTables();
@@ -263,7 +263,7 @@ trait MetaCollection
public function externalIdStarts(string $externalId): GroupCollectorInterface
{
$externalId = (string) json_encode($externalId);
$externalId = (string)json_encode($externalId);
$externalId = str_replace('\\', '\\\\', trim($externalId, '"'));
$this->joinMetaDataTables();
@@ -276,7 +276,7 @@ trait MetaCollection
public function externalUrlContains(string $url): GroupCollectorInterface
{
$this->joinMetaDataTables();
$url = (string) json_encode($url);
$url = (string)json_encode($url);
$url = str_replace('\\', '\\\\', trim($url, '"'));
$this->query->where('journal_meta.name', '=', 'external_url');
$this->query->where('journal_meta.data', 'LIKE', sprintf('%%%s%%', $url));
@@ -287,7 +287,7 @@ trait MetaCollection
public function externalUrlDoesNotContain(string $url): GroupCollectorInterface
{
$this->joinMetaDataTables();
$url = (string) json_encode($url);
$url = (string)json_encode($url);
$url = str_replace('\\', '\\\\', trim($url, '"'));
$this->query->where('journal_meta.name', '=', 'external_url');
$this->query->where('journal_meta.data', 'NOT LIKE', sprintf('%%%s%%', $url));
@@ -298,7 +298,7 @@ trait MetaCollection
public function externalUrlDoesNotEnd(string $url): GroupCollectorInterface
{
$this->joinMetaDataTables();
$url = (string) json_encode($url);
$url = (string)json_encode($url);
$url = str_replace('\\', '\\\\', ltrim($url, '"'));
$this->query->where('journal_meta.name', '=', 'external_url');
$this->query->where('journal_meta.data', 'NOT LIKE', sprintf('%%%s', $url));
@@ -309,7 +309,7 @@ trait MetaCollection
public function externalUrlDoesNotStart(string $url): GroupCollectorInterface
{
$this->joinMetaDataTables();
$url = (string) json_encode($url);
$url = (string)json_encode($url);
$url = str_replace('\\', '\\\\', rtrim($url, '"'));
// var_dump($url);
@@ -322,7 +322,7 @@ trait MetaCollection
public function externalUrlEnds(string $url): GroupCollectorInterface
{
$this->joinMetaDataTables();
$url = (string) json_encode($url);
$url = (string)json_encode($url);
$url = str_replace('\\', '\\\\', ltrim($url, '"'));
$this->query->where('journal_meta.name', '=', 'external_url');
$this->query->where('journal_meta.data', 'LIKE', sprintf('%%%s', $url));
@@ -333,7 +333,7 @@ trait MetaCollection
public function externalUrlStarts(string $url): GroupCollectorInterface
{
$this->joinMetaDataTables();
$url = (string) json_encode($url);
$url = (string)json_encode($url);
$url = str_replace('\\', '\\\\', rtrim($url, '"'));
// var_dump($url);
@@ -371,7 +371,7 @@ trait MetaCollection
public function internalReferenceContains(string $internalReference): GroupCollectorInterface
{
$internalReference = (string) json_encode($internalReference);
$internalReference = (string)json_encode($internalReference);
$internalReference = str_replace('\\', '\\\\', trim($internalReference, '"'));
// var_dump($internalReference);
// exit;
@@ -385,7 +385,7 @@ trait MetaCollection
public function internalReferenceDoesNotContain(string $internalReference): GroupCollectorInterface
{
$internalReference = (string) json_encode($internalReference);
$internalReference = (string)json_encode($internalReference);
$internalReference = str_replace('\\', '\\\\', trim($internalReference, '"'));
$this->joinMetaDataTables();
@@ -397,7 +397,7 @@ trait MetaCollection
public function internalReferenceDoesNotEnd(string $internalReference): GroupCollectorInterface
{
$internalReference = (string) json_encode($internalReference);
$internalReference = (string)json_encode($internalReference);
$internalReference = str_replace('\\', '\\\\', trim($internalReference, '"'));
$this->joinMetaDataTables();
@@ -409,7 +409,7 @@ trait MetaCollection
public function internalReferenceDoesNotStart(string $internalReference): GroupCollectorInterface
{
$internalReference = (string) json_encode($internalReference);
$internalReference = (string)json_encode($internalReference);
$internalReference = str_replace('\\', '\\\\', trim($internalReference, '"'));
$this->joinMetaDataTables();
@@ -421,7 +421,7 @@ trait MetaCollection
public function internalReferenceEnds(string $internalReference): GroupCollectorInterface
{
$internalReference = (string) json_encode($internalReference);
$internalReference = (string)json_encode($internalReference);
$internalReference = str_replace('\\', '\\\\', trim($internalReference, '"'));
$this->joinMetaDataTables();
@@ -433,7 +433,7 @@ trait MetaCollection
public function internalReferenceStarts(string $internalReference): GroupCollectorInterface
{
$internalReference = (string) json_encode($internalReference);
$internalReference = (string)json_encode($internalReference);
$internalReference = str_replace('\\', '\\\\', trim($internalReference, '"'));
$this->joinMetaDataTables();
@@ -629,7 +629,7 @@ trait MetaCollection
public function setInternalReference(string $internalReference): GroupCollectorInterface
{
$internalReference = (string) json_encode($internalReference);
$internalReference = (string)json_encode($internalReference);
$internalReference = str_replace('\\', '\\\\', trim($internalReference, '"'));
$this->joinMetaDataTables();
@@ -670,7 +670,64 @@ trait MetaCollection
}
/**
* Limit results to a specific set of tags.
* Limit results to a SPECIFIC set of tags.
*/
public function setAllTags(Collection $tags): GroupCollectorInterface
{
Log::debug(sprintf('Now in setAllTags(%d tag(s))', $tags->count()));
$this->withTagInformation();
$this->query->whereNotNull('tag_transaction_journal.tag_id');
// this method adds a "postFilter" to the collector.
$list = $tags->pluck('tag')->toArray();
$list = array_map('strtolower', $list);
$filter = static function (array $object) use ($list): bool|array {
$includedJournals = [];
$return = $object;
unset($return['transactions']);
$return['transactions'] = [];
Log::debug(sprintf('Now in setAllTags(%s) filter', implode(', ', $list)));
$expectedTagCount = count($list);
$foundTagCount = 0;
foreach ($object['transactions'] as $transaction) {
$transactionTagCount = count($transaction['tags']);
app('log')->debug(sprintf('Transaction #%d has %d tag(s)', $transaction['transaction_journal_id'], $transactionTagCount));
if ($transactionTagCount < $expectedTagCount) {
app('log')->debug(sprintf('Transaction has %d tag(s), we expect %d tag(s), return false.', $transactionTagCount, $expectedTagCount));
return false;
}
foreach ($transaction['tags'] as $tag) {
Log::debug(sprintf('"%s" versus', strtolower($tag['name'])), $list);
if (in_array(strtolower($tag['name']), $list, true)) {
app('log')->debug(sprintf('Transaction has tag "%s" so count++.', $tag['name']));
++$foundTagCount;
$journalId = $transaction['transaction_journal_id'];
// #8377 prevent adding a transaction twice when multiple tag searches find this transaction
if (!in_array($journalId, $includedJournals, true)) {
$includedJournals[] = $journalId;
$return['transactions'][] = $transaction;
}
}
}
}
Log::debug(sprintf('Found %d tags, need at least %d.', $foundTagCount, $expectedTagCount));
// found at least the expected tags.
$result = $foundTagCount >= $expectedTagCount;
if (true === $result) {
return $return;
}
return false;
};
$this->postFilters[] = $filter;
return $this;
}
/**
* Limit results to any of the tags in the list.
*/
public function setTags(Collection $tags): GroupCollectorInterface
{
@@ -683,28 +740,19 @@ trait MetaCollection
$list = array_map('strtolower', $list);
$filter = static function (array $object) use ($list): bool {
Log::debug(sprintf('Now in setTags(%s) filter', implode(', ', $list)));
$expectedTagCount = count($list);
$foundTagCount = 0;
foreach ($object['transactions'] as $transaction) {
$transactionTagCount = count($transaction['tags']);
app('log')->debug(sprintf('Transaction has %d tag(s)', $transactionTagCount));
if ($transactionTagCount < $expectedTagCount) {
app('log')->debug(sprintf('Transaction has %d tag(s), we expect %d tag(s), return false.', $transactionTagCount, $expectedTagCount));
return false;
}
foreach ($transaction['tags'] as $tag) {
Log::debug(sprintf('"%s" versus', strtolower($tag['name'])), $list);
if (in_array(strtolower($tag['name']), $list, true)) {
app('log')->debug(sprintf('Transaction has tag "%s" so count++.', $tag['name']));
++$foundTagCount;
}
}
}
Log::debug(sprintf('Found %d tags, need at least %d.', $foundTagCount, $expectedTagCount));
app('log')->debug(sprintf('Transaction has tag "%s" so return true.', $tag['name']));
// found at least the expected tags.
return $foundTagCount >= $expectedTagCount;
return true;
}
}
}
app('log')->debug('Transaction has no tags from the list, so return false.');
return false;
};
$this->postFilters[] = $filter;

View File

@@ -462,7 +462,7 @@ trait TimeCollection
*/
public function setBefore(Carbon $date): GroupCollectorInterface
{
$beforeStr = $date->format('Y-m-d 00:00:00');
$beforeStr = $date->format('Y-m-d 23:59:59');
$this->query->where('transaction_journals.date', '<=', $beforeStr);
return $this;

View File

@@ -25,7 +25,6 @@ namespace FireflyIII\Helpers\Collector;
use Carbon\Carbon;
use Carbon\Exceptions\InvalidFormatException;
use Exception;
use FireflyIII\Exceptions\FireflyException;
use FireflyIII\Helpers\Collector\Extensions\AccountCollection;
use FireflyIII\Helpers\Collector\Extensions\AmountCollection;
@@ -43,6 +42,7 @@ use Illuminate\Database\Eloquent\Builder as EloquentBuilder;
use Illuminate\Database\Query\JoinClause;
use Illuminate\Pagination\LengthAwarePaginator;
use Illuminate\Support\Collection;
use Illuminate\Support\Facades\Log;
/**
* Class GroupCollector
@@ -105,6 +105,8 @@ class GroupCollector implements GroupCollectorInterface
'transaction_groups.created_at as created_at',
'transaction_groups.updated_at as updated_at',
'transaction_groups.title as transaction_group_title',
'transaction_groups.created_at as group_created_at',
'transaction_groups.updated_at as group_updated_at',
// journal
'transaction_journals.id as transaction_journal_id',
@@ -560,6 +562,7 @@ class GroupCollector implements GroupCollectorInterface
if (0 !== count($journalIds)) {
// make all integers.
$integerIDs = array_map('intval', $journalIds);
Log::debug(sprintf('GroupCollector: setJournalIds: %s', implode(', ', $integerIDs)));
$this->query->whereIn('transaction_journals.id', $integerIDs);
}
@@ -700,6 +703,8 @@ class GroupCollector implements GroupCollectorInterface
'user_group_id' => $augumentedJournal->user_group_id,
// Field transaction_group_title was added by the query.
'title' => $augumentedJournal->transaction_group_title, // @phpstan-ignore-line
'created_at' => new Carbon($augumentedJournal->group_created_at, config('app.timezone')),
'updated_at' => new Carbon($augumentedJournal->group_updated_at, config('app.timezone')),
'transaction_type' => $parsedGroup['transaction_type_type'],
'count' => 1,
'sums' => [],
@@ -926,7 +931,6 @@ class GroupCollector implements GroupCollectorInterface
private function postFilterCollection(Collection $collection): Collection
{
$currentCollection = $collection;
app('log')->debug(sprintf('GroupCollector: postFilterCollection has %d filter(s) and %d transaction(s).', count($this->postFilters), count($currentCollection)));
/**
@@ -948,8 +952,15 @@ class GroupCollector implements GroupCollectorInterface
// skip other filters, continue to next item.
continue;
}
// if the result is a bool, use the unedited results.
if (true === $result) {
$nextCollection->push($item);
}
// if the result is an array, the filter has changed what's being returned.
if (is_array($result)) {
$nextCollection->push($result);
}
}
$currentCollection = $nextCollection;
app('log')->debug(sprintf('GroupCollector: postFilterCollection has %d transaction(s) left.', count($currentCollection)));
}

View File

@@ -559,10 +559,15 @@ interface GroupCollectorInterface
public function setTag(Tag $tag): self;
/**
* Limit results to a specific set of tags.
* Limit results to any of the specified tags.
*/
public function setTags(Collection $tags): self;
/**
* Limit results to a SPECIFIC set of tags.
*/
public function setAllTags(Collection $tags): self;
/**
* Limit the search to one specific transaction group.
*/

View File

@@ -36,6 +36,7 @@ use FireflyIII\Support\Http\Api\ExchangeRateConverter;
use FireflyIII\User;
use Illuminate\Contracts\Auth\Authenticatable;
use Illuminate\Support\Collection;
use Illuminate\Support\Facades\Log;
/**
* This class can handle both request with and without a user group and will return the appropriate repository when
@@ -72,7 +73,7 @@ class NetWorth implements NetWorthInterface
return $cache->get();
}
app('log')->debug(sprintf('Now in byAccounts("%s", "%s")', $ids, $date->format('Y-m-d')));
Log::debug(sprintf('Created new ExchangeRateConverter in %s', __METHOD__));
$default = app('amount')->getDefaultCurrency();
$converter = new ExchangeRateConverter();
@@ -86,11 +87,11 @@ class NetWorth implements NetWorthInterface
'currency_name' => $default->name,
'currency_symbol' => $default->symbol,
'currency_decimal_places' => $default->decimal_places,
'native_id' => $default->id,
'native_code' => $default->code,
'native_name' => $default->name,
'native_symbol' => $default->symbol,
'native_decimal_places' => $default->decimal_places,
'native_currency_id' => $default->id,
'native_currency_code' => $default->code,
'native_currency_name' => $default->name,
'native_currency_symbol' => $default->symbol,
'native_currency_decimal_places' => $default->decimal_places,
],
];
$balances = app('steam')->balancesByAccountsConverted($accounts, $date);
@@ -102,7 +103,7 @@ class NetWorth implements NetWorthInterface
if (null === $currency) {
$currency = app('amount')->getDefaultCurrency();
}
$currencyId = $currency->id;
$currencyCode = $currency->code;
$balance = '0';
$nativeBalance = '0';
if (array_key_exists($account->id, $balances)) {
@@ -117,23 +118,23 @@ class NetWorth implements NetWorthInterface
$nativeVirtualBalance = $converter->convert($default, $currency, $account->created_at, $virtualBalance);
$nativeBalance = bcsub($nativeBalance, $nativeVirtualBalance);
}
$netWorth[$currencyId] ??= [
$netWorth[$currencyCode] ??= [
'balance' => '0',
'native_balance' => '0',
'currency_id' => $currencyId,
'currency_id' => (string) $currency->id,
'currency_code' => $currency->code,
'currency_name' => $currency->name,
'currency_symbol' => $currency->symbol,
'currency_decimal_places' => $currency->decimal_places,
'native_id' => $default->id,
'native_code' => $default->code,
'native_name' => $default->name,
'native_symbol' => $default->symbol,
'native_decimal_places' => $default->decimal_places,
'native_currency_id' => (string) $default->id,
'native_currency_code' => $default->code,
'native_currency_name' => $default->name,
'native_currency_symbol' => $default->symbol,
'native_currency_decimal_places' => $default->decimal_places,
];
$netWorth[$currencyId]['balance'] = bcadd($balance, $netWorth[$currencyId]['balance']);
$netWorth[$currencyId]['native_balance'] = bcadd($nativeBalance, $netWorth[$currencyId]['native_balance']);
$netWorth[$currencyCode]['balance'] = bcadd($balance, $netWorth[$currencyCode]['balance']);
$netWorth[$currencyCode]['native_balance'] = bcadd($nativeBalance, $netWorth[$currencyCode]['native_balance']);
$netWorth['native']['balance'] = bcadd($nativeBalance, $netWorth['native']['balance']);
$netWorth['native']['native_balance'] = bcadd($nativeBalance, $netWorth['native']['native_balance']);
}
@@ -188,7 +189,7 @@ class NetWorth implements NetWorthInterface
}
$return[$currency->id] ??= [
'id' => (string)$currency->id,
'id' => (string) $currency->id,
'name' => $currency->name,
'symbol' => $currency->symbol,
'code' => $currency->code,
@@ -219,7 +220,7 @@ class NetWorth implements NetWorthInterface
/** @var Account $account */
foreach ($accounts as $account) {
if (1 === (int)$this->getRepository()->getMetaValue($account, 'include_net_worth')) {
if (1 === (int) $this->getRepository()->getMetaValue($account, 'include_net_worth')) {
$filtered->push($account);
}
}

View File

@@ -58,7 +58,7 @@ class CreateController extends Controller
$this->middleware(
function ($request, $next) {
app('view')->share('mainTitleIcon', 'fa-credit-card');
app('view')->share('title', (string)trans('firefly.accounts'));
app('view')->share('title', (string) trans('firefly.accounts'));
$this->repository = app(AccountRepositoryInterface::class);
$this->attachments = app(AttachmentHelperInterface::class);
@@ -77,7 +77,7 @@ class CreateController extends Controller
{
$defaultCurrency = app('amount')->getDefaultCurrency();
$subTitleIcon = config(sprintf('firefly.subIconsByIdentifier.%s', $objectType));
$subTitle = (string)trans(sprintf('firefly.make_new_%s_account', $objectType));
$subTitle = (string) trans(sprintf('firefly.make_new_%s_account', $objectType));
$roles = $this->getRoles();
$liabilityTypes = $this->getLiabilityTypes();
$hasOldInput = null !== $request->old('_token');
@@ -96,9 +96,9 @@ class CreateController extends Controller
// interest calculation periods:
$interestPeriods = [
'daily' => (string)trans('firefly.interest_calc_daily'),
'monthly' => (string)trans('firefly.interest_calc_monthly'),
'yearly' => (string)trans('firefly.interest_calc_yearly'),
'daily' => (string) trans('firefly.interest_calc_daily'),
'monthly' => (string) trans('firefly.interest_calc_monthly'),
'yearly' => (string) trans('firefly.interest_calc_yearly'),
];
// pre fill some data
@@ -106,9 +106,14 @@ class CreateController extends Controller
'preFilled',
[
'currency_id' => $defaultCurrency->id,
'include_net_worth' => $hasOldInput ? (bool)$request->old('include_net_worth') : true,
'include_net_worth' => $hasOldInput ? (bool) $request->old('include_net_worth') : true,
]
);
// issue #8321
$showNetWorth = true;
if ('liabilities' !== $objectType && 'asset' !== $objectType) {
$showNetWorth = false;
}
// put previous url in session if not redirect from store (not "create another").
if (true !== session('accounts.create.fromStore')) {
@@ -119,7 +124,7 @@ class CreateController extends Controller
return view(
'accounts.create',
compact('subTitleIcon', 'liabilityDirections', 'locations', 'objectType', 'interestPeriods', 'subTitle', 'roles', 'liabilityTypes')
compact('subTitleIcon', 'liabilityDirections', 'showNetWorth', 'locations', 'objectType', 'interestPeriods', 'subTitle', 'roles', 'liabilityTypes')
);
}
@@ -134,7 +139,7 @@ class CreateController extends Controller
{
$data = $request->getAccountData();
$account = $this->repository->store($data);
$request->session()->flash('success', (string)trans('firefly.stored_new_account', ['name' => $account->name]));
$request->session()->flash('success', (string) trans('firefly.stored_new_account', ['name' => $account->name]));
app('preferences')->mark();
Log::channel('audit')->info('Stored new account.', $data);
@@ -156,7 +161,8 @@ class CreateController extends Controller
$this->attachments->saveAttachmentsForModel($account, $files);
}
if (null !== $files && auth()->user()->hasRole('demo')) {
session()->flash('info', (string)trans('firefly.no_att_demo_user'));
Log::channel('audit')->warning(sprintf('The demo user is trying to upload attachments in %s.', __METHOD__));
session()->flash('info', (string) trans('firefly.no_att_demo_user'));
}
if (count($this->attachments->getMessages()->get('attachments')) > 0) {
@@ -165,7 +171,7 @@ class CreateController extends Controller
// redirect to previous URL.
$redirect = redirect($this->getPreviousUrl('accounts.create.url'));
if (1 === (int)$request->get('create_another')) {
if (1 === (int) $request->get('create_another')) {
// set value so create routine will not overwrite URL:
$request->session()->put('accounts.create.fromStore', true);

View File

@@ -33,6 +33,7 @@ use Illuminate\Contracts\View\Factory;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
use Illuminate\Routing\Redirector;
use Illuminate\Support\Facades\Log;
use Illuminate\View\View;
/**
@@ -127,6 +128,12 @@ class EditController extends Controller
$includeNetWorth = $repository->getMetaValue($account, 'include_net_worth');
$includeNetWorth = null === $includeNetWorth ? true : '1' === $includeNetWorth;
// issue #8321
$showNetWorth = true;
if ('liabilities' !== $objectType && 'asset' !== $objectType) {
$showNetWorth = false;
}
// code to handle active-checkboxes
$hasOldInput = null !== $request->old('_token');
$virtualBalance = null === $account->virtual_balance ? '0' : $account->virtual_balance;
@@ -154,7 +161,7 @@ class EditController extends Controller
$request->session()->flash('preFilled', $preFilled);
return view('accounts.edit', compact('account', 'currency', 'subTitle', 'subTitleIcon', 'locations', 'liabilityDirections', 'objectType', 'roles', 'preFilled', 'liabilityTypes', 'interestPeriods'));
return view('accounts.edit', compact('account', 'currency', 'showNetWorth', 'subTitle', 'subTitleIcon', 'locations', 'liabilityDirections', 'objectType', 'roles', 'preFilled', 'liabilityTypes', 'interestPeriods'));
}
/**
@@ -170,7 +177,7 @@ class EditController extends Controller
$data = $request->getAccountData();
$this->repository->update($account, $data);
Log::channel('audit')->info(sprintf('Updated account #%d.', $account->id), $data);
$request->session()->flash('success', (string) trans('firefly.updated_account', ['name' => $account->name]));
// store new attachment(s):
@@ -180,6 +187,7 @@ class EditController extends Controller
$this->attachments->saveAttachmentsForModel($account, $files);
}
if (null !== $files && auth()->user()->hasRole('demo')) {
Log::channel('audit')->warning(sprintf('The demo user is trying to upload attachments in %s.', __METHOD__));
session()->flash('info', (string) trans('firefly.no_att_demo_user'));
}

View File

@@ -78,7 +78,7 @@ class LoginController extends Controller
public function login(Request $request): JsonResponse|RedirectResponse
{
Log::channel('audit')->info(sprintf('User is trying to login using "%s"', $request->get($this->username())));
app('log')->info('User is trying to login.');
app('log')->debug('User is trying to login.');
$this->validateLogin($request);
app('log')->debug('Login data is present.');
@@ -88,7 +88,7 @@ class LoginController extends Controller
// the login attempts for this application. We'll key this by the username and
// the IP address of the client making these requests into this application.
if ($this->hasTooManyLoginAttempts($request)) {
Log::channel('audit')->info(sprintf('Login for user "%s" was locked out.', $request->get($this->username())));
Log::channel('audit')->warning(sprintf('Login for user "%s" was locked out.', $request->get($this->username())));
app('log')->error(sprintf('Login for user "%s" was locked out.', $request->get($this->username())));
$this->fireLockoutEvent($request);
@@ -114,7 +114,7 @@ class LoginController extends Controller
// to login 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')->info(sprintf('Login failed. Attempt for user "%s" failed.', $request->get($this->username())));
Log::channel('audit')->warning(sprintf('Login failed. Attempt for user "%s" failed.', $request->get($this->username())));
$this->sendFailedLoginResponse($request);

View File

@@ -33,6 +33,7 @@ use Illuminate\Contracts\View\Factory;
use Illuminate\Contracts\View\View;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Log;
/**
* Class CreateController
@@ -104,6 +105,8 @@ class CreateController extends Controller
return redirect(route('bills.create'))->withInput();
}
Log::channel('audit')->info('Stored new bill.', $billData);
$request->session()->flash('success', (string)trans('firefly.stored_new_bill', ['name' => $bill->name]));
app('preferences')->mark();
@@ -113,6 +116,7 @@ class CreateController extends Controller
$this->attachments->saveAttachmentsForModel($bill, $files);
}
if (null !== $files && auth()->user()->hasRole('demo')) {
Log::channel('audit')->warning(sprintf('The demo user is trying to upload attachments in %s.', __METHOD__));
session()->flash('info', (string)trans('firefly.no_att_demo_user'));
}

View File

@@ -33,6 +33,7 @@ use Illuminate\Contracts\View\Factory;
use Illuminate\Contracts\View\View;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Log;
/**
* Class EditController
@@ -51,7 +52,7 @@ class EditController extends Controller
$this->middleware(
function ($request, $next) {
app('view')->share('title', (string)trans('firefly.bills'));
app('view')->share('title', (string) trans('firefly.bills'));
app('view')->share('mainTitleIcon', 'fa-calendar-o');
$this->attachments = app(AttachmentHelperInterface::class);
$this->repository = app(BillRepositoryInterface::class);
@@ -74,10 +75,10 @@ class EditController extends Controller
$billPeriods = config('firefly.bill_periods');
foreach ($billPeriods as $current) {
$periods[$current] = (string)trans('firefly.'.$current);
$periods[$current] = (string) trans('firefly.'.$current);
}
$subTitle = (string)trans('firefly.edit_bill', ['name' => $bill->name]);
$subTitle = (string) trans('firefly.edit_bill', ['name' => $bill->name]);
// put previous url in session if not redirect from store (not "return_to_edit").
if (true !== session('bills.edit.fromUpdate')) {
@@ -98,7 +99,7 @@ class EditController extends Controller
'extension_date' => $bill->extension_date,
'notes' => $this->repository->getNoteText($bill),
'transaction_currency_id' => $bill->transaction_currency_id,
'active' => $hasOldInput ? (bool)$request->old('active') : $bill->active,
'active' => $hasOldInput ? (bool) $request->old('active') : $bill->active,
'object_group' => null !== $bill->objectGroups->first() ? $bill->objectGroups->first()->title : '',
];
@@ -116,7 +117,9 @@ class EditController extends Controller
$billData = $request->getBillData();
$bill = $this->repository->update($bill, $billData);
$request->session()->flash('success', (string)trans('firefly.updated_bill', ['name' => $bill->name]));
Log::channel('audit')->info(sprintf('Updated bill #%d.', $bill->id), $billData);
$request->session()->flash('success', (string) trans('firefly.updated_bill', ['name' => $bill->name]));
app('preferences')->mark();
/** @var null|array $files */
@@ -125,7 +128,8 @@ class EditController extends Controller
$this->attachments->saveAttachmentsForModel($bill, $files);
}
if (null !== $files && auth()->user()->hasRole('demo')) {
session()->flash('info', (string)trans('firefly.no_att_demo_user'));
Log::channel('audit')->warning(sprintf('The demo user is trying to upload attachments in %s.', __METHOD__));
session()->flash('info', (string) trans('firefly.no_att_demo_user'));
}
// flash messages
@@ -134,7 +138,7 @@ class EditController extends Controller
}
$redirect = redirect($this->getPreviousUrl('bills.edit.url'));
if (1 === (int)$request->get('return_to_edit')) {
if (1 === (int) $request->get('return_to_edit')) {
$request->session()->put('bills.edit.fromUpdate', true);
$redirect = redirect(route('bills.edit', [$bill->id]))->withInput(['return_to_edit' => 1]);

View File

@@ -202,7 +202,9 @@ class BudgetLimitController extends Controller
if ('' === $amount) {
$amount = '0';
}
if ((int)$amount > 268435456) { // 268 million, intentional integer
$amount = '268435456';
}
// sanity check on amount:
if (0 === bccomp($amount, '0')) {
$budgetId = $budgetLimit->budget_id;
@@ -217,9 +219,7 @@ class BudgetLimitController extends Controller
return response()->json($array);
}
if ((int)$amount > 268435456) { // 268 million, intentional integer
$amount = '268435456';
}
if (-1 === bccomp($amount, '0')) {
$amount = bcmul($amount, '-1');
}

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