Compare commits

..

63 Commits

Author SHA1 Message Date
github-actions[bot]
5b0be91f93 Merge pull request #10885 from firefly-iii/release-1757479782
🤖 Automatically merge the PR into the develop branch.
2025-09-10 06:49:50 +02:00
JC5
01e7b604da 🤖 Auto commit for release 'develop' on 2025-09-10 2025-09-10 06:49:42 +02:00
James Cole
58d175444b Fix #10883 2025-09-10 06:43:24 +02:00
James Cole
134770644a Fix amounts in transaction. 2025-09-09 17:14:53 +02:00
James Cole
a9f21c9371 Extra text in the PR. 2025-09-09 15:53:25 +02:00
github-actions[bot]
781947beeb Merge pull request #10879 from firefly-iii/release-1757425805
🤖 Automatically merge the PR into the develop branch.
2025-09-09 15:50:18 +02:00
JC5
9760cd2f97 🤖 Auto commit for release 'develop' on 2025-09-09 2025-09-09 15:50:06 +02:00
James Cole
d317e9ec32 Update changelog. 2025-09-09 15:41:19 +02:00
James Cole
534f7fcadb Merge branch 'main' into develop 2025-09-09 15:36:55 +02:00
James Cole
fb3f7a1d4b Merge pull request #10874 from firefly-iii/dependabot/github_actions/actions/stale-10
Bump actions/stale from 9 to 10
2025-09-08 11:41:37 +02:00
James Cole
bf2c3e3561 Merge pull request #10873 from firefly-iii/dependabot/github_actions/actions/github-script-8
Bump actions/github-script from 7 to 8
2025-09-08 11:41:12 +02:00
github-actions[bot]
b670f81dcd Merge pull request #10875 from firefly-iii/release-1757313349
🤖 Automatically merge the PR into the develop branch.
2025-09-08 08:36:01 +02:00
JC5
7aac1cdf67 🤖 Auto commit for release 'develop' on 2025-09-08 2025-09-08 08:35:49 +02:00
Sander Dorigo
fa0ac8a16c Fix php files 2025-09-08 08:31:09 +02:00
dependabot[bot]
0990b1f0b4 Bump actions/stale from 9 to 10
Bumps [actions/stale](https://github.com/actions/stale) from 9 to 10.
- [Release notes](https://github.com/actions/stale/releases)
- [Changelog](https://github.com/actions/stale/blob/main/CHANGELOG.md)
- [Commits](https://github.com/actions/stale/compare/v9...v10)

---
updated-dependencies:
- dependency-name: actions/stale
  dependency-version: '10'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-09-08 03:08:14 +00:00
dependabot[bot]
c1922670c8 Bump actions/github-script from 7 to 8
Bumps [actions/github-script](https://github.com/actions/github-script) from 7 to 8.
- [Release notes](https://github.com/actions/github-script/releases)
- [Commits](https://github.com/actions/github-script/compare/v7...v8)

---
updated-dependencies:
- dependency-name: actions/github-script
  dependency-version: '8'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-09-08 03:08:10 +00:00
James Cole
81cd89d66f Final nestor and phpstan fixes. 2025-09-07 17:42:16 +02:00
James Cole
f5c202543c Clean up code. 2025-09-07 17:31:08 +02:00
James Cole
034f437c6b Merge branch 'develop' of github.com:firefly-iii/firefly-iii into develop 2025-09-07 17:30:43 +02:00
James Cole
8550ba6138 Remove unused code. 2025-09-07 17:30:34 +02:00
github-actions[bot]
a51501025b Merge pull request #10872 from firefly-iii/release-1757249926
🤖 Automatically merge the PR into the develop branch.
2025-09-07 14:58:53 +02:00
JC5
a9d26e4586 🤖 Auto commit for release 'develop' on 2025-09-07 2025-09-07 14:58:46 +02:00
James Cole
949691935f Catch exceptions. 2025-09-07 14:54:44 +02:00
James Cole
4835b05304 Optimize currency search. 2025-09-07 14:49:49 +02:00
James Cole
cce5a73dd2 Clean up and fix phpstan issues. 2025-09-07 14:28:58 +02:00
github-actions[bot]
3152f635dd Merge pull request #10868 from firefly-iii/release-1757235851
🤖 Automatically merge the PR into the develop branch.
2025-09-07 11:04:21 +02:00
JC5
12e8651017 🤖 Auto commit for release 'develop' on 2025-09-07 2025-09-07 11:04:11 +02:00
James Cole
f88286c848 Merge branches 'develop' and 'develop' of github.com:firefly-iii/firefly-iii into develop 2025-09-07 10:59:12 +02:00
James Cole
39cf0533d9 Fix various phpstan issues. 2025-09-07 10:59:07 +02:00
github-actions[bot]
6d82887960 Merge pull request #10867 from firefly-iii/release-1757224570
🤖 Automatically merge the PR into the develop branch.
2025-09-07 07:56:20 +02:00
JC5
262f1bae34 🤖 Auto commit for release 'develop' on 2025-09-07 2025-09-07 07:56:10 +02:00
James Cole
75dfdcc220 Fix final phpstan issue. 2025-09-07 07:51:35 +02:00
James Cole
c3a3bdf525 Fix phpstan issues. 2025-09-07 07:51:01 +02:00
James Cole
602df95f3c Fix phpstan issues. 2025-09-07 07:43:04 +02:00
James Cole
296a64e284 Fix phpstan issues 2025-09-07 07:31:00 +02:00
James Cole
b87b99a755 Fix phpstan issues. 2025-09-07 06:25:26 +02:00
James Cole
bf53f5d6b7 Fix various phpstan issues. 2025-09-05 05:09:46 +02:00
James Cole
bcbb868acc Update packages. 2025-09-04 19:46:52 +02:00
James Cole
b3a9e6569e Fix #10854 2025-09-04 06:26:28 +02:00
James Cole
f174f124ef Fix # 2025-09-04 06:26:12 +02:00
James Cole
8745377f31 Fix #10833 2025-09-04 06:22:18 +02:00
James Cole
cf76e93f31 Remove primary currency from views, add some debug for #10854 2025-09-04 06:22:04 +02:00
James Cole
19e36f6f6e Share primary currency to all pages. 2025-09-03 21:02:13 +02:00
James Cole
2a7bb6f048 Fix #10853 2025-09-03 20:34:40 +02:00
James Cole
536eacbc0c Fix sort params 2025-09-03 20:34:28 +02:00
James Cole
af78158d0b Fix minor issues. 2025-09-02 18:38:34 +02:00
github-actions[bot]
fb97910a34 Merge pull request #10848 from firefly-iii/release-1756787147
🤖 Automatically merge the PR into the develop branch.
2025-09-02 06:25:54 +02:00
JC5
66b4d14129 🤖 Auto commit for release 'develop' on 2025-09-02 2025-09-02 06:25:47 +02:00
James Cole
fd53047dbc Merge branch 'develop' of github.com:firefly-iii/firefly-iii into develop 2025-09-02 06:03:17 +02:00
James Cole
5f6fc1bab4 Fix #10846 2025-09-02 06:03:11 +02:00
github-actions[bot]
cd0b64bd24 Merge pull request #10845 from firefly-iii/release-1756752249
🤖 Automatically merge the PR into the develop branch.
2025-09-01 20:44:18 +02:00
JC5
91b26bce0e 🤖 Auto commit for release 'develop' on 2025-09-01 2025-09-01 20:44:09 +02:00
James Cole
26a8bd921d Fix columns, improve views. 2025-09-01 20:39:40 +02:00
github-actions[bot]
ad77d55c16 Merge pull request #10844 from firefly-iii/release-1756729274
🤖 Automatically merge the PR into the develop branch.
2025-09-01 14:21:21 +02:00
JC5
445a383dd0 🤖 Auto commit for release 'develop' on 2025-09-01 2025-09-01 14:21:14 +02:00
Sander Dorigo
1666af939e Fix null 2025-09-01 14:03:21 +02:00
github-actions[bot]
35447f5eee Merge pull request #10843 from firefly-iii/release-1756727799
🤖 Automatically merge the PR into the develop branch.
2025-09-01 13:56:46 +02:00
JC5
7c6fcb5731 🤖 Auto commit for release 'develop' on 2025-09-01 2025-09-01 13:56:39 +02:00
Sander Dorigo
fabd9bf765 Merge branch 'develop' of https://github.com/firefly-iii/firefly-iii into develop 2025-09-01 13:38:39 +02:00
Sander Dorigo
6352d26633 fix argument 2025-09-01 13:38:32 +02:00
github-actions[bot]
ebef145bd6 Merge pull request #10842 from firefly-iii/release-1756723300
🤖 Automatically merge the PR into the develop branch.
2025-09-01 12:41:48 +02:00
JC5
acc89eb5f9 🤖 Auto commit for release 'develop' on 2025-09-01 2025-09-01 12:41:40 +02:00
Sander Dorigo
6523596415 fix bad call 2025-09-01 12:36:36 +02:00
284 changed files with 2018 additions and 4287 deletions

View File

@@ -402,16 +402,16 @@
}, },
{ {
"name": "friendsofphp/php-cs-fixer", "name": "friendsofphp/php-cs-fixer",
"version": "v3.86.0", "version": "v3.87.1",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer.git", "url": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer.git",
"reference": "4a952bd19dc97879b0620f495552ef09b55f7d36" "reference": "2f5170365e2a422d0c5421f9c8818b2c078105f6"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/PHP-CS-Fixer/PHP-CS-Fixer/zipball/4a952bd19dc97879b0620f495552ef09b55f7d36", "url": "https://api.github.com/repos/PHP-CS-Fixer/PHP-CS-Fixer/zipball/2f5170365e2a422d0c5421f9c8818b2c078105f6",
"reference": "4a952bd19dc97879b0620f495552ef09b55f7d36", "reference": "2f5170365e2a422d0c5421f9c8818b2c078105f6",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@@ -422,39 +422,38 @@
"ext-hash": "*", "ext-hash": "*",
"ext-json": "*", "ext-json": "*",
"ext-tokenizer": "*", "ext-tokenizer": "*",
"fidry/cpu-core-counter": "^1.2", "fidry/cpu-core-counter": "^1.3",
"php": "^7.4 || ^8.0", "php": "^7.4 || ^8.0",
"react/child-process": "^0.6.6", "react/child-process": "^0.6.6",
"react/event-loop": "^1.5", "react/event-loop": "^1.5",
"react/promise": "^3.2", "react/promise": "^3.3",
"react/socket": "^1.16", "react/socket": "^1.16",
"react/stream": "^1.4", "react/stream": "^1.4",
"sebastian/diff": "^4.0.6 || ^5.1.1 || ^6.0.2 || ^7.0", "sebastian/diff": "^4.0.6 || ^5.1.1 || ^6.0.2 || ^7.0",
"symfony/console": "^5.4.47 || ^6.4.13 || ^7.0", "symfony/console": "^5.4.47 || ^6.4.24 || ^7.0",
"symfony/event-dispatcher": "^5.4.45 || ^6.4.13 || ^7.0", "symfony/event-dispatcher": "^5.4.45 || ^6.4.24 || ^7.0",
"symfony/filesystem": "^5.4.45 || ^6.4.13 || ^7.0", "symfony/filesystem": "^5.4.45 || ^6.4.24 || ^7.0",
"symfony/finder": "^5.4.45 || ^6.4.17 || ^7.0", "symfony/finder": "^5.4.45 || ^6.4.24 || ^7.0",
"symfony/options-resolver": "^5.4.45 || ^6.4.16 || ^7.0", "symfony/options-resolver": "^5.4.45 || ^6.4.24 || ^7.0",
"symfony/polyfill-mbstring": "^1.32", "symfony/polyfill-mbstring": "^1.33",
"symfony/polyfill-php80": "^1.32", "symfony/polyfill-php80": "^1.33",
"symfony/polyfill-php81": "^1.32", "symfony/polyfill-php81": "^1.33",
"symfony/process": "^5.4.47 || ^6.4.20 || ^7.2", "symfony/process": "^5.4.47 || ^6.4.24 || ^7.2",
"symfony/stopwatch": "^5.4.45 || ^6.4.19 || ^7.0" "symfony/stopwatch": "^5.4.45 || ^6.4.24 || ^7.0"
}, },
"require-dev": { "require-dev": {
"facile-it/paraunit": "^1.3.1 || ^2.6", "facile-it/paraunit": "^1.3.1 || ^2.7",
"infection/infection": "^0.29.14", "infection/infection": "^0.29.14",
"justinrainbow/json-schema": "^5.3 || ^6.4", "justinrainbow/json-schema": "^6.5",
"keradus/cli-executor": "^2.2", "keradus/cli-executor": "^2.2",
"mikey179/vfsstream": "^1.6.12", "mikey179/vfsstream": "^1.6.12",
"php-coveralls/php-coveralls": "^2.8", "php-coveralls/php-coveralls": "^2.8",
"php-cs-fixer/accessible-object": "^1.1",
"php-cs-fixer/phpunit-constraint-isidenticalstring": "^1.6", "php-cs-fixer/phpunit-constraint-isidenticalstring": "^1.6",
"php-cs-fixer/phpunit-constraint-xmlmatchesxsd": "^1.6", "php-cs-fixer/phpunit-constraint-xmlmatchesxsd": "^1.6",
"phpunit/phpunit": "^9.6.23 || ^10.5.47 || ^11.5.25", "phpunit/phpunit": "^9.6.25 || ^10.5.53 || ^11.5.34",
"symfony/polyfill-php84": "^1.32", "symfony/polyfill-php84": "^1.33",
"symfony/var-dumper": "^5.4.48 || ^6.4.23 || ^7.3.1", "symfony/var-dumper": "^5.4.48 || ^6.4.24 || ^7.3.2",
"symfony/yaml": "^5.4.45 || ^6.4.23 || ^7.3.1" "symfony/yaml": "^5.4.45 || ^6.4.24 || ^7.3.2"
}, },
"suggest": { "suggest": {
"ext-dom": "For handling output formats in XML", "ext-dom": "For handling output formats in XML",
@@ -495,7 +494,7 @@
], ],
"support": { "support": {
"issues": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/issues", "issues": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/issues",
"source": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/tree/v3.86.0" "source": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/tree/v3.87.1"
}, },
"funding": [ "funding": [
{ {
@@ -503,7 +502,7 @@
"type": "github" "type": "github"
} }
], ],
"time": "2025-08-13T22:36:21+00:00" "time": "2025-09-02T15:27:36+00:00"
}, },
{ {
"name": "psr/container", "name": "psr/container",

View File

@@ -1,6 +1,4 @@
parameters: parameters:
scanFiles:
- ../_ide_helper.php
paths: paths:
- ../app - ../app
- ../database - ../database
@@ -9,28 +7,24 @@ parameters:
- ../bootstrap/app.php - ../bootstrap/app.php
universalObjectCratesClasses: universalObjectCratesClasses:
- Illuminate\Database\Eloquent\Model - Illuminate\Database\Eloquent\Model
# TODO: slowly remove these parameters and fix the issues found.
reportUnmatchedIgnoredErrors: true reportUnmatchedIgnoredErrors: true
ignoreErrors: ignoreErrors:
# TODO: slowly remove these exceptions and fix the issues found. # all errors below I will never fix.
- '#Dynamic call to static method#' # all the Laravel ORM things depend on this. - '#expects view-string\|null, string given#'
- identifier: varTag.nativeType - '#expects view-string, string given#'
- identifier: varTag.type - "#Parameter \\#[1-2] \\$num[1-2] of function bc[a-z]+ expects numeric-string, [a-z\\-|&]+ given#"
- identifier: missingType.generics # not interesting enough to fix.
- -
identifier: larastan.noEnvCallsOutsideOfConfig identifier: larastan.noEnvCallsOutsideOfConfig
path: ../app/Console/Commands/System/CreatesDatabase.php path: ../app/Console/Commands/System/CreatesDatabase.php
- identifier: missingType.iterableValue # not interesting enough to fix. - identifier: missingType.iterableValue # not interesting enough to fix.
- identifier: missingType.generics # not interesting enough to fix. - identifier: varTag.type # needs a custom extension for every repository, not gonna happen.
- "#Parameter \\#[1-2] \\$num[1-2] of function bc[a-z]+ expects numeric-string, [a-z\\-|&]+ given#" - '#Dynamic call to static method Illuminate#'
- '#expects view-string, string given#' - '#Call to an undefined method Illuminate\\Database\\Eloquent\\Relations\\HasMany::before#' # is custom scope
- '#expects view-string\|null, string given#' - '#Call to an undefined method Illuminate\\Database\\Eloquent\\Relations\\HasMany::after#' # is custom scope
- '#Call to an undefined method Illuminate\\Database\\Eloquent\\Relations\\HasMany::withTrashed#' # is to allow soft delete
# phpstan can't handle this so we ignore them. - '#Call to an undefined method Illuminate\\Database\\Eloquent\\Relations\\HasMany::accountTypeIn#' # is a custom scope
- '#Call to an undefined method Illuminate\\Database\\Eloquent\\Relations\\HasMany::before#' - '#Call to an undefined method Illuminate\\Database\\Eloquent\\Relations\\BelongsTo::withTrashed#' # is to allow soft delete
- '#Call to an undefined method Illuminate\\Database\\Eloquent\\Relations\\HasMany::after#'
- '#Call to an undefined method Illuminate\\Database\\Eloquent\\Relations\\HasMany::withTrashed#'
- '#Call to an undefined method Illuminate\\Database\\Eloquent\\Relations\\HasMany::accountTypeIn#'
- '#Call to an undefined method Illuminate\\Database\\Eloquent\\Relations\\BelongsTo::withTrashed#'
# The level 8 is the highest level. original was 5 # The level 8 is the highest level. original was 5
# 7 is more than enough, higher just leaves NULL things. # 7 is more than enough, higher just leaves NULL things.

View File

@@ -15,7 +15,7 @@ jobs:
timeout-minutes: 10 timeout-minutes: 10
steps: steps:
- name: Prune cancelled/skipped runs - name: Prune cancelled/skipped runs
uses: actions/github-script@v7 uses: actions/github-script@v8
with: with:
github-token: ${{ secrets.GITHUB_TOKEN }} github-token: ${{ secrets.GITHUB_TOKEN }}
script: | script: |
@@ -45,7 +45,7 @@ jobs:
} }
- name: Prune runs older than 3 days - name: Prune runs older than 3 days
uses: actions/github-script@v7 uses: actions/github-script@v8
with: with:
github-token: ${{ secrets.GITHUB_TOKEN }} github-token: ${{ secrets.GITHUB_TOKEN }}
script: | script: |

View File

@@ -250,7 +250,7 @@ jobs:
fi fi
echo "Merge all changes from $BRANCH_NAME back into '$MERGE_INTO' using a PR" echo "Merge all changes from $BRANCH_NAME back into '$MERGE_INTO' using a PR"
PR_URL=$(gh pr create -B $MERGE_INTO -H $BRANCH_NAME --title "🤖 Automatic PR to merge all changes into the '$MERGE_INTO' branch." --body '🤖 Created by GitHub action') PR_URL=$(gh pr create -B $MERGE_INTO -H $BRANCH_NAME --title "🤖 Automatic PR to merge all changes into the '$MERGE_INTO' branch." --body '🤖 This PR was created automatically by a GitHub action to merge the changed files into this branch. It will be merged automatically. `Share and enjoy`')
echo "PR URL is '$PR_URL'" echo "PR URL is '$PR_URL'"
IFS='/' read -ra parts <<< "$PR_URL" IFS='/' read -ra parts <<< "$PR_URL"
PR_NR=$(printf %s\\n "${parts[@]:(-1)}") PR_NR=$(printf %s\\n "${parts[@]:(-1)}")
@@ -272,7 +272,7 @@ jobs:
echo "Also merge everything into main since this is a release." echo "Also merge everything into main since this is a release."
echo 'create PR' echo 'create PR'
PR_URL=$(gh pr create -B main -H develop --title "🤖 Automatic PR to merge all changes into the main branch." --body "🤖 Created by GitHub action") PR_URL=$(gh pr create -B main -H develop --title "🤖 Automatic PR to merge all changes into the main branch." --body "🤖 This PR was created automatically by a GitHub action to merge the changed files into this branch. It will be merged automatically. `Share and enjoy`")
echo "PR URL is '$PR_URL'" echo "PR URL is '$PR_URL'"
IFS='/' read -ra parts <<< "$PR_URL" IFS='/' read -ra parts <<< "$PR_URL"

View File

@@ -15,7 +15,7 @@ jobs:
actions: write actions: write
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/stale@v9 - uses: actions/stale@v10
with: with:
repo-token: ${{ secrets.GITHUB_TOKEN }} repo-token: ${{ secrets.GITHUB_TOKEN }}
stale-issue-message: | stale-issue-message: |

View File

@@ -31,10 +31,10 @@ use FireflyIII\Enums\UserRoleEnum;
use FireflyIII\Exceptions\FireflyException; use FireflyIII\Exceptions\FireflyException;
use FireflyIII\Models\Budget; use FireflyIII\Models\Budget;
use FireflyIII\Models\BudgetLimit; use FireflyIII\Models\BudgetLimit;
use FireflyIII\Models\TransactionCurrency;
use FireflyIII\Repositories\Budget\BudgetLimitRepositoryInterface; use FireflyIII\Repositories\Budget\BudgetLimitRepositoryInterface;
use FireflyIII\Repositories\Budget\BudgetRepositoryInterface; use FireflyIII\Repositories\Budget\BudgetRepositoryInterface;
use FireflyIII\Repositories\Budget\OperationsRepositoryInterface; use FireflyIII\Repositories\Budget\OperationsRepositoryInterface;
use FireflyIII\Support\Facades\Amount;
use FireflyIII\Support\Http\Api\CleansChartData; use FireflyIII\Support\Http\Api\CleansChartData;
use FireflyIII\Support\Http\Api\ExchangeRateConverter; use FireflyIII\Support\Http\Api\ExchangeRateConverter;
use FireflyIII\Support\Http\Api\ValidatesUserGroupTrait; use FireflyIII\Support\Http\Api\ValidatesUserGroupTrait;
@@ -55,7 +55,6 @@ class BudgetController extends Controller
protected OperationsRepositoryInterface $opsRepository; protected OperationsRepositoryInterface $opsRepository;
private BudgetLimitRepositoryInterface $blRepository; private BudgetLimitRepositoryInterface $blRepository;
private array $currencies = []; private array $currencies = [];
private TransactionCurrency $currency;
private BudgetRepositoryInterface $repository; private BudgetRepositoryInterface $repository;
public function __construct() public function __construct()
@@ -134,9 +133,9 @@ class BudgetController extends Controller
$row['pc_left'] = '0'; $row['pc_left'] = '0';
$row['pc_overspent'] = '0'; $row['pc_overspent'] = '0';
if (null !== $limit) { if ($limit instanceof BudgetLimit) {
$row['budgeted'] = $limit->amount; $row['budgeted'] = $limit->amount;
$row['left'] = bcsub($row['budgeted'], bcmul($row['spent'], '-1')); $row['left'] = bcsub((string) $row['budgeted'], bcmul((string) $row['spent'], '-1'));
$row['overspent'] = bcmul($row['left'], '-1'); $row['overspent'] = bcmul($row['left'], '-1');
$row['left'] = 1 === bccomp($row['left'], '0') ? $row['left'] : '0'; $row['left'] = 1 === bccomp($row['left'], '0') ? $row['left'] : '0';
$row['overspent'] = 1 === bccomp($row['overspent'], '0') ? $row['overspent'] : '0'; $row['overspent'] = 1 === bccomp($row['overspent'], '0') ? $row['overspent'] : '0';
@@ -144,7 +143,7 @@ class BudgetController extends Controller
// convert data if necessary. // convert data if necessary.
if (true === $this->convertToPrimary && $currencyId !== $this->primaryCurrency->id) { if (true === $this->convertToPrimary && $currencyId !== $this->primaryCurrency->id) {
$currencies[$currencyId] ??= TransactionCurrency::find($currencyId); $currencies[$currencyId] ??= Amount::getTransactionCurrencyById($currencyId);
$row['pc_budgeted'] = $converter->convert($currencies[$currencyId], $this->primaryCurrency, $start, $row['budgeted']); $row['pc_budgeted'] = $converter->convert($currencies[$currencyId], $this->primaryCurrency, $start, $row['budgeted']);
$row['pc_spent'] = $converter->convert($currencies[$currencyId], $this->primaryCurrency, $start, $row['spent']); $row['pc_spent'] = $converter->convert($currencies[$currencyId], $this->primaryCurrency, $start, $row['spent']);
$row['pc_left'] = $converter->convert($currencies[$currencyId], $this->primaryCurrency, $start, $row['left']); $row['pc_left'] = $converter->convert($currencies[$currencyId], $this->primaryCurrency, $start, $row['left']);
@@ -201,18 +200,18 @@ class BudgetController extends Controller
return $return; return $return;
} }
/** // /**
* When no budget limits are present, the expenses of the whole period are collected and grouped. // * When no budget limits are present, the expenses of the whole period are collected and grouped.
* This is grouped per currency. Because there is no limit set, "left to spend" and "overspent" are empty. // * This is grouped per currency. Because there is no limit set, "left to spend" and "overspent" are empty.
* // *
* @throws FireflyException // * @throws FireflyException
*/ // */
private function noBudgetLimits(Budget $budget, Carbon $start, Carbon $end): array // private function noBudgetLimits(Budget $budget, Carbon $start, Carbon $end): array
{ // {
$spent = $this->opsRepository->listExpenses($start, $end, null, new Collection([$budget])); // $spent = $this->opsRepository->listExpenses($start, $end, null, new Collection([$budget]));
//
return $this->processExpenses($budget->id, $spent, $start, $end); // return $this->processExpenses($budget->id, $spent, $start, $end);
} // }
/** /**
* Shared between the "noBudgetLimits" function and "processLimit". Will take a single set of expenses and return * Shared between the "noBudgetLimits" function and "processLimit". Will take a single set of expenses and return
@@ -232,7 +231,7 @@ class BudgetController extends Controller
* @var array $block * @var array $block
*/ */
foreach ($spent as $currencyId => $block) { foreach ($spent as $currencyId => $block) {
$this->currencies[$currencyId] ??= TransactionCurrency::find($currencyId); $this->currencies[$currencyId] ??= Amount::getTransactionCurrencyById($currencyId);
$return[$currencyId] ??= [ $return[$currencyId] ??= [
'currency_id' => (string)$currencyId, 'currency_id' => (string)$currencyId,
'currency_code' => $block['currency_code'], 'currency_code' => $block['currency_code'],
@@ -251,66 +250,68 @@ class BudgetController extends Controller
// var_dump($return); // var_dump($return);
/** @var array $journal */ /** @var array $journal */
foreach ($currentBudgetArray['transaction_journals'] as $journal) { foreach ($currentBudgetArray['transaction_journals'] as $journal) {
$return[$currencyId]['spent'] = bcadd($return[$currencyId]['spent'], (string)$journal['amount']); /** @var numeric-string $amount */
$amount = (string)$journal['amount'];
$return[$currencyId]['spent'] = bcadd($return[$currencyId]['spent'], $amount);
} }
} }
return $return; return $return;
} }
/** // /**
* Function that processes each budget limit (per budget). // * Function that processes each budget limit (per budget).
* // *
* If you have a budget limit in EUR, only transactions in EUR will be considered. // * If you have a budget limit in EUR, only transactions in EUR will be considered.
* If you have a budget limit in GBP, only transactions in GBP will be considered. // * If you have a budget limit in GBP, only transactions in GBP will be considered.
* // *
* If you have a budget limit in EUR, and a transaction in GBP, it will not be considered for the EUR budget limit. // * If you have a budget limit in EUR, and a transaction in GBP, it will not be considered for the EUR budget limit.
* // *
* @throws FireflyException // * @throws FireflyException
*/ // */
private function budgetLimits(Budget $budget, Collection $limits): array // private function budgetLimits(Budget $budget, Collection $limits): array
{ // {
Log::debug(sprintf('Now in budgetLimits(#%d)', $budget->id)); // Log::debug(sprintf('Now in budgetLimits(#%d)', $budget->id));
$data = []; // $data = [];
//
// /** @var BudgetLimit $limit */
// foreach ($limits as $limit) {
// $data = array_merge($data, $this->processLimit($budget, $limit));
// }
//
// return $data;
// }
/** @var BudgetLimit $limit */ // /**
foreach ($limits as $limit) { // * @throws FireflyException
$data = array_merge($data, $this->processLimit($budget, $limit)); // */
} // private function processLimit(Budget $budget, BudgetLimit $limit): array
// {
return $data; // 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]));
* @throws FireflyException // $limitCurrencyId = $limit->transaction_currency_id;
*/ //
private function processLimit(Budget $budget, BudgetLimit $limit): array // /** @var array $entry */
{ // // only spent the entry where the entry's currency matches the budget limit's currency
Log::debug(sprintf('Created new ExchangeRateConverter in %s', __METHOD__)); // // so $filtered will only have 1 or 0 entries
$end = clone $limit->end_date; // $filtered = array_filter($spent, fn ($entry) => $entry['currency_id'] === $limitCurrencyId);
$end->endOfDay(); // $result = $this->processExpenses($budget->id, $filtered, $limit->start_date, $end);
$spent = $this->opsRepository->listExpenses($limit->start_date, $end, null, new Collection([$budget])); // if (1 === count($result)) {
$limitCurrencyId = $limit->transaction_currency_id; // $compare = bccomp($limit->amount, (string)app('steam')->positive($result[$limitCurrencyId]['spent']));
// $result[$limitCurrencyId]['budgeted'] = $limit->amount;
/** @var array $entry */ // if (1 === $compare) {
// only spent the entry where the entry's currency matches the budget limit's currency // // convert this amount into the primary currency:
// so $filtered will only have 1 or 0 entries // $result[$limitCurrencyId]['left'] = bcadd($limit->amount, (string)$result[$limitCurrencyId]['spent']);
$filtered = array_filter($spent, fn ($entry) => $entry['currency_id'] === $limitCurrencyId); // }
$result = $this->processExpenses($budget->id, $filtered, $limit->start_date, $end); // if ($compare <= 0) {
if (1 === count($result)) { // $result[$limitCurrencyId]['overspent'] = app('steam')->positive(bcadd($limit->amount, (string)$result[$limitCurrencyId]['spent']));
$compare = bccomp($limit->amount, (string)app('steam')->positive($result[$limitCurrencyId]['spent'])); // }
$result[$limitCurrencyId]['budgeted'] = $limit->amount; // }
if (1 === $compare) { //
// convert this amount into the primary currency: // return $result;
$result[$limitCurrencyId]['left'] = bcadd($limit->amount, (string)$result[$limitCurrencyId]['spent']); // }
}
if ($compare <= 0) {
$result[$limitCurrencyId]['overspent'] = app('steam')->positive(bcadd($limit->amount, (string)$result[$limitCurrencyId]['spent']));
}
}
return $result;
}
private function filterLimit(int $currencyId, Collection $limits): ?BudgetLimit private function filterLimit(int $currencyId, Collection $limits): ?BudgetLimit
{ {

View File

@@ -27,7 +27,6 @@ namespace FireflyIII\Api\V1\Controllers;
use Carbon\Carbon; use Carbon\Carbon;
use Carbon\Exceptions\InvalidFormatException; use Carbon\Exceptions\InvalidFormatException;
use FireflyIII\Exceptions\BadHttpHeaderException; use FireflyIII\Exceptions\BadHttpHeaderException;
use FireflyIII\Models\Preference;
use FireflyIII\Models\TransactionCurrency; use FireflyIII\Models\TransactionCurrency;
use FireflyIII\Support\Facades\Amount; use FireflyIII\Support\Facades\Amount;
use FireflyIII\Support\Facades\Steam; use FireflyIII\Support\Facades\Steam;
@@ -66,8 +65,6 @@ abstract class Controller extends BaseController
protected const string JSON_CONTENT_TYPE = 'application/json'; protected const string JSON_CONTENT_TYPE = 'application/json';
protected array $accepts = ['application/json', 'application/vnd.api+json']; protected array $accepts = ['application/json', 'application/vnd.api+json'];
/** @var array<int, string> */
protected array $allowedSort;
protected bool $convertToPrimary = false; protected bool $convertToPrimary = false;
protected TransactionCurrency $primaryCurrency; protected TransactionCurrency $primaryCurrency;
protected ParameterBag $parameters; protected ParameterBag $parameters;
@@ -78,7 +75,6 @@ abstract class Controller extends BaseController
public function __construct() public function __construct()
{ {
// get global parameters // get global parameters
$this->allowedSort = config('firefly.allowed_sort_parameters');
$this->middleware( $this->middleware(
function ($request, $next) { function ($request, $next) {
$this->parameters = $this->getParameters(); $this->parameters = $this->getParameters();
@@ -150,13 +146,7 @@ abstract class Controller extends BaseController
} }
if (null !== $value) { if (null !== $value) {
$value = (int)$value; $value = (int)$value;
if ($value < 1) { $value = min(max(1, $value), 2 ** 16);
$value = 1;
}
if ($value > 2 ** 16) {
$value = 2 ** 16;
}
$bag->set($integer, $value); $bag->set($integer, $value);
} }
if (null === $value if (null === $value
@@ -166,46 +156,14 @@ abstract class Controller extends BaseController
/** @var User $user */ /** @var User $user */
$user = auth()->user(); $user = auth()->user();
/** @var Preference $pageSize */
$pageSize = (int)app('preferences')->getForUser($user, 'listPageSize', 50)->data; $pageSize = (int)app('preferences')->getForUser($user, 'listPageSize', 50)->data;
$bag->set($integer, $pageSize); $bag->set($integer, $pageSize);
} }
} }
// sort fields: // sort fields:
return $this->getSortParameters($bag);
}
private function getSortParameters(ParameterBag $bag): ParameterBag
{
$sortParameters = [];
try {
$param = (string)request()->query->get('sort');
} catch (BadRequestException $e) {
Log::error('Request field "sort" contains a non-scalar value. Value set to NULL.');
Log::error($e->getMessage());
Log::error($e->getTraceAsString());
$param = '';
}
if ('' === $param) {
return $bag;
}
$parts = explode(',', $param);
foreach ($parts as $part) {
$part = trim($part);
$direction = 'asc';
if ('-' === $part[0]) {
$part = substr($part, 1);
$direction = 'desc';
}
if (in_array($part, $this->allowedSort, true)) {
$sortParameters[] = [$part, $direction];
}
}
$bag->set('sort', $sortParameters);
return $bag; return $bag;
// return $this->getSortParameters($bag);
} }
/** /**

View File

@@ -29,6 +29,7 @@ use FireflyIII\Api\V1\Requests\Insight\GenericRequest;
use FireflyIII\Enums\TransactionTypeEnum; use FireflyIII\Enums\TransactionTypeEnum;
use FireflyIII\Helpers\Collector\GroupCollectorInterface; use FireflyIII\Helpers\Collector\GroupCollectorInterface;
use FireflyIII\Support\Facades\Amount; use FireflyIII\Support\Facades\Amount;
use FireflyIII\Support\Facades\Steam;
use Illuminate\Http\JsonResponse; use Illuminate\Http\JsonResponse;
/** /**
@@ -71,7 +72,7 @@ class PeriodController extends Controller
'currency_id' => (string) $currencyId, 'currency_id' => (string) $currencyId,
'currency_code' => $currencyCode, 'currency_code' => $currencyCode,
]; ];
$response[$currencyId]['difference'] = bcadd($response[$currencyId]['difference'], (string) app('steam')->positive($journal[$field])); $response[$currencyId]['difference'] = bcadd($response[$currencyId]['difference'], Steam::positive($journal[$field]));
$response[$currencyId]['difference_float'] = (float) $response[$currencyId]['difference']; // float but on purpose. $response[$currencyId]['difference_float'] = (float) $response[$currencyId]['difference']; // float but on purpose.
} }

View File

@@ -30,6 +30,7 @@ use FireflyIII\Enums\TransactionTypeEnum;
use FireflyIII\Helpers\Collector\GroupCollectorInterface; use FireflyIII\Helpers\Collector\GroupCollectorInterface;
use FireflyIII\Repositories\Tag\TagRepositoryInterface; use FireflyIII\Repositories\Tag\TagRepositoryInterface;
use FireflyIII\Support\Facades\Amount; use FireflyIII\Support\Facades\Amount;
use FireflyIII\Support\Facades\Steam;
use Illuminate\Http\JsonResponse; use Illuminate\Http\JsonResponse;
/** /**
@@ -97,7 +98,7 @@ class TagController extends Controller
'currency_id' => (string) $currencyId, 'currency_id' => (string) $currencyId,
'currency_code' => $currencyCode, 'currency_code' => $currencyCode,
]; ];
$response[$currencyId]['difference'] = bcadd($response[$currencyId]['difference'], (string) app('steam')->positive($journal[$field])); $response[$currencyId]['difference'] = bcadd($response[$currencyId]['difference'], Steam::positive($journal[$field]));
$response[$currencyId]['difference_float'] = (float) $response[$currencyId]['difference']; $response[$currencyId]['difference_float'] = (float) $response[$currencyId]['difference'];
} }
@@ -148,7 +149,7 @@ class TagController extends Controller
'currency_id' => (string) $currencyId, 'currency_id' => (string) $currencyId,
'currency_code' => $journal['currency_code'], 'currency_code' => $journal['currency_code'],
]; ];
$response[$key]['difference'] = bcadd((string) $response[$key]['difference'], (string) app('steam')->positive($journal['amount'])); $response[$key]['difference'] = bcadd((string) $response[$key]['difference'], Steam::positive($journal['amount']));
$response[$key]['difference_float'] = (float) $response[$key]['difference']; $response[$key]['difference_float'] = (float) $response[$key]['difference'];
} }
@@ -160,10 +161,7 @@ class TagController extends Controller
'currency_id' => (string) $foreignCurrencyId, 'currency_id' => (string) $foreignCurrencyId,
'currency_code' => $journal['foreign_currency_code'], 'currency_code' => $journal['foreign_currency_code'],
]; ];
$response[$foreignKey]['difference'] = bcadd( $response[$foreignKey]['difference'] = bcadd((string) $response[$foreignKey]['difference'], Steam::positive($journal['foreign_amount']));
(string) $response[$foreignKey]['difference'],
(string) app('steam')->positive($journal['foreign_amount'])
);
$response[$foreignKey]['difference_float'] = (float) $response[$foreignKey]['difference']; $response[$foreignKey]['difference_float'] = (float) $response[$foreignKey]['difference'];
} }
} }

View File

@@ -29,6 +29,7 @@ use FireflyIII\Api\V1\Requests\Insight\GenericRequest;
use FireflyIII\Enums\TransactionTypeEnum; use FireflyIII\Enums\TransactionTypeEnum;
use FireflyIII\Helpers\Collector\GroupCollectorInterface; use FireflyIII\Helpers\Collector\GroupCollectorInterface;
use FireflyIII\Support\Facades\Amount; use FireflyIII\Support\Facades\Amount;
use FireflyIII\Support\Facades\Steam;
use Illuminate\Http\JsonResponse; use Illuminate\Http\JsonResponse;
/** /**
@@ -71,7 +72,7 @@ class PeriodController extends Controller
'currency_id' => (string) $currencyId, 'currency_id' => (string) $currencyId,
'currency_code' => $currencyCode, 'currency_code' => $currencyCode,
]; ];
$response[$currencyId]['difference'] = bcadd($response[$currencyId]['difference'], (string) app('steam')->positive($journal[$field])); $response[$currencyId]['difference'] = bcadd($response[$currencyId]['difference'], Steam::positive($journal[$field]));
$response[$currencyId]['difference_float'] = (float) $response[$currencyId]['difference']; $response[$currencyId]['difference_float'] = (float) $response[$currencyId]['difference'];
} }

View File

@@ -30,6 +30,7 @@ use FireflyIII\Enums\TransactionTypeEnum;
use FireflyIII\Helpers\Collector\GroupCollectorInterface; use FireflyIII\Helpers\Collector\GroupCollectorInterface;
use FireflyIII\Repositories\Tag\TagRepositoryInterface; use FireflyIII\Repositories\Tag\TagRepositoryInterface;
use FireflyIII\Support\Facades\Amount; use FireflyIII\Support\Facades\Amount;
use FireflyIII\Support\Facades\Steam;
use Illuminate\Http\JsonResponse; use Illuminate\Http\JsonResponse;
/** /**
@@ -95,7 +96,7 @@ class TagController extends Controller
'currency_id' => (string) $currencyId, 'currency_id' => (string) $currencyId,
'currency_code' => $currencyCode, 'currency_code' => $currencyCode,
]; ];
$response[$currencyId]['difference'] = bcadd($response[$currencyId]['difference'], (string) app('steam')->positive($journal[$field])); $response[$currencyId]['difference'] = bcadd($response[$currencyId]['difference'], Steam::positive($journal[$field]));
$response[$currencyId]['difference_float'] = (float) $response[$currencyId]['difference']; $response[$currencyId]['difference_float'] = (float) $response[$currencyId]['difference'];
} }
@@ -146,7 +147,7 @@ class TagController extends Controller
'currency_id' => (string) $currencyId, 'currency_id' => (string) $currencyId,
'currency_code' => $journal['currency_code'], 'currency_code' => $journal['currency_code'],
]; ];
$response[$key]['difference'] = bcadd((string) $response[$key]['difference'], (string) app('steam')->positive($journal['amount'])); $response[$key]['difference'] = bcadd((string) $response[$key]['difference'], Steam::positive($journal['amount']));
$response[$key]['difference_float'] = (float) $response[$key]['difference']; $response[$key]['difference_float'] = (float) $response[$key]['difference'];
} }
@@ -160,7 +161,7 @@ class TagController extends Controller
]; ];
$response[$foreignKey]['difference'] = bcadd( $response[$foreignKey]['difference'] = bcadd(
(string) $response[$foreignKey]['difference'], (string) $response[$foreignKey]['difference'],
(string) app('steam')->positive($journal['foreign_amount']) Steam::positive($journal['foreign_amount'])
); );
$response[$foreignKey]['difference_float'] = (float) $response[$foreignKey]['difference']; // intentional float $response[$foreignKey]['difference_float'] = (float) $response[$foreignKey]['difference']; // intentional float
} }

View File

@@ -86,13 +86,18 @@ class ShowController extends Controller
$count = $collection->count(); $count = $collection->count();
// continue sort: // continue sort:
// TODO if the user sorts on DB dependent field there must be no slice before enrichment, only after.
// TODO still need to figure out how to do this easily.
$accounts = $collection->slice(($this->parameters->get('page') - 1) * $params['limit'], $params['limit']); $accounts = $collection->slice(($this->parameters->get('page') - 1) * $params['limit'], $params['limit']);
// enrich // enrich
/** @var User $admin */ /** @var User $admin */
$admin = auth()->user(); $admin = auth()->user();
$enrichment = new AccountEnrichment(); $enrichment = new AccountEnrichment();
$enrichment->setSort($params['sort']);
$enrichment->setDate($this->parameters->get('date')); $enrichment->setDate($this->parameters->get('date'));
$enrichment->setStart($this->parameters->get('start'));
$enrichment->setEnd($this->parameters->get('end'));
$enrichment->setUser($admin); $enrichment->setUser($admin);
$accounts = $enrichment->enrich($accounts); $accounts = $enrichment->enrich($accounts);
@@ -116,7 +121,7 @@ class ShowController extends Controller
* *
* Show single instance. * Show single instance.
*/ */
public function show(Account $account): JsonResponse public function show(ShowRequest $request, Account $account): JsonResponse
{ {
// get list of accounts. Count it and split it. // get list of accounts. Count it and split it.
$this->repository->resetAccountOrder(); $this->repository->resetAccountOrder();
@@ -128,6 +133,8 @@ class ShowController extends Controller
$admin = auth()->user(); $admin = auth()->user();
$enrichment = new AccountEnrichment(); $enrichment = new AccountEnrichment();
$enrichment->setDate($this->parameters->get('date')); $enrichment->setDate($this->parameters->get('date'));
$enrichment->setStart($this->parameters->get('start'));
$enrichment->setEnd($this->parameters->get('end'));
$enrichment->setUser($admin); $enrichment->setUser($admin);
$account = $enrichment->enrichSingle($account); $account = $enrichment->enrichSingle($account);

View File

@@ -114,8 +114,8 @@ class ShowController extends Controller
public function show(AvailableBudget $availableBudget): JsonResponse public function show(AvailableBudget $availableBudget): JsonResponse
{ {
$manager = $this->getManager(); $manager = $this->getManager();
$start = $this->parameters->get('start'); // $start = $this->parameters->get('start');
$end = $this->parameters->get('end'); // $end = $this->parameters->get('end');
/** @var AvailableBudgetTransformer $transformer */ /** @var AvailableBudgetTransformer $transformer */
$transformer = app(AvailableBudgetTransformer::class); $transformer = app(AvailableBudgetTransformer::class);
@@ -126,8 +126,8 @@ class ShowController extends Controller
$admin = auth()->user(); $admin = auth()->user();
$enrichment = new AvailableBudgetEnrichment(); $enrichment = new AvailableBudgetEnrichment();
$enrichment->setUser($admin); $enrichment->setUser($admin);
$enrichment->setStart($start); // $enrichment->setStart($start);
$enrichment->setEnd($end); // $enrichment->setEnd($end);
$availableBudget = $enrichment->enrichSingle($availableBudget); $availableBudget = $enrichment->enrichSingle($availableBudget);

View File

@@ -84,6 +84,8 @@ class ShowController extends Controller
$enrichment->setUser($admin); $enrichment->setUser($admin);
$enrichment->setStart($this->parameters->get('start')); $enrichment->setStart($this->parameters->get('start'));
$enrichment->setEnd($this->parameters->get('end')); $enrichment->setEnd($this->parameters->get('end'));
/** @var Budget $budget */
$budget = $enrichment->enrichSingle($budget); $budget = $enrichment->enrichSingle($budget);

View File

@@ -33,6 +33,7 @@ use FireflyIII\Enums\UserRoleEnum;
use FireflyIII\Models\CurrencyExchangeRate; use FireflyIII\Models\CurrencyExchangeRate;
use FireflyIII\Models\TransactionCurrency; use FireflyIII\Models\TransactionCurrency;
use FireflyIII\Repositories\ExchangeRate\ExchangeRateRepositoryInterface; use FireflyIII\Repositories\ExchangeRate\ExchangeRateRepositoryInterface;
use FireflyIII\Support\Facades\Amount;
use FireflyIII\Support\Http\Api\ValidatesUserGroupTrait; use FireflyIII\Support\Http\Api\ValidatesUserGroupTrait;
use FireflyIII\Transformers\ExchangeRateTransformer; use FireflyIII\Transformers\ExchangeRateTransformer;
use Illuminate\Http\JsonResponse; use Illuminate\Http\JsonResponse;
@@ -69,7 +70,7 @@ class StoreController extends Controller
foreach ($data as $date => $rate) { foreach ($data as $date => $rate) {
$date = Carbon::createFromFormat('Y-m-d', $date); $date = Carbon::createFromFormat('Y-m-d', $date);
$existing = $this->repository->getSpecificRateOnDate($from, $to, $date); $existing = $this->repository->getSpecificRateOnDate($from, $to, $date);
if (null !== $existing) { if ($existing instanceof CurrencyExchangeRate) {
// update existing rate. // update existing rate.
$existing = $this->repository->updateExchangeRate($existing, $rate); $existing = $this->repository->updateExchangeRate($existing, $rate);
$collection->push($existing); $collection->push($existing);
@@ -98,12 +99,9 @@ class StoreController extends Controller
$from = $request->getFromCurrency(); $from = $request->getFromCurrency();
$collection = new Collection(); $collection = new Collection();
foreach ($data['rates'] as $key => $rate) { foreach ($data['rates'] as $key => $rate) {
$to = TransactionCurrency::where('code', $key)->first(); $to = Amount::getTransactionCurrencyByCode($key);
if (null === $to) {
continue; // should not happen.
}
$existing = $this->repository->getSpecificRateOnDate($from, $to, $date); $existing = $this->repository->getSpecificRateOnDate($from, $to, $date);
if (null !== $existing) { if ($existing instanceof CurrencyExchangeRate) {
// update existing rate. // update existing rate.
$existing = $this->repository->updateExchangeRate($existing, $rate); $existing = $this->repository->updateExchangeRate($existing, $rate);
$collection->push($existing); $collection->push($existing);

View File

@@ -30,9 +30,7 @@ use FireflyIII\Helpers\Collector\GroupCollectorInterface;
use FireflyIII\Models\Account; use FireflyIII\Models\Account;
use FireflyIII\Models\Bill; use FireflyIII\Models\Bill;
use FireflyIII\Models\Recurrence; use FireflyIII\Models\Recurrence;
use FireflyIII\Models\RecurrenceTransaction;
use FireflyIII\Models\Rule; use FireflyIII\Models\Rule;
use FireflyIII\Models\RuleTrigger;
use FireflyIII\Models\TransactionCurrency; use FireflyIII\Models\TransactionCurrency;
use FireflyIII\Repositories\Account\AccountRepositoryInterface; use FireflyIII\Repositories\Account\AccountRepositoryInterface;
use FireflyIII\Repositories\Bill\BillRepositoryInterface; use FireflyIII\Repositories\Bill\BillRepositoryInterface;
@@ -192,7 +190,7 @@ class ListController extends Controller
$enrichment->setUser($admin); $enrichment->setUser($admin);
$enrichment->setStart($this->parameters->get('start')); $enrichment->setStart($this->parameters->get('start'));
$enrichment->setEnd($this->parameters->get('end')); $enrichment->setEnd($this->parameters->get('end'));
$bills = $enrichment->enrichSingle($bills); $bills = $enrichment->enrich($bills);
// make paginator: // make paginator:
$paginator = new LengthAwarePaginator($bills, $count, $pageSize, $this->parameters->get('page')); $paginator = new LengthAwarePaginator($bills, $count, $pageSize, $this->parameters->get('page'));
@@ -268,7 +266,6 @@ class ListController extends Controller
// filter selection // filter selection
$collection = $unfiltered->filter( $collection = $unfiltered->filter(
static function (Recurrence $recurrence) use ($currency) { // @phpstan-ignore-line static function (Recurrence $recurrence) use ($currency) { // @phpstan-ignore-line
/** @var RecurrenceTransaction $transaction */
if (array_any($recurrence->recurrenceTransactions, fn ($transaction) => $transaction->transaction_currency_id === $currency->id || $transaction->foreign_currency_id === $currency->id)) { if (array_any($recurrence->recurrenceTransactions, fn ($transaction) => $transaction->transaction_currency_id === $currency->id || $transaction->foreign_currency_id === $currency->id)) {
return $recurrence; return $recurrence;
} }
@@ -320,7 +317,6 @@ class ListController extends Controller
$collection = $unfiltered->filter( $collection = $unfiltered->filter(
static function (Rule $rule) use ($currency) { // @phpstan-ignore-line static function (Rule $rule) use ($currency) { // @phpstan-ignore-line
/** @var RuleTrigger $trigger */
if (array_any($rule->ruleTriggers, fn ($trigger) => 'currency_is' === $trigger->trigger_type && $currency->name === $trigger->trigger_value)) { if (array_any($rule->ruleTriggers, fn ($trigger) => 'currency_is' === $trigger->trigger_type && $currency->name === $trigger->trigger_value)) {
return $rule; return $rule;
} }

View File

@@ -481,7 +481,7 @@ class BasicController extends Controller
$currencies = []; $currencies = [];
// first, create an entry for each entry in the "available" array. // first, create an entry for each entry in the "available" array.
/** @var array $availableBudget */ /** @var string $availableBudget */
foreach ($available as $currencyId => $availableBudget) { foreach ($available as $currencyId => $availableBudget) {
$currencies[$currencyId] ??= $this->currencyRepos->find($currencyId); $currencies[$currencyId] ??= $this->currencyRepos->find($currencyId);
$return[$currencyId] = [ $return[$currencyId] = [

View File

@@ -156,13 +156,11 @@ class ConfigurationController extends Controller
} }
// fallback // fallback
if (!str_starts_with($configKey, 'configuration.')) { $data = [
$data = [ 'title' => $configKey,
'title' => $configKey, 'value' => config($shortKey),
'value' => config($configKey), 'editable' => false,
'editable' => false, ];
];
}
return response()->api(['data' => $data])->header('Content-Type', self::JSON_CONTENT_TYPE); return response()->api(['data' => $data])->header('Content-Type', self::JSON_CONTENT_TYPE);
} }

View File

@@ -77,6 +77,8 @@ class UpdateController extends Controller
$admin = auth()->user(); $admin = auth()->user();
$enrichment = new WebhookEnrichment(); $enrichment = new WebhookEnrichment();
$enrichment->setUser($admin); $enrichment->setUser($admin);
/** @var Webhook $webhook */
$webhook = $enrichment->enrichSingle($webhook); $webhook = $enrichment->enrichSingle($webhook);
Log::channel('audit')->info(sprintf('User updates webhook #%d', $webhook->id), $data); Log::channel('audit')->info(sprintf('User updates webhook #%d', $webhook->id), $data);

View File

@@ -24,7 +24,7 @@ declare(strict_types=1);
namespace FireflyIII\Api\V1\Requests\Chart; namespace FireflyIII\Api\V1\Requests\Chart;
use Illuminate\Contracts\Validation\Validator; use Illuminate\Validation\Validator;
use FireflyIII\Enums\UserRoleEnum; use FireflyIII\Enums\UserRoleEnum;
use FireflyIII\Support\Http\Api\ValidatesUserGroupTrait; use FireflyIII\Support\Http\Api\ValidatesUserGroupTrait;
use FireflyIII\Support\Request\ChecksLogin; use FireflyIII\Support\Request\ChecksLogin;

View File

@@ -24,7 +24,7 @@ declare(strict_types=1);
namespace FireflyIII\Api\V1\Requests\Data\Bulk; namespace FireflyIII\Api\V1\Requests\Data\Bulk;
use Illuminate\Contracts\Validation\Validator; use Illuminate\Validation\Validator;
use FireflyIII\Repositories\Account\AccountRepositoryInterface; use FireflyIII\Repositories\Account\AccountRepositoryInterface;
use FireflyIII\Support\Request\ChecksLogin; use FireflyIII\Support\Request\ChecksLogin;
use FireflyIII\Support\Request\ConvertsDataTypes; use FireflyIII\Support\Request\ConvertsDataTypes;

View File

@@ -24,7 +24,7 @@ declare(strict_types=1);
namespace FireflyIII\Api\V1\Requests\Data\Bulk; namespace FireflyIII\Api\V1\Requests\Data\Bulk;
use Illuminate\Contracts\Validation\Validator; use Illuminate\Validation\Validator;
use JsonException; use JsonException;
use FireflyIII\Enums\ClauseType; use FireflyIII\Enums\ClauseType;
use FireflyIII\Rules\IsValidBulkClause; use FireflyIII\Rules\IsValidBulkClause;

View File

@@ -23,13 +23,14 @@ declare(strict_types=1);
namespace FireflyIII\Api\V1\Requests\Models\Account; namespace FireflyIII\Api\V1\Requests\Models\Account;
use Illuminate\Validation\Validator;
use Carbon\Carbon; use Carbon\Carbon;
use FireflyIII\Models\Preference; use FireflyIII\Models\Account;
use FireflyIII\Rules\IsValidSortInstruction;
use FireflyIII\Support\Facades\Preferences; use FireflyIII\Support\Facades\Preferences;
use FireflyIII\Support\Http\Api\AccountFilter; use FireflyIII\Support\Http\Api\AccountFilter;
use FireflyIII\Support\Request\ConvertsDataTypes; use FireflyIII\Support\Request\ConvertsDataTypes;
use FireflyIII\User; use FireflyIII\User;
use Illuminate\Contracts\Validation\Validator;
use Illuminate\Foundation\Http\FormRequest; use Illuminate\Foundation\Http\FormRequest;
class ShowRequest extends FormRequest class ShowRequest extends FormRequest
@@ -44,8 +45,6 @@ class ShowRequest extends FormRequest
// get default for user: // get default for user:
/** @var User $user */ /** @var User $user */
$user = auth()->user(); $user = auth()->user();
/** @var Preference $pageSize */
$limit = (int)Preferences::getForUser($user, 'listPageSize', 50)->data; $limit = (int)Preferences::getForUser($user, 'listPageSize', 50)->data;
} }
@@ -55,7 +54,7 @@ class ShowRequest extends FormRequest
return [ return [
'type' => $this->convertString('type', 'all'), 'type' => $this->convertString('type', 'all'),
'limit' => $limit, 'limit' => $limit,
'sort' => $this->convertString('sort', 'order'), 'sort' => $this->convertSortParameters('sort', Account::class),
'page' => $page, 'page' => $page,
]; ];
} }
@@ -68,10 +67,10 @@ class ShowRequest extends FormRequest
'date' => 'date', 'date' => 'date',
'start' => 'date|present_with:end|before_or_equal:end|before:2038-01-17|after:1970-01-02', 'start' => 'date|present_with:end|before_or_equal:end|before:2038-01-17|after:1970-01-02',
'end' => 'date|present_with:start|after_or_equal:start|before:2038-01-17|after:1970-01-02', 'end' => 'date|present_with:start|after_or_equal:start|before:2038-01-17|after:1970-01-02',
'sort' => 'in:active,iban,name,order,-active,-iban,-name,-order', // TODO improve me. 'sort' => ['nullable', new IsValidSortInstruction(Account::class)],
'type' => sprintf('in:%s', $keys), 'type' => sprintf('in:%s', $keys),
'limit' => 'number|min:1|max:131337', 'limit' => 'numeric|min:1|max:131337',
'page' => 'number|min:1|max:131337', 'page' => 'numeric|min:1|max:131337',
]; ];
} }
@@ -79,10 +78,12 @@ class ShowRequest extends FormRequest
{ {
$validator->after( $validator->after(
function (Validator $validator): void { function (Validator $validator): void {
if ($validator->failed()) { if (count($validator->failed()) > 0) {
return; return;
} }
$data = $validator->getData(); $data = $validator->getData();
if (array_key_exists('date', $data) && array_key_exists('start', $data) && array_key_exists('end', $data)) { if (array_key_exists('date', $data) && array_key_exists('start', $data) && array_key_exists('end', $data)) {
// assume valid dates, before we got here. // assume valid dates, before we got here.
$start = Carbon::parse($data['start'], config('app.timezone'))->startOfDay(); $start = Carbon::parse($data['start'], config('app.timezone'))->startOfDay();

View File

@@ -24,7 +24,7 @@ declare(strict_types=1);
namespace FireflyIII\Api\V1\Requests\Models\Account; namespace FireflyIII\Api\V1\Requests\Models\Account;
use Illuminate\Contracts\Validation\Validator; use Illuminate\Validation\Validator;
use FireflyIII\Models\Account; use FireflyIII\Models\Account;
use FireflyIII\Models\Location; use FireflyIII\Models\Location;
use FireflyIII\Repositories\Account\AccountRepositoryInterface; use FireflyIII\Repositories\Account\AccountRepositoryInterface;

View File

@@ -24,7 +24,7 @@ declare(strict_types=1);
namespace FireflyIII\Api\V1\Requests\Models\AvailableBudget; namespace FireflyIII\Api\V1\Requests\Models\AvailableBudget;
use Illuminate\Contracts\Validation\Validator; use Illuminate\Validation\Validator;
use Carbon\Carbon; use Carbon\Carbon;
use FireflyIII\Rules\IsValidPositiveAmount; use FireflyIII\Rules\IsValidPositiveAmount;
use FireflyIII\Support\Request\ChecksLogin; use FireflyIII\Support\Request\ChecksLogin;

View File

@@ -24,7 +24,7 @@ declare(strict_types=1);
namespace FireflyIII\Api\V1\Requests\Models\Bill; namespace FireflyIII\Api\V1\Requests\Models\Bill;
use Illuminate\Contracts\Validation\Validator; use Illuminate\Validation\Validator;
use ValueError; use ValueError;
use TypeError; use TypeError;
use FireflyIII\Rules\IsBoolean; use FireflyIII\Rules\IsBoolean;

View File

@@ -24,7 +24,7 @@ declare(strict_types=1);
namespace FireflyIII\Api\V1\Requests\Models\Bill; namespace FireflyIII\Api\V1\Requests\Models\Bill;
use Illuminate\Contracts\Validation\Validator; use Illuminate\Validation\Validator;
use FireflyIII\Models\Bill; use FireflyIII\Models\Bill;
use FireflyIII\Rules\IsBoolean; use FireflyIII\Rules\IsBoolean;
use FireflyIII\Rules\IsValidPositiveAmount; use FireflyIII\Rules\IsValidPositiveAmount;

View File

@@ -24,7 +24,7 @@ declare(strict_types=1);
namespace FireflyIII\Api\V1\Requests\Models\Budget; namespace FireflyIII\Api\V1\Requests\Models\Budget;
use Illuminate\Contracts\Validation\Validator; use Illuminate\Validation\Validator;
use FireflyIII\Rules\IsBoolean; use FireflyIII\Rules\IsBoolean;
use FireflyIII\Rules\IsValidPositiveAmount; use FireflyIII\Rules\IsValidPositiveAmount;
use FireflyIII\Support\Request\ChecksLogin; use FireflyIII\Support\Request\ChecksLogin;

View File

@@ -24,7 +24,7 @@ declare(strict_types=1);
namespace FireflyIII\Api\V1\Requests\Models\Budget; namespace FireflyIII\Api\V1\Requests\Models\Budget;
use Illuminate\Contracts\Validation\Validator; use Illuminate\Validation\Validator;
use FireflyIII\Models\Budget; use FireflyIII\Models\Budget;
use FireflyIII\Rules\IsBoolean; use FireflyIII\Rules\IsBoolean;
use FireflyIII\Rules\IsValidPositiveAmount; use FireflyIII\Rules\IsValidPositiveAmount;

View File

@@ -24,7 +24,7 @@ declare(strict_types=1);
namespace FireflyIII\Api\V1\Requests\Models\BudgetLimit; namespace FireflyIII\Api\V1\Requests\Models\BudgetLimit;
use Illuminate\Contracts\Validation\Validator; use Illuminate\Validation\Validator;
use Carbon\Carbon; use Carbon\Carbon;
use FireflyIII\Rules\IsValidPositiveAmount; use FireflyIII\Rules\IsValidPositiveAmount;
use FireflyIII\Support\Request\ChecksLogin; use FireflyIII\Support\Request\ChecksLogin;

View File

@@ -28,7 +28,7 @@ use Carbon\Carbon;
use Carbon\Exceptions\InvalidFormatException; use Carbon\Exceptions\InvalidFormatException;
use FireflyIII\Support\Request\ChecksLogin; use FireflyIII\Support\Request\ChecksLogin;
use FireflyIII\Support\Request\ConvertsDataTypes; use FireflyIII\Support\Request\ConvertsDataTypes;
use Illuminate\Contracts\Validation\Validator; use Illuminate\Validation\Validator;
use Illuminate\Foundation\Http\FormRequest; use Illuminate\Foundation\Http\FormRequest;
class StoreByCurrenciesRequest extends FormRequest class StoreByCurrenciesRequest extends FormRequest
@@ -55,7 +55,7 @@ class StoreByCurrenciesRequest extends FormRequest
{ {
$validator->after( $validator->after(
static function (Validator $validator): void { static function (Validator $validator): void {
$data = $validator->getData() ?? []; $data = $validator->getData();
foreach ($data as $date => $rate) { foreach ($data as $date => $rate) {
try { try {
$date = Carbon::createFromFormat('Y-m-d', $date); $date = Carbon::createFromFormat('Y-m-d', $date);

View File

@@ -24,10 +24,12 @@ declare(strict_types=1);
namespace FireflyIII\Api\V1\Requests\Models\CurrencyExchangeRate; namespace FireflyIII\Api\V1\Requests\Models\CurrencyExchangeRate;
use Illuminate\Validation\Validator;
use FireflyIII\Exceptions\FireflyException;
use FireflyIII\Models\TransactionCurrency; use FireflyIII\Models\TransactionCurrency;
use FireflyIII\Support\Facades\Amount;
use FireflyIII\Support\Request\ChecksLogin; use FireflyIII\Support\Request\ChecksLogin;
use FireflyIII\Support\Request\ConvertsDataTypes; use FireflyIII\Support\Request\ConvertsDataTypes;
use Illuminate\Contracts\Validation\Validator;
use Illuminate\Foundation\Http\FormRequest; use Illuminate\Foundation\Http\FormRequest;
class StoreByDateRequest extends FormRequest class StoreByDateRequest extends FormRequest
@@ -35,6 +37,9 @@ class StoreByDateRequest extends FormRequest
use ChecksLogin; use ChecksLogin;
use ConvertsDataTypes; use ConvertsDataTypes;
/**
* @return array<string, mixed>
*/
public function getAll(): array public function getAll(): array
{ {
return [ return [
@@ -45,11 +50,13 @@ class StoreByDateRequest extends FormRequest
public function getFromCurrency(): TransactionCurrency public function getFromCurrency(): TransactionCurrency
{ {
return TransactionCurrency::where('code', $this->get('from'))->first(); return Amount::getTransactionCurrencyByCode((string)$this->get('from'));
} }
/** /**
* The rules that the incoming request must be matched against. * The rules that the incoming request must be matched against.
*
* @return array<string, string>
*/ */
public function rules(): array public function rules(): array
{ {
@@ -79,8 +86,10 @@ class StoreByDateRequest extends FormRequest
continue; continue;
} }
$to = TransactionCurrency::where('code', $key)->first();
if (null === $to) { try {
$to = Amount::getTransactionCurrencyByCode((string)$key);
} catch (FireflyException) {
$validator->errors()->add(sprintf('rates.%s', $key), trans('validation.invalid_currency_code', ['code' => $key])); $validator->errors()->add(sprintf('rates.%s', $key), trans('validation.invalid_currency_code', ['code' => $key]));
} }
} }

View File

@@ -26,6 +26,7 @@ namespace FireflyIII\Api\V1\Requests\Models\CurrencyExchangeRate;
use Carbon\Carbon; use Carbon\Carbon;
use FireflyIII\Models\TransactionCurrency; use FireflyIII\Models\TransactionCurrency;
use FireflyIII\Support\Facades\Amount;
use FireflyIII\Support\Request\ChecksLogin; use FireflyIII\Support\Request\ChecksLogin;
use FireflyIII\Support\Request\ConvertsDataTypes; use FireflyIII\Support\Request\ConvertsDataTypes;
use Illuminate\Foundation\Http\FormRequest; use Illuminate\Foundation\Http\FormRequest;
@@ -42,7 +43,7 @@ class StoreRequest extends FormRequest
public function getFromCurrency(): TransactionCurrency public function getFromCurrency(): TransactionCurrency
{ {
return TransactionCurrency::where('code', $this->get('from'))->first(); return Amount::getTransactionCurrencyByCode((string) $this->get('from'));
} }
public function getRate(): string public function getRate(): string
@@ -52,7 +53,7 @@ class StoreRequest extends FormRequest
public function getToCurrency(): TransactionCurrency public function getToCurrency(): TransactionCurrency
{ {
return TransactionCurrency::where('code', $this->get('to'))->first(); return Amount::getTransactionCurrencyByCode((string) $this->get('to'));
} }
/** /**

View File

@@ -24,7 +24,8 @@ declare(strict_types=1);
namespace FireflyIII\Api\V1\Requests\Models\PiggyBank; namespace FireflyIII\Api\V1\Requests\Models\PiggyBank;
use Illuminate\Contracts\Validation\Validator; use Illuminate\Validation\Validator;
use FireflyIII\Support\Facades\Amount;
use FireflyIII\Models\TransactionCurrency; use FireflyIII\Models\TransactionCurrency;
use FireflyIII\Repositories\Account\AccountRepositoryInterface; use FireflyIII\Repositories\Account\AccountRepositoryInterface;
use FireflyIII\Rules\IsValidZeroOrMoreAmount; use FireflyIII\Rules\IsValidZeroOrMoreAmount;
@@ -96,7 +97,7 @@ class StoreRequest extends FormRequest
// validate start before end only if both are there. // validate start before end only if both are there.
$data = $validator->getData(); $data = $validator->getData();
$currency = $this->getCurrencyFromData($validator, $data); $currency = $this->getCurrencyFromData($validator, $data);
if (null === $currency) { if (!$currency instanceof TransactionCurrency) {
return; return;
} }
$targetAmount = (string) ($data['target_amount'] ?? '0'); $targetAmount = (string) ($data['target_amount'] ?? '0');
@@ -135,16 +136,10 @@ class StoreRequest extends FormRequest
private function getCurrencyFromData(Validator $validator, array $data): ?TransactionCurrency private function getCurrencyFromData(Validator $validator, array $data): ?TransactionCurrency
{ {
if (array_key_exists('transaction_currency_code', $data) && '' !== (string) $data['transaction_currency_code']) { if (array_key_exists('transaction_currency_code', $data) && '' !== (string) $data['transaction_currency_code']) {
$currency = TransactionCurrency::whereCode($data['transaction_currency_code'])->first(); return Amount::getTransactionCurrencyByCode((string) $data['transaction_currency_code']);
if (null !== $currency) {
return $currency;
}
} }
if (array_key_exists('transaction_currency_id', $data) && '' !== (string) $data['transaction_currency_id']) { if (array_key_exists('transaction_currency_id', $data) && '' !== (string) $data['transaction_currency_id']) {
$currency = TransactionCurrency::find((int) $data['transaction_currency_id']); return Amount::getTransactionCurrencyById((int) $data['transaction_currency_id']);
if (null !== $currency) {
return $currency;
}
} }
$validator->errors()->add('transaction_currency_id', trans('validation.require_currency_id_code')); $validator->errors()->add('transaction_currency_id', trans('validation.require_currency_id_code'));

View File

@@ -24,7 +24,7 @@ declare(strict_types=1);
namespace FireflyIII\Api\V1\Requests\Models\Recurrence; namespace FireflyIII\Api\V1\Requests\Models\Recurrence;
use Illuminate\Contracts\Validation\Validator; use Illuminate\Validation\Validator;
use FireflyIII\Rules\BelongsUser; use FireflyIII\Rules\BelongsUser;
use FireflyIII\Rules\IsBoolean; use FireflyIII\Rules\IsBoolean;
use FireflyIII\Rules\IsValidPositiveAmount; use FireflyIII\Rules\IsValidPositiveAmount;

View File

@@ -24,7 +24,7 @@ declare(strict_types=1);
namespace FireflyIII\Api\V1\Requests\Models\Recurrence; namespace FireflyIII\Api\V1\Requests\Models\Recurrence;
use Illuminate\Contracts\Validation\Validator; use Illuminate\Validation\Validator;
use FireflyIII\Models\Recurrence; use FireflyIII\Models\Recurrence;
use FireflyIII\Rules\BelongsUser; use FireflyIII\Rules\BelongsUser;
use FireflyIII\Rules\IsBoolean; use FireflyIII\Rules\IsBoolean;

View File

@@ -24,7 +24,7 @@ declare(strict_types=1);
namespace FireflyIII\Api\V1\Requests\Models\Rule; namespace FireflyIII\Api\V1\Requests\Models\Rule;
use Illuminate\Contracts\Validation\Validator; use Illuminate\Validation\Validator;
use FireflyIII\Rules\IsBoolean; use FireflyIII\Rules\IsBoolean;
use FireflyIII\Rules\IsValidActionExpression; use FireflyIII\Rules\IsValidActionExpression;
use FireflyIII\Support\Request\ChecksLogin; use FireflyIII\Support\Request\ChecksLogin;

View File

@@ -24,7 +24,7 @@ declare(strict_types=1);
namespace FireflyIII\Api\V1\Requests\Models\Rule; namespace FireflyIII\Api\V1\Requests\Models\Rule;
use Illuminate\Contracts\Validation\Validator; use Illuminate\Validation\Validator;
use FireflyIII\Models\Rule; use FireflyIII\Models\Rule;
use FireflyIII\Rules\IsBoolean; use FireflyIII\Rules\IsBoolean;
use FireflyIII\Rules\IsValidActionExpression; use FireflyIII\Rules\IsValidActionExpression;

View File

@@ -24,7 +24,7 @@ declare(strict_types=1);
namespace FireflyIII\Api\V1\Requests\Models\Transaction; namespace FireflyIII\Api\V1\Requests\Models\Transaction;
use Illuminate\Contracts\Validation\Validator; use Illuminate\Validation\Validator;
use FireflyIII\Models\Location; use FireflyIII\Models\Location;
use FireflyIII\Rules\BelongsUser; use FireflyIII\Rules\BelongsUser;
use FireflyIII\Rules\IsBoolean; use FireflyIII\Rules\IsBoolean;

View File

@@ -24,7 +24,7 @@ declare(strict_types=1);
namespace FireflyIII\Api\V1\Requests\Models\Transaction; namespace FireflyIII\Api\V1\Requests\Models\Transaction;
use Illuminate\Contracts\Validation\Validator; use Illuminate\Validation\Validator;
use FireflyIII\Exceptions\FireflyException; use FireflyIII\Exceptions\FireflyException;
use FireflyIII\Models\TransactionGroup; use FireflyIII\Models\TransactionGroup;
use FireflyIII\Rules\BelongsUser; use FireflyIII\Rules\BelongsUser;

View File

@@ -24,7 +24,7 @@ declare(strict_types=1);
namespace FireflyIII\Api\V1\Requests\Models\TransactionLink; namespace FireflyIII\Api\V1\Requests\Models\TransactionLink;
use Illuminate\Contracts\Validation\Validator; use Illuminate\Validation\Validator;
use FireflyIII\Repositories\Journal\JournalRepositoryInterface; use FireflyIII\Repositories\Journal\JournalRepositoryInterface;
use FireflyIII\Repositories\LinkType\LinkTypeRepositoryInterface; use FireflyIII\Repositories\LinkType\LinkTypeRepositoryInterface;
use FireflyIII\Support\Request\ChecksLogin; use FireflyIII\Support\Request\ChecksLogin;

View File

@@ -24,7 +24,7 @@ declare(strict_types=1);
namespace FireflyIII\Api\V1\Requests\Models\TransactionLink; namespace FireflyIII\Api\V1\Requests\Models\TransactionLink;
use Illuminate\Contracts\Validation\Validator; use Illuminate\Validation\Validator;
use FireflyIII\Models\TransactionJournalLink; use FireflyIII\Models\TransactionJournalLink;
use FireflyIII\Repositories\Journal\JournalRepositoryInterface; use FireflyIII\Repositories\Journal\JournalRepositoryInterface;
use FireflyIII\Repositories\LinkType\LinkTypeRepositoryInterface; use FireflyIII\Repositories\LinkType\LinkTypeRepositoryInterface;

View File

@@ -24,7 +24,7 @@ declare(strict_types=1);
namespace FireflyIII\Api\V1\Requests\System; namespace FireflyIII\Api\V1\Requests\System;
use Illuminate\Contracts\Validation\Validator; use Illuminate\Validation\Validator;
use FireflyIII\Rules\IsBoolean; use FireflyIII\Rules\IsBoolean;
use FireflyIII\Support\Request\ChecksLogin; use FireflyIII\Support\Request\ChecksLogin;
use FireflyIII\Support\Request\ConvertsDataTypes; use FireflyIII\Support\Request\ConvertsDataTypes;

View File

@@ -45,9 +45,7 @@ class CorrectsGroupAccounts extends Command
public function handle(): int public function handle(): int
{ {
$groups = []; $groups = [];
$res = TransactionJournal::groupBy('transaction_group_id') $res = TransactionJournal::groupBy('transaction_group_id')->get(['transaction_group_id', DB::raw('COUNT(transaction_group_id) as the_count')]);
->get(['transaction_group_id', DB::raw('COUNT(transaction_group_id) as the_count')])// @phpstan-ignore-line
;
/** @var TransactionJournal $journal */ /** @var TransactionJournal $journal */
foreach ($res as $journal) { foreach ($res as $journal) {

View File

@@ -263,9 +263,9 @@ class CorrectsUnevenAmount extends Command
// Log::debug(sprintf('[c] %s', var_export($source->transaction_currency_id === $destination->foreign_currency_id,true))); // Log::debug(sprintf('[c] %s', var_export($source->transaction_currency_id === $destination->foreign_currency_id,true)));
// Log::debug(sprintf('[d] %s', var_export((int) $destination->transaction_currency_id ===(int) $source->foreign_currency_id, true))); // Log::debug(sprintf('[d] %s', var_export((int) $destination->transaction_currency_id ===(int) $source->foreign_currency_id, true)));
if (0 === bccomp((string) app('steam')->positive($source->amount), (string) app('steam')->positive($destination->foreign_amount)) if (0 === bccomp(Steam::positive($source->amount), Steam::positive($destination->foreign_amount))
&& $source->transaction_currency_id === $destination->foreign_currency_id && $source->transaction_currency_id === $destination->foreign_currency_id
&& 0 === bccomp((string) app('steam')->positive($destination->amount), (string) app('steam')->positive($source->foreign_amount)) && 0 === bccomp(Steam::positive($destination->amount), Steam::positive($source->foreign_amount))
&& (int) $destination->transaction_currency_id === (int) $source->foreign_currency_id && (int) $destination->transaction_currency_id === (int) $source->foreign_currency_id
) { ) {
return true; return true;
@@ -302,10 +302,10 @@ class CorrectsUnevenAmount extends Command
private function isBetweenAssetAndLiability(TransactionJournal $journal): bool private function isBetweenAssetAndLiability(TransactionJournal $journal): bool
{ {
/** @var Transaction $sourceTransaction */ /** @var null|Transaction $sourceTransaction */
$sourceTransaction = $journal->transactions()->where('amount', '<', 0)->first(); $sourceTransaction = $journal->transactions()->where('amount', '<', 0)->first();
/** @var Transaction $destinationTransaction */ /** @var null|Transaction $destinationTransaction */
$destinationTransaction = $journal->transactions()->where('amount', '>', 0)->first(); $destinationTransaction = $journal->transactions()->where('amount', '>', 0)->first();
if (null === $sourceTransaction || null === $destinationTransaction) { if (null === $sourceTransaction || null === $destinationTransaction) {
Log::warning('Either transaction is false, stop.'); Log::warning('Either transaction is false, stop.');

View File

@@ -55,10 +55,7 @@ class RemovesEmptyJournals extends Command
*/ */
private function deleteUnevenJournals(): void private function deleteUnevenJournals(): void
{ {
$set = Transaction::whereNull('deleted_at') $set = Transaction::whereNull('deleted_at')->groupBy('transactions.transaction_journal_id')->get([DB::raw('COUNT(transactions.transaction_journal_id) as the_count'), 'transaction_journal_id']);
->groupBy('transactions.transaction_journal_id')
->get([DB::raw('COUNT(transactions.transaction_journal_id) as the_count'), 'transaction_journal_id']) // @phpstan-ignore-line
;
$total = 0; $total = 0;
/** @var Transaction $row */ /** @var Transaction $row */

View File

@@ -32,18 +32,7 @@ class ValidatesEnvironmentVariables extends Command
{ {
use ShowsFriendlyMessages; use ShowsFriendlyMessages;
/**
* The console command description.
*
* @var null|string
*/
protected $description = 'Makes sure you use the correct variables.'; protected $description = 'Makes sure you use the correct variables.';
/**
* The name and signature of the console command.
*
* @var string
*/
protected $signature = 'integrity:validates-environment-variables'; protected $signature = 'integrity:validates-environment-variables';
/** /**

View File

@@ -50,7 +50,7 @@ class RecalculatesRunningBalance extends Command
/** /**
* Execute the console command. * Execute the console command.
*/ */
public function handle() public function handle(): int
{ {
if (true === config('firefly.feature_flags.running_balance_column')) { if (true === config('firefly.feature_flags.running_balance_column')) {
$this->friendlyInfo('Will recalculate account balances. This may take a LONG time. Please be patient.'); $this->friendlyInfo('Will recalculate account balances. This may take a LONG time. Please be patient.');
@@ -60,6 +60,8 @@ class RecalculatesRunningBalance extends Command
return 0; return 0;
} }
$this->friendlyWarning('This command has been disabled.'); $this->friendlyWarning('This command has been disabled.');
return 0;
} }
private function correctBalanceAmounts(bool $forced): void private function correctBalanceAmounts(bool $forced): void

View File

@@ -29,6 +29,9 @@ use FireflyIII\Console\Commands\ShowsFriendlyMessages;
use Illuminate\Console\Command; use Illuminate\Console\Command;
use Symfony\Component\Console\Command\Command as CommandAlias; use Symfony\Component\Console\Command\Command as CommandAlias;
use function Safe\file_put_contents;
use function Safe\json_encode;
class ResetsErrorMailLimit extends Command class ResetsErrorMailLimit extends Command
{ {
use ShowsFriendlyMessages; use ShowsFriendlyMessages;

View File

@@ -78,8 +78,8 @@ class ScansAttachments extends Command
} }
$tempFileName = tempnam(sys_get_temp_dir(), 'FireflyIII'); $tempFileName = tempnam(sys_get_temp_dir(), 'FireflyIII');
file_put_contents($tempFileName, $decryptedContent); file_put_contents($tempFileName, $decryptedContent);
$attachment->md5 = (string)md5_file($tempFileName); $attachment->md5 = md5_file($tempFileName);
$attachment->mime = (string)mime_content_type($tempFileName); $attachment->mime = mime_content_type($tempFileName);
$attachment->save(); $attachment->save();
$this->friendlyInfo(sprintf('Fixed attachment #%d', $attachment->id)); $this->friendlyInfo(sprintf('Fixed attachment #%d', $attachment->id));
} }

View File

@@ -66,7 +66,7 @@ class RemovesDatabaseDecryption extends Command
* @var string $table * @var string $table
* @var array $fields * @var array $fields
*/ */
foreach ($tables as $table => $fields) { foreach ($tables as $table => $fields) { // @phpstan-ignore-line
$this->decryptTable($table, $fields); $this->decryptTable($table, $fields);
} }

View File

@@ -25,9 +25,11 @@ declare(strict_types=1);
namespace FireflyIII\Console\Commands\Upgrade; namespace FireflyIII\Console\Commands\Upgrade;
use FireflyIII\Console\Commands\ShowsFriendlyMessages; use FireflyIII\Console\Commands\ShowsFriendlyMessages;
use FireflyIII\Exceptions\FireflyException;
use FireflyIII\Models\Preference; use FireflyIII\Models\Preference;
use FireflyIII\Models\TransactionCurrency; use FireflyIII\Models\TransactionCurrency;
use FireflyIII\Models\UserGroup; use FireflyIII\Models\UserGroup;
use FireflyIII\Support\Facades\Amount;
use FireflyIII\User; use FireflyIII\User;
use Illuminate\Console\Command; use Illuminate\Console\Command;
use Illuminate\Support\Collection; use Illuminate\Support\Collection;
@@ -65,7 +67,7 @@ class UpgradesCurrencyPreferences extends Command
{ {
$configVar = app('fireflyconfig')->get(self::CONFIG_NAME, false); $configVar = app('fireflyconfig')->get(self::CONFIG_NAME, false);
if (null !== $configVar) { if (null !== $configVar) {
return (bool) $configVar->data; return (bool)$configVar->data;
} }
return false; return false;
@@ -104,8 +106,8 @@ class UpgradesCurrencyPreferences extends Command
private function upgradeUserPreferences(User $user): void private function upgradeUserPreferences(User $user): void
{ {
$currencies = TransactionCurrency::get(); $currencies = TransactionCurrency::get();
$enabled = new Collection(); $enabled = new Collection();
/** @var TransactionCurrency $currency */ /** @var TransactionCurrency $currency */
foreach ($currencies as $currency) { foreach ($currencies as $currency) {
@@ -116,10 +118,11 @@ class UpgradesCurrencyPreferences extends Command
$user->currencies()->sync($enabled->pluck('id')->toArray()); $user->currencies()->sync($enabled->pluck('id')->toArray());
// set the default currency for the user and for the group: // set the default currency for the user and for the group:
$preference = $this->getPreference($user); $preference = $this->getPreference($user);
$primaryCurrency = TransactionCurrency::where('code', $preference)->first();
if (null === $primaryCurrency) { try {
// get EUR $primaryCurrency = Amount::getTransactionCurrencyByCode($preference);
} catch (FireflyException) {
$primaryCurrency = TransactionCurrency::where('code', 'EUR')->first(); $primaryCurrency = TransactionCurrency::where('code', 'EUR')->first();
} }
$user->currencies()->updateExistingPivot($primaryCurrency->id, ['user_default' => true]); $user->currencies()->updateExistingPivot($primaryCurrency->id, ['user_default' => true]);
@@ -135,7 +138,7 @@ class UpgradesCurrencyPreferences extends Command
} }
if (null !== $preference->data && !is_array($preference->data)) { if (null !== $preference->data && !is_array($preference->data)) {
return (string) $preference->data; return (string)$preference->data;
} }
return 'EUR'; return 'EUR';

View File

@@ -37,7 +37,7 @@ class ActuallyLoggedIn extends Event
public User $user; public User $user;
public function __construct(null|Authenticatable|User $user) public function __construct(Authenticatable|User|null $user)
{ {
if ($user instanceof User) { if ($user instanceof User) {
$this->user = $user; $this->user = $user;

View File

@@ -1,43 +0,0 @@
<?php
/*
* DestroyedTransactionLink.php
* Copyright (c) 2020 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\Events;
use FireflyIII\Models\TransactionJournalLink;
use Illuminate\Queue\SerializesModels;
/**
* Class DestroyedTransactionLink
*/
class DestroyedTransactionLink extends Event
{
use SerializesModels;
// @phpstan-ignore-line
/**
* DestroyedTransactionLink constructor.
*/
public function __construct(private TransactionJournalLink $link) {}
}

View File

@@ -35,7 +35,7 @@ class DisabledMFA extends Event
public User $user; public User $user;
public function __construct(null|Authenticatable|User $user) public function __construct(Authenticatable|User|null $user)
{ {
if ($user instanceof User) { if ($user instanceof User) {
$this->user = $user; $this->user = $user;

View File

@@ -35,7 +35,7 @@ class EnabledMFA extends Event
public User $user; public User $user;
public function __construct(null|Authenticatable|User $user) public function __construct(Authenticatable|User|null $user)
{ {
if ($user instanceof User) { if ($user instanceof User) {
$this->user = $user; $this->user = $user;

View File

@@ -35,7 +35,7 @@ class MFABackupFewLeft extends Event
public User $user; public User $user;
public function __construct(null|Authenticatable|User $user, public int $count) public function __construct(Authenticatable|User|null $user, public int $count)
{ {
if ($user instanceof User) { if ($user instanceof User) {
$this->user = $user; $this->user = $user;

View File

@@ -35,7 +35,7 @@ class MFABackupNoLeft extends Event
public User $user; public User $user;
public function __construct(null|Authenticatable|User $user) public function __construct(Authenticatable|User|null $user)
{ {
if ($user instanceof User) { if ($user instanceof User) {
$this->user = $user; $this->user = $user;

View File

@@ -35,7 +35,7 @@ class MFAManyFailedAttempts extends Event
public User $user; public User $user;
public function __construct(null|Authenticatable|User $user, public int $count) public function __construct(Authenticatable|User|null $user, public int $count)
{ {
if ($user instanceof User) { if ($user instanceof User) {
$this->user = $user; $this->user = $user;

View File

@@ -35,7 +35,7 @@ class MFANewBackupCodes extends Event
public User $user; public User $user;
public function __construct(null|Authenticatable|User $user) public function __construct(Authenticatable|User|null $user)
{ {
if ($user instanceof User) { if ($user instanceof User) {
$this->user = $user; $this->user = $user;

View File

@@ -35,7 +35,7 @@ class MFAUsedBackupCode extends Event
public User $user; public User $user;
public function __construct(null|Authenticatable|User $user) public function __construct(Authenticatable|User|null $user)
{ {
if ($user instanceof User) { if ($user instanceof User) {
$this->user = $user; $this->user = $user;

View File

@@ -35,7 +35,7 @@ class UserAttemptedLogin extends Event
public User $user; public User $user;
public function __construct(null|Authenticatable|User $user) public function __construct(Authenticatable|User|null $user)
{ {
if ($user instanceof User) { if ($user instanceof User) {
$this->user = $user; $this->user = $user;

View File

@@ -170,7 +170,7 @@ class GracefulNotFoundHandler extends ExceptionHandler
} }
/** @var null|Account $account */ /** @var null|Account $account */
$account = $user->accounts()->with(['accountType'])->withTrashed()->find($accountId); $account = $user->accounts()->withTrashed()->with(['accountType'])->find($accountId);
if (null === $account) { if (null === $account) {
app('log')->error(sprintf('Could not find account %d, so give big fat error.', $accountId)); app('log')->error(sprintf('Could not find account %d, so give big fat error.', $accountId));

View File

@@ -282,7 +282,7 @@ class PiggyBankFactory
// create event: // create event:
Log::debug('linkToAccountIds: Trigger change for positive amount [b].'); Log::debug('linkToAccountIds: Trigger change for positive amount [b].');
event(new ChangedAmount($piggyBank, $toBeLinked[$account->id]['current_amount'], null, null)); event(new ChangedAmount($piggyBank, $toBeLinked[$account->id]['current_amount'] ?? '0', null, null));
} }
if (!array_key_exists('current_amount', $info)) { if (!array_key_exists('current_amount', $info)) {
$toBeLinked[$account->id] ??= []; $toBeLinked[$account->id] ??= [];

View File

@@ -26,7 +26,9 @@ namespace FireflyIII\Factory;
use FireflyIII\Exceptions\FireflyException; use FireflyIII\Exceptions\FireflyException;
use FireflyIII\Models\TransactionCurrency; use FireflyIII\Models\TransactionCurrency;
use FireflyIII\Support\Facades\Amount;
use Illuminate\Database\QueryException; use Illuminate\Database\QueryException;
use Illuminate\Support\Facades\Log;
/** /**
* Class TransactionCurrencyFactory * Class TransactionCurrencyFactory
@@ -41,14 +43,14 @@ class TransactionCurrencyFactory
$data['code'] = e($data['code']); $data['code'] = e($data['code']);
$data['symbol'] = e($data['symbol']); $data['symbol'] = e($data['symbol']);
$data['name'] = e($data['name']); $data['name'] = e($data['name']);
$data['decimal_places'] = (int) $data['decimal_places']; $data['decimal_places'] = (int)$data['decimal_places'];
// if the code already exists (deleted) // if the code already exists (deleted)
// force delete it and then create the transaction: // force delete it and then create the transaction:
$count = TransactionCurrency::withTrashed()->whereCode($data['code'])->count(); $count = TransactionCurrency::withTrashed()->whereCode($data['code'])->count();
if (1 === $count) { if (1 === $count) {
$old = TransactionCurrency::withTrashed()->whereCode($data['code'])->first(); $old = TransactionCurrency::withTrashed()->whereCode($data['code'])->first();
$old->forceDelete(); $old->forceDelete();
app('log')->warning(sprintf('Force deleted old currency with ID #%d and code "%s".', $old->id, $data['code'])); Log::warning(sprintf('Force deleted old currency with ID #%d and code "%s".', $old->id, $data['code']));
} }
try { try {
@@ -64,8 +66,8 @@ class TransactionCurrencyFactory
); );
} catch (QueryException $e) { } catch (QueryException $e) {
$result = null; $result = null;
app('log')->error(sprintf('Could not create new currency: %s', $e->getMessage())); Log::error(sprintf('Could not create new currency: %s', $e->getMessage()));
app('log')->error($e->getTraceAsString()); Log::error($e->getTraceAsString());
throw new FireflyException('400004: Could not store new currency.', 0, $e); throw new FireflyException('400004: Could not store new currency.', 0, $e);
} }
@@ -76,32 +78,33 @@ class TransactionCurrencyFactory
public function find(?int $currencyId, ?string $currencyCode): ?TransactionCurrency public function find(?int $currencyId, ?string $currencyCode): ?TransactionCurrency
{ {
$currencyCode = e($currencyCode); $currencyCode = e($currencyCode);
$currencyId = (int) $currencyId; $currencyId = (int)$currencyId;
$currency = null;
if ('' === $currencyCode && 0 === $currencyId) { if ('' === $currencyCode && 0 === $currencyId) {
app('log')->debug('Cannot find anything on empty currency code and empty currency ID!'); Log::debug('Cannot find anything on empty currency code and empty currency ID!');
return null; return null;
} }
// first by ID: // first by ID:
if ($currencyId > 0) { if ($currencyId > 0) {
$currency = TransactionCurrency::find($currencyId); try {
if (null !== $currency) { $currency = Amount::getTransactionCurrencyById($currencyId);
return $currency; } catch (FireflyException) {
Log::warning(sprintf('Currency ID is #%d but found nothing!', $currencyId));
} }
app('log')->warning(sprintf('Currency ID is %d but found nothing!', $currencyId));
} }
// then by code: // then by code:
if ('' !== $currencyCode) { if ('' !== $currencyCode && null === $currency) {
$currency = TransactionCurrency::whereCode($currencyCode)->first(); try {
if (null !== $currency) { $currency = Amount::getTransactionCurrencyByCode($currencyCode);
return $currency; } catch (FireflyException) {
Log::warning(sprintf('Currency code is "%s" but found nothing!', $currencyCode));
} }
app('log')->warning(sprintf('Currency code is %d but found nothing!', $currencyCode));
} }
app('log')->warning('Found nothing for currency.'); Log::info(sprintf('Found currency #%d based on ID %d and code "%s".', $currency->id, $currencyId, $currencyCode));
return null; return $currency;
} }
} }

View File

@@ -184,6 +184,8 @@ class StandardMessageGenerator implements MessageGeneratorInterface
if ($model instanceof Budget) { if ($model instanceof Budget) {
$enrichment = new BudgetEnrichment(); $enrichment = new BudgetEnrichment();
$enrichment->setUser($model->user); $enrichment->setUser($model->user);
/** @var Budget $model */
$model = $enrichment->enrichSingle($model); $model = $enrichment->enrichSingle($model);
$transformer = new BudgetTransformer(); $transformer = new BudgetTransformer();
$basicMessage['content'] = $transformer->transform($model); $basicMessage['content'] = $transformer->transform($model);
@@ -197,6 +199,7 @@ class StandardMessageGenerator implements MessageGeneratorInterface
$parameters->set('start', $model->start_date); $parameters->set('start', $model->start_date);
$parameters->set('end', $model->end_date); $parameters->set('end', $model->end_date);
/** @var BudgetLimit $model */
$model = $enrichment->enrichSingle($model); $model = $enrichment->enrichSingle($model);
$transformer = new BudgetLimitTransformer(); $transformer = new BudgetLimitTransformer();
$transformer->setParameters($parameters); $transformer->setParameters($parameters);
@@ -295,7 +298,7 @@ class StandardMessageGenerator implements MessageGeneratorInterface
$this->webhooks = $webhooks; $this->webhooks = $webhooks;
} }
private function getRelevantResponse(array $triggers, WebhookResponseModel $response, $class): string private function getRelevantResponse(array $triggers, WebhookResponseModel $response, string $class): string
{ {
// return none if none. // return none if none.
if (WebhookResponse::NONE->name === $response->title) { if (WebhookResponse::NONE->name === $response->title) {

View File

@@ -32,7 +32,6 @@ use FireflyIII\Notifications\Admin\UserInvitation;
use FireflyIII\Notifications\Admin\VersionCheckResult; use FireflyIII\Notifications\Admin\VersionCheckResult;
use FireflyIII\Notifications\Notifiables\OwnerNotifiable; use FireflyIII\Notifications\Notifiables\OwnerNotifiable;
use FireflyIII\Notifications\Test\OwnerTestNotificationEmail; use FireflyIII\Notifications\Test\OwnerTestNotificationEmail;
use FireflyIII\Notifications\Test\OwnerTestNotificationNtfy;
use FireflyIII\Notifications\Test\OwnerTestNotificationPushover; use FireflyIII\Notifications\Test\OwnerTestNotificationPushover;
use FireflyIII\Notifications\Test\OwnerTestNotificationSlack; use FireflyIII\Notifications\Test\OwnerTestNotificationSlack;
use Illuminate\Support\Facades\Log; use Illuminate\Support\Facades\Log;
@@ -140,10 +139,10 @@ class AdminEventHandler
break; break;
case 'ntfy': // case 'ntfy':
$class = OwnerTestNotificationNtfy::class; // $class = OwnerTestNotificationNtfy::class;
//
break; // break;
case 'pushover': case 'pushover':
$class = OwnerTestNotificationPushover::class; $class = OwnerTestNotificationPushover::class;

View File

@@ -34,6 +34,8 @@ use FireflyIII\Support\Facades\Preferences;
use Illuminate\Support\Facades\Log; use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Notification; use Illuminate\Support\Facades\Notification;
use function Safe\json_encode;
/** /**
* Class BillEventHandler * Class BillEventHandler
*/ */

View File

@@ -44,7 +44,6 @@ use FireflyIII\Models\UserRole;
use FireflyIII\Notifications\Admin\UserRegistration as AdminRegistrationNotification; use FireflyIII\Notifications\Admin\UserRegistration as AdminRegistrationNotification;
use FireflyIII\Notifications\Security\UserFailedLoginAttempt; use FireflyIII\Notifications\Security\UserFailedLoginAttempt;
use FireflyIII\Notifications\Test\UserTestNotificationEmail; use FireflyIII\Notifications\Test\UserTestNotificationEmail;
use FireflyIII\Notifications\Test\UserTestNotificationNtfy;
use FireflyIII\Notifications\Test\UserTestNotificationPushover; use FireflyIII\Notifications\Test\UserTestNotificationPushover;
use FireflyIII\Notifications\Test\UserTestNotificationSlack; use FireflyIII\Notifications\Test\UserTestNotificationSlack;
use FireflyIII\Notifications\User\UserLogin; use FireflyIII\Notifications\User\UserLogin;
@@ -129,7 +128,7 @@ class UserEventHandler
$groupTitle = $user->email; $groupTitle = $user->email;
$index = 1; $index = 1;
/** @var UserGroup $group */ /** @var null|UserGroup $group */
$group = null; $group = null;
// create a new group. // create a new group.
@@ -411,10 +410,10 @@ class UserEventHandler
break; break;
case 'ntfy': // case 'ntfy':
$class = UserTestNotificationNtfy::class; // $class = UserTestNotificationNtfy::class;
//
break; // break;
case 'pushover': case 'pushover':
$class = UserTestNotificationPushover::class; $class = UserTestNotificationPushover::class;

View File

@@ -35,6 +35,8 @@ use Illuminate\Support\Facades\Crypt;
use Illuminate\Support\Facades\Log; use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Storage; use Illuminate\Support\Facades\Storage;
use Illuminate\Support\MessageBag; use Illuminate\Support\MessageBag;
use Safe\Exceptions\FileinfoException;
use Safe\Exceptions\FilesystemException;
use Symfony\Component\HttpFoundation\File\UploadedFile; use Symfony\Component\HttpFoundation\File\UploadedFile;
use function Safe\tmpfile; use function Safe\tmpfile;
@@ -126,9 +128,11 @@ class AttachmentHelper implements AttachmentHelperInterface
public function saveAttachmentFromApi(Attachment $attachment, string $content): bool public function saveAttachmentFromApi(Attachment $attachment, string $content): bool
{ {
Log::debug(sprintf('Now in %s', __METHOD__)); Log::debug(sprintf('Now in %s', __METHOD__));
$resource = tmpfile();
if (false === $resource) { try {
Log::error('Cannot create temp-file for file upload.'); $resource = tmpfile();
} catch (FilesystemException $e) {
Log::error(sprintf('Cannot create temp-file for file upload: %s', $e->getMessage()));
return false; return false;
} }
@@ -141,17 +145,20 @@ class AttachmentHelper implements AttachmentHelperInterface
$path = stream_get_meta_data($resource)['uri']; $path = stream_get_meta_data($resource)['uri'];
Log::debug(sprintf('Path is %s', $path)); Log::debug(sprintf('Path is %s', $path));
$result = fwrite($resource, $content);
if (false === $result) { try {
Log::error('Could not write temp file.'); $result = fwrite($resource, $content);
} catch (FilesystemException $e) {
Log::error(sprintf('Could not write to temp file: %s', $e->getMessage()));
return false; return false;
} }
Log::debug(sprintf('Wrote %d bytes to temp file.', $result)); Log::debug(sprintf('Wrote %d bytes to temp file.', $result));
$finfo = finfo_open(FILEINFO_MIME_TYPE);
if (false === $finfo) { try {
Log::error('Could not open finfo.'); $finfo = finfo_open(FILEINFO_MIME_TYPE);
fclose($resource); } catch (FileinfoException $e) {
Log::error(sprintf('Could not open finfo handler: %s', $e->getMessage()));
return false; return false;
} }
@@ -171,7 +178,7 @@ class AttachmentHelper implements AttachmentHelperInterface
$this->uploadDisk->put($file, $content); $this->uploadDisk->put($file, $content);
// update attachment. // update attachment.
$attachment->md5 = (string) md5_file($path); $attachment->md5 = md5_file($path);
$attachment->mime = $mime; $attachment->mime = $mime;
$attachment->size = strlen($content); $attachment->size = strlen($content);
$attachment->uploaded = true; $attachment->uploaded = true;
@@ -233,7 +240,7 @@ class AttachmentHelper implements AttachmentHelperInterface
$attachment = new Attachment(); // create Attachment object. $attachment = new Attachment(); // create Attachment object.
$attachment->user()->associate($user); $attachment->user()->associate($user);
$attachment->attachable()->associate($model); $attachment->attachable()->associate($model);
$attachment->md5 = (string) md5_file($file->getRealPath()); $attachment->md5 = md5_file($file->getRealPath());
$attachment->filename = $file->getClientOriginalName(); $attachment->filename = $file->getClientOriginalName();
$attachment->mime = $file->getMimeType(); $attachment->mime = $file->getMimeType();
$attachment->size = $file->getSize(); $attachment->size = $file->getSize();

View File

@@ -24,6 +24,7 @@ declare(strict_types=1);
namespace FireflyIII\Helpers\Collector\Extensions; namespace FireflyIII\Helpers\Collector\Extensions;
use FireflyIII\Enums\TransactionTypeEnum;
use FireflyIII\Helpers\Collector\GroupCollectorInterface; use FireflyIII\Helpers\Collector\GroupCollectorInterface;
use FireflyIII\Models\Bill; use FireflyIII\Models\Bill;
use FireflyIII\Models\Budget; use FireflyIII\Models\Budget;
@@ -199,7 +200,7 @@ trait MetaCollection
public function excludeInternalReference(string $internalReference): GroupCollectorInterface public function excludeInternalReference(string $internalReference): GroupCollectorInterface
{ {
$internalReference = (string) json_encode($internalReference); $internalReference = json_encode($internalReference);
$internalReference = str_replace('\\', '\\\\', trim($internalReference, '"')); $internalReference = str_replace('\\', '\\\\', trim($internalReference, '"'));
$this->joinMetaDataTables(); $this->joinMetaDataTables();
@@ -220,7 +221,7 @@ trait MetaCollection
public function externalIdContains(string $externalId): GroupCollectorInterface public function externalIdContains(string $externalId): GroupCollectorInterface
{ {
$externalId = (string) json_encode($externalId); $externalId = json_encode($externalId);
$externalId = str_replace('\\', '\\\\', trim($externalId, '"')); $externalId = str_replace('\\', '\\\\', trim($externalId, '"'));
$this->joinMetaDataTables(); $this->joinMetaDataTables();
@@ -232,7 +233,7 @@ trait MetaCollection
public function externalIdDoesNotContain(string $externalId): GroupCollectorInterface public function externalIdDoesNotContain(string $externalId): GroupCollectorInterface
{ {
$externalId = (string) json_encode($externalId); $externalId = json_encode($externalId);
$externalId = str_replace('\\', '\\\\', trim($externalId, '"')); $externalId = str_replace('\\', '\\\\', trim($externalId, '"'));
$this->joinMetaDataTables(); $this->joinMetaDataTables();
@@ -244,7 +245,7 @@ trait MetaCollection
public function externalIdDoesNotEnd(string $externalId): GroupCollectorInterface public function externalIdDoesNotEnd(string $externalId): GroupCollectorInterface
{ {
$externalId = (string) json_encode($externalId); $externalId = json_encode($externalId);
$externalId = str_replace('\\', '\\\\', trim($externalId, '"')); $externalId = str_replace('\\', '\\\\', trim($externalId, '"'));
$this->joinMetaDataTables(); $this->joinMetaDataTables();
@@ -256,7 +257,7 @@ trait MetaCollection
public function externalIdDoesNotStart(string $externalId): GroupCollectorInterface public function externalIdDoesNotStart(string $externalId): GroupCollectorInterface
{ {
$externalId = (string) json_encode($externalId); $externalId = json_encode($externalId);
$externalId = str_replace('\\', '\\\\', trim($externalId, '"')); $externalId = str_replace('\\', '\\\\', trim($externalId, '"'));
$this->joinMetaDataTables(); $this->joinMetaDataTables();
@@ -268,7 +269,7 @@ trait MetaCollection
public function externalIdEnds(string $externalId): GroupCollectorInterface public function externalIdEnds(string $externalId): GroupCollectorInterface
{ {
$externalId = (string) json_encode($externalId); $externalId = json_encode($externalId);
$externalId = str_replace('\\', '\\\\', trim($externalId, '"')); $externalId = str_replace('\\', '\\\\', trim($externalId, '"'));
$this->joinMetaDataTables(); $this->joinMetaDataTables();
@@ -280,7 +281,7 @@ trait MetaCollection
public function externalIdStarts(string $externalId): GroupCollectorInterface public function externalIdStarts(string $externalId): GroupCollectorInterface
{ {
$externalId = (string) json_encode($externalId); $externalId = json_encode($externalId);
$externalId = str_replace('\\', '\\\\', trim($externalId, '"')); $externalId = str_replace('\\', '\\\\', trim($externalId, '"'));
$this->joinMetaDataTables(); $this->joinMetaDataTables();
@@ -293,7 +294,7 @@ trait MetaCollection
public function externalUrlContains(string $url): GroupCollectorInterface public function externalUrlContains(string $url): GroupCollectorInterface
{ {
$this->joinMetaDataTables(); $this->joinMetaDataTables();
$url = (string) json_encode($url); $url = json_encode($url);
$url = str_replace('\\', '\\\\', trim($url, '"')); $url = str_replace('\\', '\\\\', trim($url, '"'));
$this->query->where('journal_meta.name', '=', 'external_url'); $this->query->where('journal_meta.name', '=', 'external_url');
$this->query->whereLike('journal_meta.data', sprintf('%%%s%%', $url)); $this->query->whereLike('journal_meta.data', sprintf('%%%s%%', $url));
@@ -304,7 +305,7 @@ trait MetaCollection
public function externalUrlDoesNotContain(string $url): GroupCollectorInterface public function externalUrlDoesNotContain(string $url): GroupCollectorInterface
{ {
$this->joinMetaDataTables(); $this->joinMetaDataTables();
$url = (string) json_encode($url); $url = json_encode($url);
$url = str_replace('\\', '\\\\', trim($url, '"')); $url = str_replace('\\', '\\\\', trim($url, '"'));
$this->query->where('journal_meta.name', '=', 'external_url'); $this->query->where('journal_meta.name', '=', 'external_url');
$this->query->whereNotLike('journal_meta.data', sprintf('%%%s%%', $url)); $this->query->whereNotLike('journal_meta.data', sprintf('%%%s%%', $url));
@@ -315,7 +316,7 @@ trait MetaCollection
public function externalUrlDoesNotEnd(string $url): GroupCollectorInterface public function externalUrlDoesNotEnd(string $url): GroupCollectorInterface
{ {
$this->joinMetaDataTables(); $this->joinMetaDataTables();
$url = (string) json_encode($url); $url = json_encode($url);
$url = str_replace('\\', '\\\\', ltrim($url, '"')); $url = str_replace('\\', '\\\\', ltrim($url, '"'));
$this->query->where('journal_meta.name', '=', 'external_url'); $this->query->where('journal_meta.name', '=', 'external_url');
$this->query->whereNotLike('journal_meta.data', sprintf('%%%s', $url)); $this->query->whereNotLike('journal_meta.data', sprintf('%%%s', $url));
@@ -326,7 +327,7 @@ trait MetaCollection
public function externalUrlDoesNotStart(string $url): GroupCollectorInterface public function externalUrlDoesNotStart(string $url): GroupCollectorInterface
{ {
$this->joinMetaDataTables(); $this->joinMetaDataTables();
$url = (string) json_encode($url); $url = json_encode($url);
$url = str_replace('\\', '\\\\', rtrim($url, '"')); $url = str_replace('\\', '\\\\', rtrim($url, '"'));
// var_dump($url); // var_dump($url);
@@ -339,7 +340,7 @@ trait MetaCollection
public function externalUrlEnds(string $url): GroupCollectorInterface public function externalUrlEnds(string $url): GroupCollectorInterface
{ {
$this->joinMetaDataTables(); $this->joinMetaDataTables();
$url = (string) json_encode($url); $url = json_encode($url);
$url = str_replace('\\', '\\\\', ltrim($url, '"')); $url = str_replace('\\', '\\\\', ltrim($url, '"'));
$this->query->where('journal_meta.name', '=', 'external_url'); $this->query->where('journal_meta.name', '=', 'external_url');
$this->query->whereLike('journal_meta.data', sprintf('%%%s', $url)); $this->query->whereLike('journal_meta.data', sprintf('%%%s', $url));
@@ -350,7 +351,7 @@ trait MetaCollection
public function externalUrlStarts(string $url): GroupCollectorInterface public function externalUrlStarts(string $url): GroupCollectorInterface
{ {
$this->joinMetaDataTables(); $this->joinMetaDataTables();
$url = (string) json_encode($url); $url = json_encode($url);
$url = str_replace('\\', '\\\\', rtrim($url, '"')); $url = str_replace('\\', '\\\\', rtrim($url, '"'));
// var_dump($url); // var_dump($url);
@@ -401,7 +402,7 @@ trait MetaCollection
public function internalReferenceContains(string $internalReference): GroupCollectorInterface public function internalReferenceContains(string $internalReference): GroupCollectorInterface
{ {
$internalReference = (string) json_encode($internalReference); $internalReference = json_encode($internalReference);
$internalReference = str_replace('\\', '\\\\', trim($internalReference, '"')); $internalReference = str_replace('\\', '\\\\', trim($internalReference, '"'));
// var_dump($internalReference); // var_dump($internalReference);
// exit; // exit;
@@ -416,7 +417,7 @@ trait MetaCollection
public function internalReferenceDoesNotContain(string $internalReference): GroupCollectorInterface public function internalReferenceDoesNotContain(string $internalReference): GroupCollectorInterface
{ {
$internalReference = (string) json_encode($internalReference); $internalReference = json_encode($internalReference);
$internalReference = str_replace('\\', '\\\\', trim($internalReference, '"')); $internalReference = str_replace('\\', '\\\\', trim($internalReference, '"'));
$this->joinMetaDataTables(); $this->joinMetaDataTables();
@@ -429,7 +430,7 @@ trait MetaCollection
public function internalReferenceDoesNotEnd(string $internalReference): GroupCollectorInterface public function internalReferenceDoesNotEnd(string $internalReference): GroupCollectorInterface
{ {
$internalReference = (string) json_encode($internalReference); $internalReference = json_encode($internalReference);
$internalReference = str_replace('\\', '\\\\', trim($internalReference, '"')); $internalReference = str_replace('\\', '\\\\', trim($internalReference, '"'));
$this->joinMetaDataTables(); $this->joinMetaDataTables();
@@ -442,7 +443,7 @@ trait MetaCollection
public function internalReferenceDoesNotStart(string $internalReference): GroupCollectorInterface public function internalReferenceDoesNotStart(string $internalReference): GroupCollectorInterface
{ {
$internalReference = (string) json_encode($internalReference); $internalReference = json_encode($internalReference);
$internalReference = str_replace('\\', '\\\\', trim($internalReference, '"')); $internalReference = str_replace('\\', '\\\\', trim($internalReference, '"'));
$this->joinMetaDataTables(); $this->joinMetaDataTables();
@@ -455,7 +456,7 @@ trait MetaCollection
public function internalReferenceEnds(string $internalReference): GroupCollectorInterface public function internalReferenceEnds(string $internalReference): GroupCollectorInterface
{ {
$internalReference = (string) json_encode($internalReference); $internalReference = json_encode($internalReference);
$internalReference = str_replace('\\', '\\\\', trim($internalReference, '"')); $internalReference = str_replace('\\', '\\\\', trim($internalReference, '"'));
$this->joinMetaDataTables(); $this->joinMetaDataTables();
@@ -468,7 +469,7 @@ trait MetaCollection
public function internalReferenceStarts(string $internalReference): GroupCollectorInterface public function internalReferenceStarts(string $internalReference): GroupCollectorInterface
{ {
$internalReference = (string) json_encode($internalReference); $internalReference = json_encode($internalReference);
$internalReference = str_replace('\\', '\\\\', trim($internalReference, '"')); $internalReference = str_replace('\\', '\\\\', trim($internalReference, '"'));
$this->joinMetaDataTables(); $this->joinMetaDataTables();
@@ -724,7 +725,7 @@ trait MetaCollection
public function setInternalReference(string $internalReference): GroupCollectorInterface public function setInternalReference(string $internalReference): GroupCollectorInterface
{ {
$internalReference = (string) json_encode($internalReference); $internalReference = json_encode($internalReference);
$internalReference = str_replace('\\', '\\\\', trim($internalReference, '"')); $internalReference = str_replace('\\', '\\\\', trim($internalReference, '"'));
$this->joinMetaDataTables(); $this->joinMetaDataTables();
@@ -919,6 +920,8 @@ trait MetaCollection
{ {
$this->withCategoryInformation(); $this->withCategoryInformation();
$this->query->whereNull('category_transaction_journal.category_id'); $this->query->whereNull('category_transaction_journal.category_id');
// better fix for #10507
$this->query->whereNotIn('transaction_types.type', [TransactionTypeEnum::OPENING_BALANCE->value]);
return $this; return $this;
} }

View File

@@ -26,6 +26,7 @@ namespace FireflyIII\Helpers\Collector;
use Carbon\Carbon; use Carbon\Carbon;
use Carbon\Exceptions\InvalidFormatException; use Carbon\Exceptions\InvalidFormatException;
use Closure;
use Exception; use Exception;
use FireflyIII\Enums\TransactionTypeEnum; use FireflyIII\Enums\TransactionTypeEnum;
use FireflyIII\Exceptions\FireflyException; use FireflyIII\Exceptions\FireflyException;
@@ -45,7 +46,6 @@ use Illuminate\Database\Query\JoinClause;
use Illuminate\Pagination\LengthAwarePaginator; use Illuminate\Pagination\LengthAwarePaginator;
use Illuminate\Support\Collection; use Illuminate\Support\Collection;
use Illuminate\Support\Facades\Log; use Illuminate\Support\Facades\Log;
use Closure;
use Override; use Override;
use function Safe\json_decode; use function Safe\json_decode;
@@ -303,7 +303,7 @@ class GroupCollector implements GroupCollectorInterface
foreach ($params as $param) { foreach ($params as $param) {
$replace = sprintf('"%s"', $param); $replace = sprintf('"%s"', $param);
if (is_int($param)) { if (is_int($param)) {
$replace = (string) $param; $replace = (string)$param;
} }
$pos = strpos($query, '?'); $pos = strpos($query, '?');
if (false !== $pos) { if (false !== $pos) {
@@ -518,13 +518,13 @@ class GroupCollector implements GroupCollectorInterface
/** @var TransactionJournal $augumentedJournal */ /** @var TransactionJournal $augumentedJournal */
foreach ($collection as $augumentedJournal) { foreach ($collection as $augumentedJournal) {
$groupId = (int) $augumentedJournal->transaction_group_id; $groupId = (int)$augumentedJournal->transaction_group_id;
if (!array_key_exists($groupId, $groups)) { if (!array_key_exists($groupId, $groups)) {
// make new array // make new array
$parsedGroup = $this->parseAugmentedJournal($augumentedJournal); $parsedGroup = $this->parseAugmentedJournal($augumentedJournal);
$groupArray = [ $groupArray = [
'id' => (int) $augumentedJournal->transaction_group_id, 'id' => (int)$augumentedJournal->transaction_group_id,
'user_id' => $augumentedJournal->user_id, 'user_id' => $augumentedJournal->user_id,
'user_group_id' => $augumentedJournal->user_group_id, 'user_group_id' => $augumentedJournal->user_group_id,
// Field transaction_group_title was added by the query. // Field transaction_group_title was added by the query.
@@ -537,7 +537,7 @@ class GroupCollector implements GroupCollectorInterface
'transactions' => [], 'transactions' => [],
]; ];
// Field transaction_journal_id was added by the query. // Field transaction_journal_id was added by the query.
$journalId = (int) $augumentedJournal->transaction_journal_id; $journalId = (int)$augumentedJournal->transaction_journal_id;
$groupArray['transactions'][$journalId] = $parsedGroup; $groupArray['transactions'][$journalId] = $parsedGroup;
$groups[$groupId] = $groupArray; $groups[$groupId] = $groupArray;
@@ -545,7 +545,7 @@ class GroupCollector implements GroupCollectorInterface
} }
// or parse the rest. // or parse the rest.
// Field transaction_journal_id was added by the query. // Field transaction_journal_id was added by the query.
$journalId = (int) $augumentedJournal->transaction_journal_id; $journalId = (int)$augumentedJournal->transaction_journal_id;
if (array_key_exists($journalId, $groups[$groupId]['transactions'])) { if (array_key_exists($journalId, $groups[$groupId]['transactions'])) {
// append data to existing group + journal (for multiple tags or multiple attachments) // append data to existing group + journal (for multiple tags or multiple attachments)
$groups[$groupId]['transactions'][$journalId] = $this->mergeTags($groups[$groupId]['transactions'][$journalId], $augumentedJournal); $groups[$groupId]['transactions'][$journalId] = $this->mergeTags($groups[$groupId]['transactions'][$journalId], $augumentedJournal);
@@ -597,8 +597,8 @@ class GroupCollector implements GroupCollectorInterface
$dates = ['interest_date', 'payment_date', 'invoice_date', 'book_date', 'due_date', 'process_date']; $dates = ['interest_date', 'payment_date', 'invoice_date', 'book_date', 'due_date', 'process_date'];
if (array_key_exists('meta_name', $result) && in_array($result['meta_name'], $dates, true)) { if (array_key_exists('meta_name', $result) && in_array($result['meta_name'], $dates, true)) {
$name = $result['meta_name']; $name = $result['meta_name'];
if (array_key_exists('meta_data', $result) && '' !== (string) $result['meta_data']) { if (array_key_exists('meta_data', $result) && '' !== (string)$result['meta_data']) {
$result[$name] = Carbon::createFromFormat('!Y-m-d', substr((string) json_decode((string) $result['meta_data']), 0, 10)); $result[$name] = Carbon::createFromFormat('!Y-m-d', substr((string)json_decode((string)$result['meta_data']), 0, 10));
} }
} }
@@ -611,9 +611,9 @@ class GroupCollector implements GroupCollectorInterface
// convert back to strings because SQLite is dumb like that. // convert back to strings because SQLite is dumb like that.
$result = $this->convertToStrings($result); $result = $this->convertToStrings($result);
$result['reconciled'] = 1 === (int) $result['reconciled']; $result['reconciled'] = 1 === (int)$result['reconciled'];
if (array_key_exists('tag_id', $result) && null !== $result['tag_id']) { // assume the other fields are present as well. if (array_key_exists('tag_id', $result) && null !== $result['tag_id']) { // assume the other fields are present as well.
$tagId = (int) $augumentedJournal['tag_id']; $tagId = (int)$augumentedJournal['tag_id'];
$tagDate = null; $tagDate = null;
try { try {
@@ -623,7 +623,7 @@ class GroupCollector implements GroupCollectorInterface
} }
$result['tags'][$tagId] = [ $result['tags'][$tagId] = [
'id' => (int) $result['tag_id'], 'id' => (int)$result['tag_id'],
'name' => $result['tag_name'], 'name' => $result['tag_name'],
'date' => $tagDate, 'date' => $tagDate,
'description' => $result['tag_description'], 'description' => $result['tag_description'],
@@ -632,8 +632,8 @@ class GroupCollector implements GroupCollectorInterface
// also merge attachments: // also merge attachments:
if (array_key_exists('attachment_id', $result)) { if (array_key_exists('attachment_id', $result)) {
$uploaded = 1 === (int) $result['attachment_uploaded']; $uploaded = 1 === (int)$result['attachment_uploaded'];
$attachmentId = (int) $augumentedJournal['attachment_id']; $attachmentId = (int)$augumentedJournal['attachment_id'];
if (0 !== $attachmentId && $uploaded) { if (0 !== $attachmentId && $uploaded) {
$result['attachments'][$attachmentId] = [ $result['attachments'][$attachmentId] = [
'id' => $attachmentId, 'id' => $attachmentId,
@@ -659,7 +659,7 @@ class GroupCollector implements GroupCollectorInterface
private function convertToInteger(array $array): array private function convertToInteger(array $array): array
{ {
foreach ($this->integerFields as $field) { foreach ($this->integerFields as $field) {
$array[$field] = array_key_exists($field, $array) ? (int) $array[$field] : null; $array[$field] = array_key_exists($field, $array) ? (int)$array[$field] : null;
} }
return $array; return $array;
@@ -668,7 +668,7 @@ class GroupCollector implements GroupCollectorInterface
private function convertToBoolean(array $array): array private function convertToBoolean(array $array): array
{ {
foreach ($this->booleanFields as $field) { foreach ($this->booleanFields as $field) {
$array[$field] = array_key_exists($field, $array) ? (bool) $array[$field] : null; $array[$field] = array_key_exists($field, $array) ? (bool)$array[$field] : null;
} }
return $array; return $array;
@@ -677,7 +677,7 @@ class GroupCollector implements GroupCollectorInterface
private function convertToStrings(array $array): array private function convertToStrings(array $array): array
{ {
foreach ($this->stringFields as $field) { foreach ($this->stringFields as $field) {
$array[$field] = array_key_exists($field, $array) && null !== $array[$field] ? (string) $array[$field] : null; $array[$field] = array_key_exists($field, $array) && null !== $array[$field] ? (string)$array[$field] : null;
} }
return $array; return $array;
@@ -687,7 +687,7 @@ class GroupCollector implements GroupCollectorInterface
{ {
$newArray = $newJournal->toArray(); $newArray = $newJournal->toArray();
if (array_key_exists('tag_id', $newArray)) { // assume the other fields are present as well. if (array_key_exists('tag_id', $newArray)) { // assume the other fields are present as well.
$tagId = (int) $newJournal['tag_id']; $tagId = (int)$newJournal['tag_id'];
$tagDate = null; $tagDate = null;
@@ -698,7 +698,7 @@ class GroupCollector implements GroupCollectorInterface
} }
$existingJournal['tags'][$tagId] = [ $existingJournal['tags'][$tagId] = [
'id' => (int) $newArray['tag_id'], 'id' => (int)$newArray['tag_id'],
'name' => $newArray['tag_name'], 'name' => $newArray['tag_name'],
'date' => $tagDate, 'date' => $tagDate,
'description' => $newArray['tag_description'], 'description' => $newArray['tag_description'],
@@ -712,7 +712,7 @@ class GroupCollector implements GroupCollectorInterface
{ {
$newArray = $newJournal->toArray(); $newArray = $newJournal->toArray();
if (array_key_exists('attachment_id', $newArray)) { if (array_key_exists('attachment_id', $newArray)) {
$attachmentId = (int) $newJournal['attachment_id']; $attachmentId = (int)$newJournal['attachment_id'];
$existingJournal['attachments'][$attachmentId] = [ $existingJournal['attachments'][$attachmentId] = [
'id' => $attachmentId, 'id' => $attachmentId,
@@ -731,13 +731,13 @@ class GroupCollector implements GroupCollectorInterface
foreach ($groups as $groudId => $group) { foreach ($groups as $groudId => $group) {
/** @var array $transaction */ /** @var array $transaction */
foreach ($group['transactions'] as $transaction) { foreach ($group['transactions'] as $transaction) {
$currencyId = (int) $transaction['currency_id']; $currencyId = (int)$transaction['currency_id'];
if (null === $transaction['amount']) { if (null === $transaction['amount']) {
throw new FireflyException(sprintf('Amount is NULL for a transaction in group #%d, please investigate.', $groudId)); throw new FireflyException(sprintf('Amount is NULL for a transaction in group #%d, please investigate.', $groudId));
} }
$pcAmount = (string) ('' === $transaction['pc_amount'] ? '0' : $transaction['pc_amount']); $pcAmount = (string)('' === $transaction['pc_amount'] ? '0' : $transaction['pc_amount']);
$pcForeignAmount = (string) ('' === $transaction['pc_foreign_amount'] ? '0' : $transaction['pc_foreign_amount']); $pcForeignAmount = (string)('' === $transaction['pc_foreign_amount'] ? '0' : $transaction['pc_foreign_amount']);
$foreignAmount = (string) ('' === $transaction['foreign_amount'] ? '0' : $transaction['foreign_amount']); $foreignAmount = (string)('' === $transaction['foreign_amount'] ? '0' : $transaction['foreign_amount']);
// set default: // set default:
if (!array_key_exists($currencyId, $groups[$groudId]['sums'])) { if (!array_key_exists($currencyId, $groups[$groudId]['sums'])) {
@@ -748,11 +748,11 @@ class GroupCollector implements GroupCollectorInterface
$groups[$groudId]['sums'][$currencyId]['amount'] = '0'; $groups[$groudId]['sums'][$currencyId]['amount'] = '0';
$groups[$groudId]['sums'][$currencyId]['pc_amount'] = '0'; $groups[$groudId]['sums'][$currencyId]['pc_amount'] = '0';
} }
$groups[$groudId]['sums'][$currencyId]['amount'] = bcadd((string) $groups[$groudId]['sums'][$currencyId]['amount'], $transaction['amount']); $groups[$groudId]['sums'][$currencyId]['amount'] = bcadd((string)$groups[$groudId]['sums'][$currencyId]['amount'], $transaction['amount']);
$groups[$groudId]['sums'][$currencyId]['pc_amount'] = bcadd((string) $groups[$groudId]['sums'][$currencyId]['pc_amount'], $pcAmount); $groups[$groudId]['sums'][$currencyId]['pc_amount'] = bcadd((string)$groups[$groudId]['sums'][$currencyId]['pc_amount'], $pcAmount);
if (null !== $transaction['foreign_amount'] && null !== $transaction['foreign_currency_id']) { if (null !== $transaction['foreign_amount'] && null !== $transaction['foreign_currency_id']) {
$currencyId = (int) $transaction['foreign_currency_id']; $currencyId = (int)$transaction['foreign_currency_id'];
// set default: // set default:
if (!array_key_exists($currencyId, $groups[$groudId]['sums'])) { if (!array_key_exists($currencyId, $groups[$groudId]['sums'])) {
@@ -763,7 +763,7 @@ class GroupCollector implements GroupCollectorInterface
$groups[$groudId]['sums'][$currencyId]['amount'] = '0'; $groups[$groudId]['sums'][$currencyId]['amount'] = '0';
$groups[$groudId]['sums'][$currencyId]['pc_amount'] = '0'; $groups[$groudId]['sums'][$currencyId]['pc_amount'] = '0';
} }
$groups[$groudId]['sums'][$currencyId]['amount'] = bcadd((string) $groups[$groudId]['sums'][$currencyId]['amount'], $foreignAmount); $groups[$groudId]['sums'][$currencyId]['amount'] = bcadd((string)$groups[$groudId]['sums'][$currencyId]['amount'], $foreignAmount);
$groups[$groudId]['sums'][$currencyId]['pc_amount'] = bcadd($groups[$groudId]['sums'][$currencyId]['amount'], $pcForeignAmount); $groups[$groudId]['sums'][$currencyId]['pc_amount'] = bcadd($groups[$groudId]['sums'][$currencyId]['amount'], $pcForeignAmount);
} }
} }
@@ -1095,10 +1095,6 @@ class GroupCollector implements GroupCollectorInterface
->whereNull('transaction_groups.deleted_at') ->whereNull('transaction_groups.deleted_at')
->whereNull('transaction_journals.deleted_at') ->whereNull('transaction_journals.deleted_at')
->whereNull('source.deleted_at') ->whereNull('source.deleted_at')
// #10507 ignore opening balance.
->where('transaction_types.type', '!=', TransactionTypeEnum::OPENING_BALANCE->value)
->whereNotNull('transaction_groups.id') ->whereNotNull('transaction_groups.id')
->whereNull('destination.deleted_at') ->whereNull('destination.deleted_at')
->orderBy('transaction_journals.date', 'DESC') ->orderBy('transaction_journals.date', 'DESC')

View File

@@ -51,7 +51,7 @@ class NetWorth implements NetWorthInterface
private AccountRepositoryInterface $accountRepository; private AccountRepositoryInterface $accountRepository;
private CurrencyRepositoryInterface $currencyRepos; private CurrencyRepositoryInterface $currencyRepos;
private User $user; // @phpstan-ignore-line private User $user; // @phpstan-ignore-line
private ?UserGroup $userGroup = null; // @phpstan-ignore-line private ?UserGroup $userGroup = null;
/** /**
* This method collects the user's net worth in ALL the user's currencies * This method collects the user's net worth in ALL the user's currencies
@@ -116,7 +116,7 @@ class NetWorth implements NetWorthInterface
return $netWorth; return $netWorth;
} }
public function setUser(null|Authenticatable|User $user): void public function setUser(Authenticatable|User|null $user): void
{ {
if (!$user instanceof User) { if (!$user instanceof User) {
return; return;

View File

@@ -46,7 +46,7 @@ interface NetWorthInterface
*/ */
public function byAccounts(Collection $accounts, Carbon $date): array; public function byAccounts(Collection $accounts, Carbon $date): array;
public function setUser(null|Authenticatable|User $user): void; public function setUser(Authenticatable|User|null $user): void;
public function setUserGroup(UserGroup $userGroup): void; public function setUserGroup(UserGroup $userGroup): void;

View File

@@ -70,6 +70,7 @@ class NotificationController extends Controller
} }
$forcedAvailability['ntfy'] = '' !== $ntfyTopic; $forcedAvailability['ntfy'] = '' !== $ntfyTopic;
$forcedAvailability['pushover'] = '' !== $pushoverAppToken && '' !== $pushoverUserToken; $forcedAvailability['pushover'] = '' !== $pushoverAppToken && '' !== $pushoverUserToken;
$forcedAvailability['slack'] = '' !== $slackUrl;
return view( return view(
'settings.notifications.index', 'settings.notifications.index',

View File

@@ -33,6 +33,7 @@ use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request; use Illuminate\Http\Request;
use Illuminate\Support\Facades\Log; use Illuminate\Support\Facades\Log;
use Illuminate\View\View; use Illuminate\View\View;
use Safe\Exceptions\UrlException;
use function Safe\parse_url; use function Safe\parse_url;
@@ -103,11 +104,15 @@ class ForgotPasswordController extends Controller
*/ */
private function validateHost(): void private function validateHost(): void
{ {
$configuredHost = parse_url((string) config('app.url'), PHP_URL_HOST); try {
if (false === $configuredHost || null === $configuredHost) { $configuredHost = parse_url((string)config('app.url'), PHP_URL_HOST);
} catch (UrlException $e) {
throw new FireflyException('Please set a valid and correct Firefly III URL in the APP_URL environment variable.', 0, $e);
}
if (!is_string($configuredHost)) {
throw new FireflyException('Please set a valid and correct Firefly III URL in the APP_URL environment variable.'); throw new FireflyException('Please set a valid and correct Firefly III URL in the APP_URL environment variable.');
} }
$host = request()->host(); $host = request()->host();
if ($configuredHost !== $host) { if ($configuredHost !== $host) {
Log::error(sprintf('Host header is "%s", APP_URL is "%s".', $host, $configuredHost)); Log::error(sprintf('Host header is "%s", APP_URL is "%s".', $host, $configuredHost));

View File

@@ -249,8 +249,8 @@ class LoginController extends Controller
$allowReset = false; $allowReset = false;
} }
$email = $request?->old('email'); $email = $request->old('email');
$remember = $request?->old('remember'); $remember = $request->old('remember');
$storeInCookie = config('google2fa.store_in_cookie', false); $storeInCookie = config('google2fa.store_in_cookie', false);
if (false !== $storeInCookie) { if (false !== $storeInCookie) {

View File

@@ -69,15 +69,14 @@ class CreateController extends Controller
*/ */
public function create(Request $request) public function create(Request $request)
{ {
$periods = []; $periods = [];
/** @var array $billPeriods */ /** @var array $billPeriods */
$billPeriods = config('firefly.bill_periods'); $billPeriods = config('firefly.bill_periods');
foreach ($billPeriods as $current) { foreach ($billPeriods as $current) {
$periods[$current] = (string) trans('firefly.repeat_freq_'.$current); $periods[$current] = (string) trans('firefly.repeat_freq_'.$current);
} }
$subTitle = (string) trans('firefly.create_new_bill'); $subTitle = (string) trans('firefly.create_new_bill');
$primaryCurrency = $this->primaryCurrency;
// put previous url in session if not redirect from store (not "create another"). // put previous url in session if not redirect from store (not "create another").
if (true !== session('bills.create.fromStore')) { if (true !== session('bills.create.fromStore')) {
@@ -85,7 +84,7 @@ class CreateController extends Controller
} }
$request->session()->forget('bills.create.fromStore'); $request->session()->forget('bills.create.fromStore');
return view('bills.create', compact('periods', 'subTitle', 'primaryCurrency')); return view('bills.create', compact('periods', 'subTitle'));
} }
/** /**

View File

@@ -88,7 +88,6 @@ class EditController extends Controller
$bill->amount_min = app('steam')->bcround($bill->amount_min, $bill->transactionCurrency->decimal_places); $bill->amount_min = app('steam')->bcround($bill->amount_min, $bill->transactionCurrency->decimal_places);
$bill->amount_max = app('steam')->bcround($bill->amount_max, $bill->transactionCurrency->decimal_places); $bill->amount_max = app('steam')->bcround($bill->amount_max, $bill->transactionCurrency->decimal_places);
$rules = $this->repository->getRulesForBill($bill); $rules = $this->repository->getRulesForBill($bill);
$primaryCurrency = $this->primaryCurrency;
// code to handle active-checkboxes // code to handle active-checkboxes
$hasOldInput = null !== $request->old('_token'); $hasOldInput = null !== $request->old('_token');
@@ -105,7 +104,7 @@ class EditController extends Controller
$request->session()->flash('preFilled', $preFilled); $request->session()->flash('preFilled', $preFilled);
$request->session()->forget('bills.edit.fromUpdate'); $request->session()->forget('bills.edit.fromUpdate');
return view('bills.edit', compact('subTitle', 'periods', 'rules', 'bill', 'primaryCurrency', 'preFilled')); return view('bills.edit', compact('subTitle', 'periods', 'rules', 'bill', 'preFilled'));
} }
/** /**

View File

@@ -135,7 +135,6 @@ class IndexController extends Controller
// get all inactive budgets, and simply list them: // get all inactive budgets, and simply list them:
$inactive = $this->repository->getInactiveBudgets(); $inactive = $this->repository->getInactiveBudgets();
$primaryCurrency = $this->primaryCurrency;
return view( return view(
'budgets.index', 'budgets.index',
@@ -148,7 +147,6 @@ class IndexController extends Controller
'budgets', 'budgets',
'currencies', 'currencies',
'periodTitle', 'periodTitle',
'primaryCurrency',
'activeDaysPassed', 'activeDaysPassed',
'activeDaysLeft', 'activeDaysLeft',
'inactive', 'inactive',

View File

@@ -330,6 +330,7 @@ class AccountController extends Controller
/** @var array $journal */ /** @var array $journal */
foreach ($journals as $journal) { foreach ($journals as $journal) {
$key = sprintf('%d-%d', $journal['category_id'], $journal['currency_id']); $key = sprintf('%d-%d', $journal['category_id'], $journal['currency_id']);
$field = 'amount';
if (!array_key_exists($key, $result)) { if (!array_key_exists($key, $result)) {
// currency info: // currency info:
@@ -338,7 +339,6 @@ class AccountController extends Controller
$currencySymbol = $journal['currency_symbol']; $currencySymbol = $journal['currency_symbol'];
$currencyCode = $journal['currency_code']; $currencyCode = $journal['currency_code'];
$currencyDecimalPlaces = $journal['currency_decimal_places']; $currencyDecimalPlaces = $journal['currency_decimal_places'];
$field = 'amount';
if ($this->convertToPrimary && $this->primaryCurrency->id !== $currencyId) { if ($this->convertToPrimary && $this->primaryCurrency->id !== $currencyId) {
$field = 'pc_amount'; $field = 'pc_amount';
$currencyName = $this->primaryCurrency->name; $currencyName = $this->primaryCurrency->name;
@@ -437,6 +437,7 @@ class AccountController extends Controller
/** @var array $journal */ /** @var array $journal */
foreach ($journals as $journal) { foreach ($journals as $journal) {
$key = sprintf('%d-%d', $journal['category_id'], $journal['currency_id']); $key = sprintf('%d-%d', $journal['category_id'], $journal['currency_id']);
$field = 'amount';
if (!array_key_exists($key, $result)) { if (!array_key_exists($key, $result)) {
// currency info: // currency info:
@@ -445,7 +446,6 @@ class AccountController extends Controller
$currencySymbol = $journal['currency_symbol']; $currencySymbol = $journal['currency_symbol'];
$currencyCode = $journal['currency_code']; $currencyCode = $journal['currency_code'];
$currencyDecimalPlaces = $journal['currency_decimal_places']; $currencyDecimalPlaces = $journal['currency_decimal_places'];
$field = 'amount';
if ($this->convertToPrimary && $this->primaryCurrency->id !== $currencyId) { if ($this->convertToPrimary && $this->primaryCurrency->id !== $currencyId) {
$field = 'pc_amount'; $field = 'pc_amount';
$currencyName = $this->primaryCurrency->name; $currencyName = $this->primaryCurrency->name;

View File

@@ -38,6 +38,7 @@ use FireflyIII\Repositories\Budget\NoBudgetRepositoryInterface;
use FireflyIII\Repositories\Budget\OperationsRepositoryInterface; use FireflyIII\Repositories\Budget\OperationsRepositoryInterface;
use FireflyIII\Support\CacheProperties; use FireflyIII\Support\CacheProperties;
use FireflyIII\Support\Chart\Budget\FrontpageChartGenerator; use FireflyIII\Support\Chart\Budget\FrontpageChartGenerator;
use FireflyIII\Support\Facades\Navigation;
use FireflyIII\Support\Http\Controllers\AugumentData; use FireflyIII\Support\Http\Controllers\AugumentData;
use FireflyIII\Support\Http\Controllers\DateCalculation; use FireflyIII\Support\Http\Controllers\DateCalculation;
use Illuminate\Http\JsonResponse; use Illuminate\Http\JsonResponse;
@@ -102,14 +103,14 @@ class BudgetController extends Controller
$collection = new Collection([$budget]); $collection = new Collection([$budget]);
$chartData = []; $chartData = [];
$loopStart = clone $start; $loopStart = clone $start;
$loopStart = app('navigation')->startOfPeriod($loopStart, $step); $loopStart = Navigation::startOfPeriod($loopStart, $step);
$currencies = []; $currencies = [];
$defaultEntries = []; $defaultEntries = [];
while ($end >= $loopStart) { while ($end >= $loopStart) {
/** @var Carbon $loopEnd */ /** @var Carbon $loopEnd */
$loopEnd = app('navigation')->endOfPeriod($loopStart, $step); $loopEnd = Navigation::endOfPeriod($loopStart, $step);
$spent = $this->opsRepository->sumExpenses($loopStart, $loopEnd, null, $collection); // this method already converts to primary currency. $spent = $this->opsRepository->sumExpenses($loopStart, $loopEnd, null, $collection); // this method already converts to primary currency.
$label = trim((string) app('navigation')->periodShow($loopStart, $step)); $label = trim(Navigation::periodShow($loopStart, $step));
foreach ($spent as $row) { foreach ($spent as $row) {
$currencyId = $row['currency_id']; $currencyId = $row['currency_id'];
@@ -496,8 +497,8 @@ class BudgetController extends Controller
if ($cache->has()) { if ($cache->has()) {
return response()->json($cache->get()); return response()->json($cache->get());
} }
$titleFormat = app('navigation')->preferredCarbonLocalizedFormat($start, $end); $titleFormat = Navigation::preferredCarbonLocalizedFormat($start, $end);
$preferredRange = app('navigation')->preferredRangeFormat($start, $end); $preferredRange = Navigation::preferredRangeFormat($start, $end);
$chartData = [ $chartData = [
[ [
'label' => (string) trans('firefly.box_spent_in_currency', ['currency' => $currency->name]), 'label' => (string) trans('firefly.box_spent_in_currency', ['currency' => $currency->name]),
@@ -517,9 +518,9 @@ class BudgetController extends Controller
$currentStart = clone $start; $currentStart = clone $start;
while ($currentStart <= $end) { while ($currentStart <= $end) {
$currentStart = app('navigation')->startOfPeriod($currentStart, $preferredRange); $currentStart = Navigation::startOfPeriod($currentStart, $preferredRange);
$title = $currentStart->isoFormat($titleFormat); $title = $currentStart->isoFormat($titleFormat);
$currentEnd = app('navigation')->endOfPeriod($currentStart, $preferredRange); $currentEnd = Navigation::endOfPeriod($currentStart, $preferredRange);
// default limit is no limit: // default limit is no limit:
$chartData[0]['entries'][$title] = 0; $chartData[0]['entries'][$title] = 0;
@@ -565,17 +566,17 @@ class BudgetController extends Controller
} }
// the expenses: // the expenses:
$titleFormat = app('navigation')->preferredCarbonLocalizedFormat($start, $end); $titleFormat = Navigation::preferredCarbonLocalizedFormat($start, $end);
$chartData = []; $chartData = [];
$currentStart = clone $start; $currentStart = clone $start;
$preferredRange = app('navigation')->preferredRangeFormat($start, $end); $preferredRange = Navigation::preferredRangeFormat($start, $end);
while ($currentStart <= $end) { while ($currentStart <= $end) {
$currentEnd = app('navigation')->endOfPeriod($currentStart, $preferredRange); $currentEnd = Navigation::endOfPeriod($currentStart, $preferredRange);
$title = $currentStart->isoFormat($titleFormat); $title = $currentStart->isoFormat($titleFormat);
$sum = $this->nbRepository->sumExpenses($currentStart, $currentEnd, $accounts, $currency); $sum = $this->nbRepository->sumExpenses($currentStart, $currentEnd, $accounts, $currency);
$amount = app('steam')->positive($sum[$currency->id]['sum'] ?? '0'); $amount = app('steam')->positive($sum[$currency->id]['sum'] ?? '0');
$chartData[$title] = app('steam')->bcround($amount, $currency->decimal_places); $chartData[$title] = app('steam')->bcround($amount, $currency->decimal_places);
$currentStart = app('navigation')->addPeriod($currentStart, $preferredRange, 0); $currentStart = Navigation::addPeriod($currentStart, $preferredRange, 0);
} }
$data = $this->generator->singleSet((string) trans('firefly.spent'), $chartData); $data = $this->generator->singleSet((string) trans('firefly.spent'), $chartData);

View File

@@ -29,6 +29,8 @@ use FireflyIII\Generator\Chart\Basic\GeneratorInterface;
use FireflyIII\Http\Controllers\Controller; use FireflyIII\Http\Controllers\Controller;
use FireflyIII\Models\Budget; use FireflyIII\Models\Budget;
use FireflyIII\Repositories\Budget\OperationsRepositoryInterface; use FireflyIII\Repositories\Budget\OperationsRepositoryInterface;
use FireflyIII\Support\Facades\Navigation;
use FireflyIII\Support\Facades\Steam;
use FireflyIII\Support\Http\Controllers\AugumentData; use FireflyIII\Support\Http\Controllers\AugumentData;
use FireflyIII\Support\Http\Controllers\TransactionCalculation; use FireflyIII\Support\Http\Controllers\TransactionCalculation;
use Illuminate\Http\JsonResponse; use Illuminate\Http\JsonResponse;
@@ -84,8 +86,8 @@ class BudgetReportController extends Controller
'currency_code' => $currency['currency_code'], 'currency_code' => $currency['currency_code'],
]; ];
foreach ($budget['transaction_journals'] as $journal) { foreach ($budget['transaction_journals'] as $journal) {
$amount = app('steam')->positive($journal['amount']); $amount = Steam::positive($journal['amount']);
$result[$title]['amount'] = bcadd($result[$title]['amount'], (string) $amount); $result[$title]['amount'] = bcadd($result[$title]['amount'], $amount);
} }
} }
} }
@@ -114,8 +116,8 @@ class BudgetReportController extends Controller
'currency_code' => $currency['currency_code'], 'currency_code' => $currency['currency_code'],
]; ];
$amount = app('steam')->positive($journal['amount']); $amount = Steam::positive($journal['amount']);
$result[$title]['amount'] = bcadd($result[$title]['amount'], (string) $amount); $result[$title]['amount'] = bcadd($result[$title]['amount'], $amount);
} }
} }
} }
@@ -144,8 +146,8 @@ class BudgetReportController extends Controller
'currency_code' => $currency['currency_code'], 'currency_code' => $currency['currency_code'],
]; ];
$amount = app('steam')->positive($journal['amount']); $amount = Steam::positive($journal['amount']);
$result[$title]['amount'] = bcadd($result[$title]['amount'], (string) $amount); $result[$title]['amount'] = bcadd($result[$title]['amount'], $amount);
} }
} }
} }
@@ -162,7 +164,7 @@ class BudgetReportController extends Controller
{ {
$chartData = []; $chartData = [];
$spent = $this->opsRepository->listExpenses($start, $end, $accounts, new Collection([$budget])); $spent = $this->opsRepository->listExpenses($start, $end, $accounts, new Collection([$budget]));
$format = app('navigation')->preferredCarbonLocalizedFormat($start, $end); $format = Navigation::preferredCarbonLocalizedFormat($start, $end);
// loop expenses. // loop expenses.
foreach ($spent as $currency) { foreach ($spent as $currency) {
@@ -184,9 +186,9 @@ class BudgetReportController extends Controller
foreach ($currency['budgets'] as $currentBudget) { foreach ($currency['budgets'] as $currentBudget) {
foreach ($currentBudget['transaction_journals'] as $journal) { foreach ($currentBudget['transaction_journals'] as $journal) {
$key = $journal['date']->isoFormat($format); $key = $journal['date']->isoFormat($format);
$amount = app('steam')->positive($journal['amount']); $amount = Steam::positive($journal['amount']);
$chartData[$spentKey]['entries'][$key] ??= '0'; $chartData[$spentKey]['entries'][$key] ??= '0';
$chartData[$spentKey]['entries'][$key] = bcadd($chartData[$spentKey]['entries'][$key], (string) $amount); $chartData[$spentKey]['entries'][$key] = bcadd($chartData[$spentKey]['entries'][$key], $amount);
} }
} }
} }
@@ -199,11 +201,11 @@ class BudgetReportController extends Controller
private function makeEntries(Carbon $start, Carbon $end): array private function makeEntries(Carbon $start, Carbon $end): array
{ {
$return = []; $return = [];
$format = app('navigation')->preferredCarbonLocalizedFormat($start, $end); $format = Navigation::preferredCarbonLocalizedFormat($start, $end);
$preferredRange = app('navigation')->preferredRangeFormat($start, $end); $preferredRange = Navigation::preferredRangeFormat($start, $end);
$currentStart = clone $start; $currentStart = clone $start;
while ($currentStart <= $end) { while ($currentStart <= $end) {
$currentEnd = app('navigation')->endOfPeriod($currentStart, $preferredRange); $currentEnd = Navigation::endOfPeriod($currentStart, $preferredRange);
$key = $currentStart->isoFormat($format); $key = $currentStart->isoFormat($format);
$return[$key] = '0'; $return[$key] = '0';
$currentStart = clone $currentEnd; $currentStart = clone $currentEnd;
@@ -232,8 +234,8 @@ class BudgetReportController extends Controller
'currency_code' => $currency['currency_code'], 'currency_code' => $currency['currency_code'],
]; ];
$amount = app('steam')->positive($journal['amount']); $amount = Steam::positive($journal['amount']);
$result[$title]['amount'] = bcadd($result[$title]['amount'], (string) $amount); $result[$title]['amount'] = bcadd($result[$title]['amount'], $amount);
} }
} }
} }

View File

@@ -34,6 +34,7 @@ use FireflyIII\Repositories\Category\OperationsRepositoryInterface;
use FireflyIII\Support\CacheProperties; use FireflyIII\Support\CacheProperties;
use FireflyIII\Support\Chart\Category\FrontpageChartGenerator; use FireflyIII\Support\Chart\Category\FrontpageChartGenerator;
use FireflyIII\Support\Chart\Category\WholePeriodChartGenerator; use FireflyIII\Support\Chart\Category\WholePeriodChartGenerator;
use FireflyIII\Support\Facades\Steam;
use FireflyIII\Support\Http\Controllers\AugumentData; use FireflyIII\Support\Http\Controllers\AugumentData;
use FireflyIII\Support\Http\Controllers\ChartGeneration; use FireflyIII\Support\Http\Controllers\ChartGeneration;
use FireflyIII\Support\Http\Controllers\DateCalculation; use FireflyIII\Support\Http\Controllers\DateCalculation;
@@ -211,19 +212,19 @@ class CategoryController extends Controller
// loop income and expenses for this category.: // loop income and expenses for this category.:
$outSet = $expenses[$currencyId]['categories'][$categoryId] ?? ['transaction_journals' => []]; $outSet = $expenses[$currencyId]['categories'][$categoryId] ?? ['transaction_journals' => []];
foreach ($outSet['transaction_journals'] as $journal) { foreach ($outSet['transaction_journals'] as $journal) {
$amount = app('steam')->positive($journal['amount']); $amount = Steam::positive($journal['amount']);
$date = $journal['date']->isoFormat($format); $date = $journal['date']->isoFormat($format);
$chartData[$outKey]['entries'][$date] ??= '0'; $chartData[$outKey]['entries'][$date] ??= '0';
$chartData[$outKey]['entries'][$date] = bcadd((string) $amount, $chartData[$outKey]['entries'][$date]); $chartData[$outKey]['entries'][$date] = bcadd($amount, $chartData[$outKey]['entries'][$date]);
} }
$inSet = $income[$currencyId]['categories'][$categoryId] ?? ['transaction_journals' => []]; $inSet = $income[$currencyId]['categories'][$categoryId] ?? ['transaction_journals' => []];
foreach ($inSet['transaction_journals'] as $journal) { foreach ($inSet['transaction_journals'] as $journal) {
$amount = app('steam')->positive($journal['amount']); $amount = Steam::positive($journal['amount']);
$date = $journal['date']->isoFormat($format); $date = $journal['date']->isoFormat($format);
$chartData[$inKey]['entries'][$date] ??= '0'; $chartData[$inKey]['entries'][$date] ??= '0';
$chartData[$inKey]['entries'][$date] = bcadd((string) $amount, $chartData[$inKey]['entries'][$date]); $chartData[$inKey]['entries'][$date] = bcadd($amount, $chartData[$inKey]['entries'][$date]);
} }
} }

View File

@@ -28,6 +28,7 @@ use FireflyIII\Generator\Chart\Basic\GeneratorInterface;
use FireflyIII\Http\Controllers\Controller; use FireflyIII\Http\Controllers\Controller;
use FireflyIII\Models\Category; use FireflyIII\Models\Category;
use FireflyIII\Repositories\Category\OperationsRepositoryInterface; use FireflyIII\Repositories\Category\OperationsRepositoryInterface;
use FireflyIII\Support\Facades\Steam;
use FireflyIII\Support\Http\Controllers\AugumentData; use FireflyIII\Support\Http\Controllers\AugumentData;
use FireflyIII\Support\Http\Controllers\TransactionCalculation; use FireflyIII\Support\Http\Controllers\TransactionCalculation;
use Illuminate\Http\JsonResponse; use Illuminate\Http\JsonResponse;
@@ -82,8 +83,8 @@ class CategoryReportController extends Controller
'currency_symbol' => $currency['currency_symbol'], 'currency_symbol' => $currency['currency_symbol'],
'currency_code' => $currency['currency_code'], 'currency_code' => $currency['currency_code'],
]; ];
$amount = app('steam')->positive($journal['amount']); $amount = Steam::positive($journal['amount']);
$result[$title]['amount'] = bcadd($result[$title]['amount'], (string) $amount); $result[$title]['amount'] = bcadd($result[$title]['amount'], $amount);
} }
} }
} }
@@ -109,8 +110,8 @@ class CategoryReportController extends Controller
'currency_code' => $currency['currency_code'], 'currency_code' => $currency['currency_code'],
]; ];
foreach ($category['transaction_journals'] as $journal) { foreach ($category['transaction_journals'] as $journal) {
$amount = app('steam')->positive($journal['amount']); $amount = Steam::positive($journal['amount']);
$result[$title]['amount'] = bcadd($result[$title]['amount'], (string) $amount); $result[$title]['amount'] = bcadd($result[$title]['amount'], $amount);
} }
} }
} }
@@ -137,8 +138,8 @@ class CategoryReportController extends Controller
'currency_code' => $currency['currency_code'], 'currency_code' => $currency['currency_code'],
]; ];
foreach ($category['transaction_journals'] as $journal) { foreach ($category['transaction_journals'] as $journal) {
$amount = app('steam')->positive($journal['amount']); $amount = Steam::positive($journal['amount']);
$result[$title]['amount'] = bcadd($result[$title]['amount'], (string) $amount); $result[$title]['amount'] = bcadd($result[$title]['amount'], $amount);
} }
} }
} }
@@ -165,8 +166,8 @@ class CategoryReportController extends Controller
'currency_symbol' => $currency['currency_symbol'], 'currency_symbol' => $currency['currency_symbol'],
'currency_code' => $currency['currency_code'], 'currency_code' => $currency['currency_code'],
]; ];
$amount = app('steam')->positive($journal['amount']); $amount = Steam::positive($journal['amount']);
$result[$title]['amount'] = bcadd($result[$title]['amount'], (string) $amount); $result[$title]['amount'] = bcadd($result[$title]['amount'], $amount);
} }
} }
} }
@@ -193,8 +194,8 @@ class CategoryReportController extends Controller
'currency_symbol' => $currency['currency_symbol'], 'currency_symbol' => $currency['currency_symbol'],
'currency_code' => $currency['currency_code'], 'currency_code' => $currency['currency_code'],
]; ];
$amount = app('steam')->positive($journal['amount']); $amount = Steam::positive($journal['amount']);
$result[$title]['amount'] = bcadd($result[$title]['amount'], (string) $amount); $result[$title]['amount'] = bcadd($result[$title]['amount'], $amount);
} }
} }
} }
@@ -230,9 +231,9 @@ class CategoryReportController extends Controller
foreach ($currency['categories'] as $currentCategory) { foreach ($currency['categories'] as $currentCategory) {
foreach ($currentCategory['transaction_journals'] as $journal) { foreach ($currentCategory['transaction_journals'] as $journal) {
$key = $journal['date']->isoFormat($format); $key = $journal['date']->isoFormat($format);
$amount = app('steam')->positive($journal['amount']); $amount = Steam::positive($journal['amount']);
$chartData[$spentKey]['entries'][$key] ??= '0'; $chartData[$spentKey]['entries'][$key] ??= '0';
$chartData[$spentKey]['entries'][$key] = bcadd($chartData[$spentKey]['entries'][$key], (string) $amount); $chartData[$spentKey]['entries'][$key] = bcadd($chartData[$spentKey]['entries'][$key], $amount);
} }
} }
} }
@@ -257,9 +258,9 @@ class CategoryReportController extends Controller
foreach ($currency['categories'] as $currentCategory) { foreach ($currency['categories'] as $currentCategory) {
foreach ($currentCategory['transaction_journals'] as $journal) { foreach ($currentCategory['transaction_journals'] as $journal) {
$key = $journal['date']->isoFormat($format); $key = $journal['date']->isoFormat($format);
$amount = app('steam')->positive($journal['amount']); $amount = Steam::positive($journal['amount']);
$chartData[$spentKey]['entries'][$key] ??= '0'; $chartData[$spentKey]['entries'][$key] ??= '0';
$chartData[$spentKey]['entries'][$key] = bcadd($chartData[$spentKey]['entries'][$key], (string) $amount); $chartData[$spentKey]['entries'][$key] = bcadd($chartData[$spentKey]['entries'][$key], $amount);
} }
} }
} }
@@ -306,8 +307,8 @@ class CategoryReportController extends Controller
'currency_symbol' => $currency['currency_symbol'], 'currency_symbol' => $currency['currency_symbol'],
'currency_code' => $currency['currency_code'], 'currency_code' => $currency['currency_code'],
]; ];
$amount = app('steam')->positive($journal['amount']); $amount = Steam::positive($journal['amount']);
$result[$title]['amount'] = bcadd($result[$title]['amount'], (string) $amount); $result[$title]['amount'] = bcadd($result[$title]['amount'], $amount);
} }
} }
} }
@@ -334,8 +335,8 @@ class CategoryReportController extends Controller
'currency_symbol' => $currency['currency_symbol'], 'currency_symbol' => $currency['currency_symbol'],
'currency_code' => $currency['currency_code'], 'currency_code' => $currency['currency_code'],
]; ];
$amount = app('steam')->positive($journal['amount']); $amount = Steam::positive($journal['amount']);
$result[$title]['amount'] = bcadd($result[$title]['amount'], (string) $amount); $result[$title]['amount'] = bcadd($result[$title]['amount'], $amount);
} }
} }
} }

View File

@@ -30,6 +30,7 @@ use FireflyIII\Http\Controllers\Controller;
use FireflyIII\Models\Account; use FireflyIII\Models\Account;
use FireflyIII\Repositories\Account\AccountRepositoryInterface; use FireflyIII\Repositories\Account\AccountRepositoryInterface;
use FireflyIII\Repositories\Account\OperationsRepositoryInterface; use FireflyIII\Repositories\Account\OperationsRepositoryInterface;
use FireflyIII\Support\Facades\Steam;
use Illuminate\Http\JsonResponse; use Illuminate\Http\JsonResponse;
use Illuminate\Support\Collection; use Illuminate\Support\Collection;
@@ -81,8 +82,8 @@ class DoubleReportController extends Controller
'currency_symbol' => $currency['currency_symbol'], 'currency_symbol' => $currency['currency_symbol'],
'currency_code' => $currency['currency_code'], 'currency_code' => $currency['currency_code'],
]; ];
$amount = app('steam')->positive($journal['amount']); $amount = Steam::positive($journal['amount']);
$result[$title]['amount'] = bcadd($result[$title]['amount'], (string) $amount); $result[$title]['amount'] = bcadd($result[$title]['amount'], $amount);
} }
} }
@@ -108,8 +109,8 @@ class DoubleReportController extends Controller
'currency_symbol' => $currency['currency_symbol'], 'currency_symbol' => $currency['currency_symbol'],
'currency_code' => $currency['currency_code'], 'currency_code' => $currency['currency_code'],
]; ];
$amount = app('steam')->positive($journal['amount']); $amount = Steam::positive($journal['amount']);
$result[$title]['amount'] = bcadd($result[$title]['amount'], (string) $amount); $result[$title]['amount'] = bcadd($result[$title]['amount'], $amount);
} }
} }
@@ -135,8 +136,8 @@ class DoubleReportController extends Controller
'currency_symbol' => $currency['currency_symbol'], 'currency_symbol' => $currency['currency_symbol'],
'currency_code' => $currency['currency_code'], 'currency_code' => $currency['currency_code'],
]; ];
$amount = app('steam')->positive($journal['amount']); $amount = Steam::positive($journal['amount']);
$result[$title]['amount'] = bcadd($result[$title]['amount'], (string) $amount); $result[$title]['amount'] = bcadd($result[$title]['amount'], $amount);
} }
} }
@@ -176,9 +177,9 @@ class DoubleReportController extends Controller
foreach ($currency['transaction_journals'] as $journal) { foreach ($currency['transaction_journals'] as $journal) {
$key = $journal['date']->isoFormat($format); $key = $journal['date']->isoFormat($format);
$amount = app('steam')->positive($journal['amount']); $amount = Steam::positive($journal['amount']);
$chartData[$spentKey]['entries'][$key] ??= '0'; $chartData[$spentKey]['entries'][$key] ??= '0';
$chartData[$spentKey]['entries'][$key] = bcadd($chartData[$spentKey]['entries'][$key], (string) $amount); $chartData[$spentKey]['entries'][$key] = bcadd($chartData[$spentKey]['entries'][$key], $amount);
} }
} }
// loop income. // loop income.
@@ -202,9 +203,9 @@ class DoubleReportController extends Controller
foreach ($currency['transaction_journals'] as $journal) { foreach ($currency['transaction_journals'] as $journal) {
$key = $journal['date']->isoFormat($format); $key = $journal['date']->isoFormat($format);
$amount = app('steam')->positive($journal['amount']); $amount = Steam::positive($journal['amount']);
$chartData[$earnedKey]['entries'][$key] ??= '0'; $chartData[$earnedKey]['entries'][$key] ??= '0';
$chartData[$earnedKey]['entries'][$key] = bcadd($chartData[$earnedKey]['entries'][$key], (string) $amount); $chartData[$earnedKey]['entries'][$key] = bcadd($chartData[$earnedKey]['entries'][$key], $amount);
} }
} }
@@ -274,8 +275,8 @@ class DoubleReportController extends Controller
'currency_symbol' => $currency['currency_symbol'], 'currency_symbol' => $currency['currency_symbol'],
'currency_code' => $currency['currency_code'], 'currency_code' => $currency['currency_code'],
]; ];
$amount = app('steam')->positive($journal['amount']); $amount = Steam::positive($journal['amount']);
$result[$title]['amount'] = bcadd($result[$title]['amount'], (string) $amount); $result[$title]['amount'] = bcadd($result[$title]['amount'], $amount);
} }
// loop each tag: // loop each tag:
@@ -293,8 +294,8 @@ class DoubleReportController extends Controller
'currency_symbol' => $currency['currency_symbol'], 'currency_symbol' => $currency['currency_symbol'],
'currency_code' => $currency['currency_code'], 'currency_code' => $currency['currency_code'],
]; ];
$amount = app('steam')->positive($journal['amount']); $amount = Steam::positive($journal['amount']);
$result[$title]['amount'] = bcadd($result[$title]['amount'], (string) $amount); $result[$title]['amount'] = bcadd($result[$title]['amount'], $amount);
} }
} }
} }
@@ -327,8 +328,8 @@ class DoubleReportController extends Controller
'currency_symbol' => $currency['currency_symbol'], 'currency_symbol' => $currency['currency_symbol'],
'currency_code' => $currency['currency_code'], 'currency_code' => $currency['currency_code'],
]; ];
$amount = app('steam')->positive($journal['amount']); $amount = Steam::positive($journal['amount']);
$result[$title]['amount'] = bcadd($result[$title]['amount'], (string) $amount); $result[$title]['amount'] = bcadd($result[$title]['amount'], $amount);
} }
// loop each tag: // loop each tag:
@@ -346,8 +347,8 @@ class DoubleReportController extends Controller
'currency_symbol' => $currency['currency_symbol'], 'currency_symbol' => $currency['currency_symbol'],
'currency_code' => $currency['currency_code'], 'currency_code' => $currency['currency_code'],
]; ];
$amount = app('steam')->positive($journal['amount']); $amount = Steam::positive($journal['amount']);
$result[$title]['amount'] = bcadd($result[$title]['amount'], (string) $amount); $result[$title]['amount'] = bcadd($result[$title]['amount'], $amount);
} }
} }
} }

View File

@@ -32,6 +32,7 @@ use FireflyIII\Http\Controllers\Controller;
use FireflyIII\Models\Account; use FireflyIII\Models\Account;
use FireflyIII\Repositories\Account\AccountRepositoryInterface; use FireflyIII\Repositories\Account\AccountRepositoryInterface;
use FireflyIII\Support\CacheProperties; use FireflyIII\Support\CacheProperties;
use FireflyIII\Support\Facades\Steam;
use FireflyIII\Support\Http\Controllers\BasicDataSupport; use FireflyIII\Support\Http\Controllers\BasicDataSupport;
use FireflyIII\Support\Http\Controllers\ChartGeneration; use FireflyIII\Support\Http\Controllers\ChartGeneration;
use Illuminate\Http\JsonResponse; use Illuminate\Http\JsonResponse;
@@ -73,7 +74,7 @@ class ReportController extends Controller
if ($cache->has()) { if ($cache->has()) {
return response()->json($cache->get()); return response()->json($cache->get());
} }
$locale = app('steam')->getLocale(); $locale = Steam::getLocale();
$current = clone $start; $current = clone $start;
$chartData = []; $chartData = [];
@@ -193,7 +194,7 @@ class ReportController extends Controller
]; ];
// in our outgoing? // in our outgoing?
$key = 'spent'; $key = 'spent';
$amount = app('steam')->positive($journal['amount']); $amount = Steam::positive($journal['amount']);
// deposit = incoming // deposit = incoming
// transfer or reconcile or opening balance, and these accounts are the destination. // transfer or reconcile or opening balance, and these accounts are the destination.
@@ -207,7 +208,7 @@ class ReportController extends Controller
&& in_array($journal['destination_account_id'], $ids, true))) { && in_array($journal['destination_account_id'], $ids, true))) {
$key = 'earned'; $key = 'earned';
} }
$data[$currencyId][$period][$key] = bcadd((string) $data[$currencyId][$period][$key], (string) $amount); $data[$currencyId][$period][$key] = bcadd((string) $data[$currencyId][$period][$key], $amount);
} }
// loop this data, make chart bars for each currency: // loop this data, make chart bars for each currency:
@@ -250,8 +251,8 @@ class ReportController extends Controller
$title = $currentStart->isoFormat($titleFormat); $title = $currentStart->isoFormat($titleFormat);
// #8663 make sure the period exists in the data previously collected. // #8663 make sure the period exists in the data previously collected.
if (array_key_exists($key, $currency)) { if (array_key_exists($key, $currency)) {
$income['entries'][$title] = app('steam')->bcround($currency[$key]['earned'] ?? '0', $currency['currency_decimal_places']); $income['entries'][$title] = Steam::bcround($currency[$key]['earned'] ?? '0', $currency['currency_decimal_places']);
$expense['entries'][$title] = app('steam')->bcround($currency[$key]['spent'] ?? '0', $currency['currency_decimal_places']); $expense['entries'][$title] = Steam::bcround($currency[$key]['spent'] ?? '0', $currency['currency_decimal_places']);
} }
// #9477 if the period is not in the data, add it with zero values. // #9477 if the period is not in the data, add it with zero values.
if (!array_key_exists($key, $currency)) { if (!array_key_exists($key, $currency)) {

View File

@@ -28,6 +28,7 @@ use FireflyIII\Generator\Chart\Basic\GeneratorInterface;
use FireflyIII\Http\Controllers\Controller; use FireflyIII\Http\Controllers\Controller;
use FireflyIII\Models\Tag; use FireflyIII\Models\Tag;
use FireflyIII\Repositories\Tag\OperationsRepositoryInterface; use FireflyIII\Repositories\Tag\OperationsRepositoryInterface;
use FireflyIII\Support\Facades\Steam;
use FireflyIII\Support\Http\Controllers\AugumentData; use FireflyIII\Support\Http\Controllers\AugumentData;
use FireflyIII\Support\Http\Controllers\TransactionCalculation; use FireflyIII\Support\Http\Controllers\TransactionCalculation;
use Illuminate\Http\JsonResponse; use Illuminate\Http\JsonResponse;
@@ -82,8 +83,8 @@ class TagReportController extends Controller
'currency_symbol' => $currency['currency_symbol'], 'currency_symbol' => $currency['currency_symbol'],
'currency_code' => $currency['currency_code'], 'currency_code' => $currency['currency_code'],
]; ];
$amount = app('steam')->positive($journal['amount']); $amount = Steam::positive($journal['amount']);
$result[$title]['amount'] = bcadd($result[$title]['amount'], (string) $amount); $result[$title]['amount'] = bcadd($result[$title]['amount'], $amount);
} }
} }
} }
@@ -110,8 +111,8 @@ class TagReportController extends Controller
'currency_symbol' => $currency['currency_symbol'], 'currency_symbol' => $currency['currency_symbol'],
'currency_code' => $currency['currency_code'], 'currency_code' => $currency['currency_code'],
]; ];
$amount = app('steam')->positive($journal['amount']); $amount = Steam::positive($journal['amount']);
$result[$title]['amount'] = bcadd($result[$title]['amount'], (string) $amount); $result[$title]['amount'] = bcadd($result[$title]['amount'], $amount);
} }
} }
} }
@@ -138,8 +139,8 @@ class TagReportController extends Controller
'currency_symbol' => $currency['currency_symbol'], 'currency_symbol' => $currency['currency_symbol'],
'currency_code' => $currency['currency_code'], 'currency_code' => $currency['currency_code'],
]; ];
$amount = app('steam')->positive($journal['amount']); $amount = Steam::positive($journal['amount']);
$result[$title]['amount'] = bcadd($result[$title]['amount'], (string) $amount); $result[$title]['amount'] = bcadd($result[$title]['amount'], $amount);
} }
} }
} }
@@ -166,8 +167,8 @@ class TagReportController extends Controller
'currency_symbol' => $currency['currency_symbol'], 'currency_symbol' => $currency['currency_symbol'],
'currency_code' => $currency['currency_code'], 'currency_code' => $currency['currency_code'],
]; ];
$amount = app('steam')->positive($journal['amount']); $amount = Steam::positive($journal['amount']);
$result[$title]['amount'] = bcadd($result[$title]['amount'], (string) $amount); $result[$title]['amount'] = bcadd($result[$title]['amount'], $amount);
} }
} }
} }
@@ -194,8 +195,8 @@ class TagReportController extends Controller
'currency_symbol' => $currency['currency_symbol'], 'currency_symbol' => $currency['currency_symbol'],
'currency_code' => $currency['currency_code'], 'currency_code' => $currency['currency_code'],
]; ];
$amount = app('steam')->positive($journal['amount']); $amount = Steam::positive($journal['amount']);
$result[$title]['amount'] = bcadd($result[$title]['amount'], (string) $amount); $result[$title]['amount'] = bcadd($result[$title]['amount'], $amount);
} }
} }
} }
@@ -235,9 +236,9 @@ class TagReportController extends Controller
foreach ($currency['tags'] as $currentTag) { foreach ($currency['tags'] as $currentTag) {
foreach ($currentTag['transaction_journals'] as $journal) { foreach ($currentTag['transaction_journals'] as $journal) {
$key = $journal['date']->isoFormat($format); $key = $journal['date']->isoFormat($format);
$amount = app('steam')->positive($journal['amount']); $amount = Steam::positive($journal['amount']);
$chartData[$spentKey]['entries'][$key] ??= '0'; $chartData[$spentKey]['entries'][$key] ??= '0';
$chartData[$spentKey]['entries'][$key] = bcadd($chartData[$spentKey]['entries'][$key], (string) $amount); $chartData[$spentKey]['entries'][$key] = bcadd($chartData[$spentKey]['entries'][$key], $amount);
} }
} }
} }
@@ -262,9 +263,9 @@ class TagReportController extends Controller
foreach ($currency['tags'] as $currentTag) { foreach ($currency['tags'] as $currentTag) {
foreach ($currentTag['transaction_journals'] as $journal) { foreach ($currentTag['transaction_journals'] as $journal) {
$key = $journal['date']->isoFormat($format); $key = $journal['date']->isoFormat($format);
$amount = app('steam')->positive($journal['amount']); $amount = Steam::positive($journal['amount']);
$chartData[$spentKey]['entries'][$key] ??= '0'; $chartData[$spentKey]['entries'][$key] ??= '0';
$chartData[$spentKey]['entries'][$key] = bcadd($chartData[$spentKey]['entries'][$key], (string) $amount); $chartData[$spentKey]['entries'][$key] = bcadd($chartData[$spentKey]['entries'][$key], $amount);
} }
} }
} }
@@ -311,8 +312,8 @@ class TagReportController extends Controller
'currency_symbol' => $currency['currency_symbol'], 'currency_symbol' => $currency['currency_symbol'],
'currency_code' => $currency['currency_code'], 'currency_code' => $currency['currency_code'],
]; ];
$amount = app('steam')->positive($journal['amount']); $amount = Steam::positive($journal['amount']);
$result[$title]['amount'] = bcadd($result[$title]['amount'], (string) $amount); $result[$title]['amount'] = bcadd($result[$title]['amount'], $amount);
} }
} }
} }
@@ -339,8 +340,8 @@ class TagReportController extends Controller
'currency_symbol' => $currency['currency_symbol'], 'currency_symbol' => $currency['currency_symbol'],
'currency_code' => $currency['currency_code'], 'currency_code' => $currency['currency_code'],
]; ];
$amount = app('steam')->positive($journal['amount']); $amount = Steam::positive($journal['amount']);
$result[$title]['amount'] = bcadd($result[$title]['amount'], (string) $amount); $result[$title]['amount'] = bcadd($result[$title]['amount'], $amount);
} }
} }
} }
@@ -366,8 +367,8 @@ class TagReportController extends Controller
'currency_code' => $currency['currency_code'], 'currency_code' => $currency['currency_code'],
]; ];
foreach ($tag['transaction_journals'] as $journal) { foreach ($tag['transaction_journals'] as $journal) {
$amount = app('steam')->positive($journal['amount']); $amount = Steam::positive($journal['amount']);
$result[$title]['amount'] = bcadd($result[$title]['amount'], (string) $amount); $result[$title]['amount'] = bcadd($result[$title]['amount'], $amount);
} }
} }
} }
@@ -392,8 +393,8 @@ class TagReportController extends Controller
'currency_code' => $currency['currency_code'], 'currency_code' => $currency['currency_code'],
]; ];
foreach ($tag['transaction_journals'] as $journal) { foreach ($tag['transaction_journals'] as $journal) {
$amount = app('steam')->positive($journal['amount']); $amount = Steam::positive($journal['amount']);
$result[$title]['amount'] = bcadd($result[$title]['amount'], (string) $amount); $result[$title]['amount'] = bcadd($result[$title]['amount'], $amount);
} }
} }
} }

View File

@@ -95,8 +95,8 @@ abstract class Controller extends BaseController
View::share('logoutUrl', $logoutUrl); View::share('logoutUrl', $logoutUrl);
// upload size // upload size
$maxFileSize = Steam::phpBytes((string) ini_get('upload_max_filesize')); $maxFileSize = Steam::phpBytes(ini_get('upload_max_filesize'));
$maxPostSize = Steam::phpBytes((string) ini_get('post_max_size')); $maxPostSize = Steam::phpBytes(ini_get('post_max_size'));
$uploadSize = min($maxFileSize, $maxPostSize); $uploadSize = min($maxFileSize, $maxPostSize);
View::share('uploadSize', $uploadSize); View::share('uploadSize', $uploadSize);
@@ -140,6 +140,7 @@ abstract class Controller extends BaseController
View::share('language', $language); View::share('language', $language);
View::share('locale', $locale); View::share('locale', $locale);
View::share('convertToPrimary', $this->convertToPrimary); View::share('convertToPrimary', $this->convertToPrimary);
View::share('primaryCurrency', $this->primaryCurrency);
View::share('shownDemo', $shownDemo); View::share('shownDemo', $shownDemo);
View::share('current_route_name', $page); View::share('current_route_name', $page);
View::share('original_route_name', Route::currentRouteName()); View::share('original_route_name', Route::currentRouteName());

View File

@@ -151,13 +151,13 @@ class DebugController extends Controller
} }
if ('' !== $logContent) { if ('' !== $logContent) {
// last few lines // last few lines
$logContent = 'Truncated from this point <----|'.substr((string) $logContent, -16384); $logContent = 'Truncated from this point <----|'.substr($logContent, -16384);
} }
return view('debug', compact('table', 'now', 'logContent')); return view('debug', compact('table', 'now', 'logContent'));
} }
public function apiTest() public function apiTest(): View
{ {
return view('test.api-test'); return view('test.api-test');
} }
@@ -175,8 +175,8 @@ class DebugController extends Controller
private function getSystemInformation(): array private function getSystemInformation(): array
{ {
$maxFileSize = Steam::phpBytes((string) ini_get('upload_max_filesize')); $maxFileSize = Steam::phpBytes(ini_get('upload_max_filesize'));
$maxPostSize = Steam::phpBytes((string) ini_get('post_max_size')); $maxPostSize = Steam::phpBytes(ini_get('post_max_size'));
$drivers = DB::availableDrivers(); $drivers = DB::availableDrivers();
$currentDriver = DB::getDriverName(); $currentDriver = DB::getDriverName();
@@ -208,7 +208,7 @@ class DebugController extends Controller
try { try {
if (file_exists('/var/www/counter-main.txt')) { if (file_exists('/var/www/counter-main.txt')) {
$return['build'] = trim((string) file_get_contents('/var/www/counter-main.txt')); $return['build'] = trim(file_get_contents('/var/www/counter-main.txt'));
app('log')->debug(sprintf('build is now "%s"', $return['build'])); app('log')->debug(sprintf('build is now "%s"', $return['build']));
} }
} catch (Exception $e) { } catch (Exception $e) {
@@ -218,7 +218,7 @@ class DebugController extends Controller
try { try {
if (file_exists('/var/www/build-date-main.txt')) { if (file_exists('/var/www/build-date-main.txt')) {
$return['build_date'] = trim((string) file_get_contents('/var/www/build-date-main.txt')); $return['build_date'] = trim(file_get_contents('/var/www/build-date-main.txt'));
} }
} catch (Exception $e) { } catch (Exception $e) {
app('log')->debug('Could not check build date, but thats ok.'); app('log')->debug('Could not check build date, but thats ok.');

View File

@@ -35,6 +35,7 @@ use FireflyIII\Repositories\Account\AccountRepositoryInterface;
use FireflyIII\Repositories\Currency\CurrencyRepositoryInterface; use FireflyIII\Repositories\Currency\CurrencyRepositoryInterface;
use FireflyIII\Support\CacheProperties; use FireflyIII\Support\CacheProperties;
use FireflyIII\Support\Facades\Amount; use FireflyIII\Support\Facades\Amount;
use FireflyIII\Support\Facades\Steam;
use FireflyIII\Support\Http\Controllers\DateCalculation; use FireflyIII\Support\Http\Controllers\DateCalculation;
use Illuminate\Http\JsonResponse; use Illuminate\Http\JsonResponse;
@@ -92,9 +93,9 @@ class BoxController extends Controller
$currencyId = $this->convertToPrimary && $this->primaryCurrency->id !== (int) $journal['currency_id'] ? $this->primaryCurrency->id : (int) $journal['currency_id']; $currencyId = $this->convertToPrimary && $this->primaryCurrency->id !== (int) $journal['currency_id'] ? $this->primaryCurrency->id : (int) $journal['currency_id'];
$amount = Amount::getAmountFromJournal($journal); $amount = Amount::getAmountFromJournal($journal);
$incomes[$currencyId] ??= '0'; $incomes[$currencyId] ??= '0';
$incomes[$currencyId] = bcadd($incomes[$currencyId], (string) app('steam')->positive($amount)); $incomes[$currencyId] = bcadd($incomes[$currencyId], Steam::positive($amount));
$sums[$currencyId] ??= '0'; $sums[$currencyId] ??= '0';
$sums[$currencyId] = bcadd($sums[$currencyId], (string) app('steam')->positive($amount)); $sums[$currencyId] = bcadd($sums[$currencyId], Steam::positive($amount));
} }
// collect expenses // collect expenses

View File

@@ -82,6 +82,8 @@ class ShowController extends Controller
$admin = auth()->user(); $admin = auth()->user();
$enrichment = new PiggyBankEnrichment(); $enrichment = new PiggyBankEnrichment();
$enrichment->setUser($admin); $enrichment->setUser($admin);
/** @var PiggyBank $piggyBank */
$piggyBank = $enrichment->enrichSingle($piggyBank); $piggyBank = $enrichment->enrichSingle($piggyBank);
/** @var PiggyBankTransformer $transformer */ /** @var PiggyBankTransformer $transformer */

View File

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

View File

@@ -207,7 +207,7 @@ class ProfileController extends Controller
$existing = $repository->findByEmail($newEmail); $existing = $repository->findByEmail($newEmail);
if ($existing instanceof User) { if ($existing instanceof User) {
// force user logout. // force user logout.
Auth::guard()->logout(); // @phpstan-ignore-line (does not recognize function) Auth::guard()->logout();
$request->session()->invalidate(); $request->session()->invalidate();
session()->flash('success', (string) trans('firefly.email_changed')); session()->flash('success', (string) trans('firefly.email_changed'));
@@ -221,7 +221,7 @@ class ProfileController extends Controller
event(new UserChangedEmail($user, $newEmail, $oldEmail)); event(new UserChangedEmail($user, $newEmail, $oldEmail));
// force user logout. // force user logout.
Auth::guard()->logout(); // @phpstan-ignore-line (does not recognize function) Auth::guard()->logout();
$request->session()->invalidate(); $request->session()->invalidate();
session()->flash('success', (string) trans('firefly.email_changed')); session()->flash('success', (string) trans('firefly.email_changed'));
@@ -412,7 +412,7 @@ class ProfileController extends Controller
// found user.which email address to return to? // found user.which email address to return to?
$set = app('preferences')->beginsWith($user, 'previous_email_'); $set = app('preferences')->beginsWith($user, 'previous_email_');
/** @var string $match */ /** @var null|string $match */
$match = null; $match = null;
foreach ($set as $entry) { foreach ($set as $entry) {
$hashed = hash('sha256', sprintf('%s%s', (string) config('app.key'), $entry->data)); $hashed = hash('sha256', sprintf('%s%s', (string) config('app.key'), $entry->data));

View File

@@ -49,7 +49,7 @@ class CreateController extends Controller
private AttachmentHelperInterface $attachments; private AttachmentHelperInterface $attachments;
private BillRepositoryInterface $billRepository; private BillRepositoryInterface $billRepository;
private BudgetRepositoryInterface $budgetRepos; private BudgetRepositoryInterface $budgetRepos;
private RecurringRepositoryInterface $recurring; private RecurringRepositoryInterface $repository;
/** /**
* CreateController constructor. * CreateController constructor.
@@ -65,7 +65,7 @@ class CreateController extends Controller
app('view')->share('title', (string) trans('firefly.recurrences')); app('view')->share('title', (string) trans('firefly.recurrences'));
app('view')->share('subTitle', (string) trans('firefly.create_new_recurrence')); app('view')->share('subTitle', (string) trans('firefly.create_new_recurrence'));
$this->recurring = app(RecurringRepositoryInterface::class); $this->repository = app(RecurringRepositoryInterface::class);
$this->budgetRepos = app(BudgetRepositoryInterface::class); $this->budgetRepos = app(BudgetRepositoryInterface::class);
$this->attachments = app(AttachmentHelperInterface::class); $this->attachments = app(AttachmentHelperInterface::class);
$this->billRepository = app(BillRepositoryInterface::class); $this->billRepository = app(BillRepositoryInterface::class);
@@ -84,7 +84,6 @@ class CreateController extends Controller
{ {
$budgets = app('expandedform')->makeSelectListWithEmpty($this->budgetRepos->getActiveBudgets()); $budgets = app('expandedform')->makeSelectListWithEmpty($this->budgetRepos->getActiveBudgets());
$bills = app('expandedform')->makeSelectListWithEmpty($this->billRepository->getActiveBills()); $bills = app('expandedform')->makeSelectListWithEmpty($this->billRepository->getActiveBills());
$primaryCurrency = $this->primaryCurrency;
$tomorrow = today(config('app.timezone')); $tomorrow = today(config('app.timezone'));
$oldRepetitionType = $request->old('repetition_type'); $oldRepetitionType = $request->old('repetition_type');
$tomorrow->addDay(); $tomorrow->addDay();
@@ -116,7 +115,7 @@ class CreateController extends Controller
return view( return view(
'recurring.create', 'recurring.create',
compact('tomorrow', 'oldRepetitionType', 'bills', 'weekendResponses', 'preFilled', 'repetitionEnds', 'primaryCurrency', 'budgets') compact('tomorrow', 'oldRepetitionType', 'bills', 'weekendResponses', 'preFilled', 'repetitionEnds', 'budgets')
); );
} }
@@ -129,7 +128,6 @@ class CreateController extends Controller
{ {
$budgets = app('expandedform')->makeSelectListWithEmpty($this->budgetRepos->getActiveBudgets()); $budgets = app('expandedform')->makeSelectListWithEmpty($this->budgetRepos->getActiveBudgets());
$bills = app('expandedform')->makeSelectListWithEmpty($this->billRepository->getActiveBills()); $bills = app('expandedform')->makeSelectListWithEmpty($this->billRepository->getActiveBills());
$primaryCurrency = $this->primaryCurrency;
$tomorrow = today(config('app.timezone')); $tomorrow = today(config('app.timezone'));
$oldRepetitionType = $request->old('repetition_type'); $oldRepetitionType = $request->old('repetition_type');
$tomorrow->addDay(); $tomorrow->addDay();
@@ -208,10 +206,7 @@ class CreateController extends Controller
} }
$request->session()->flash('preFilled', $preFilled); $request->session()->flash('preFilled', $preFilled);
return view( return view('recurring.create', compact('tomorrow', 'oldRepetitionType', 'bills', 'weekendResponses', 'preFilled', 'repetitionEnds', 'budgets'));
'recurring.create',
compact('tomorrow', 'oldRepetitionType', 'bills', 'weekendResponses', 'preFilled', 'repetitionEnds', 'primaryCurrency', 'budgets')
);
} }
/** /**
@@ -226,7 +221,7 @@ class CreateController extends Controller
$data = $request->getAll(); $data = $request->getAll();
try { try {
$recurrence = $this->recurring->store($data); $recurrence = $this->repository->store($data);
} catch (FireflyException $e) { } catch (FireflyException $e) {
session()->flash('error', $e->getMessage()); session()->flash('error', $e->getMessage());

View File

@@ -38,8 +38,7 @@ use Illuminate\View\View;
*/ */
class DeleteController extends Controller class DeleteController extends Controller
{ {
/** @var RecurringRepositoryInterface Recurring repository */ private RecurringRepositoryInterface $repository;
private $recurring;
/** /**
* DeleteController constructor. * DeleteController constructor.
@@ -54,7 +53,7 @@ class DeleteController extends Controller
app('view')->share('mainTitleIcon', 'fa-paint-brush'); app('view')->share('mainTitleIcon', 'fa-paint-brush');
app('view')->share('title', (string) trans('firefly.recurrences')); app('view')->share('title', (string) trans('firefly.recurrences'));
$this->recurring = app(RecurringRepositoryInterface::class); $this->repository = app(RecurringRepositoryInterface::class);
return $next($request); return $next($request);
} }
@@ -72,7 +71,7 @@ class DeleteController extends Controller
// put previous url in session // put previous url in session
$this->rememberPreviousUrl('recurrences.delete.url'); $this->rememberPreviousUrl('recurrences.delete.url');
$journalsCreated = $this->recurring->getTransactions($recurrence)->count(); $journalsCreated = $this->repository->getTransactions($recurrence)->count();
return view('recurring.delete', compact('recurrence', 'subTitle', 'journalsCreated')); return view('recurring.delete', compact('recurrence', 'subTitle', 'journalsCreated'));
} }

View File

@@ -54,7 +54,7 @@ class EditController extends Controller
private AttachmentHelperInterface $attachments; private AttachmentHelperInterface $attachments;
private BillRepositoryInterface $billRepository; private BillRepositoryInterface $billRepository;
private BudgetRepositoryInterface $budgetRepos; private BudgetRepositoryInterface $budgetRepos;
private RecurringRepositoryInterface $recurring; private RecurringRepositoryInterface $repository;
/** /**
* EditController constructor. * EditController constructor.
@@ -70,7 +70,7 @@ class EditController extends Controller
app('view')->share('title', (string) trans('firefly.recurrences')); app('view')->share('title', (string) trans('firefly.recurrences'));
app('view')->share('subTitle', (string) trans('firefly.recurrences')); app('view')->share('subTitle', (string) trans('firefly.recurrences'));
$this->recurring = app(RecurringRepositoryInterface::class); $this->repository = app(RecurringRepositoryInterface::class);
$this->budgetRepos = app(BudgetRepositoryInterface::class); $this->budgetRepos = app(BudgetRepositoryInterface::class);
$this->attachments = app(AttachmentHelperInterface::class); $this->attachments = app(AttachmentHelperInterface::class);
$this->billRepository = app(BillRepositoryInterface::class); $this->billRepository = app(BillRepositoryInterface::class);
@@ -100,6 +100,8 @@ class EditController extends Controller
$admin = auth()->user(); $admin = auth()->user();
$enrichment = new RecurringEnrichment(); $enrichment = new RecurringEnrichment();
$enrichment->setUser($admin); $enrichment->setUser($admin);
/** @var Recurrence $recurrence */
$recurrence = $enrichment->enrichSingle($recurrence); $recurrence = $enrichment->enrichSingle($recurrence);
/** @var RecurrenceTransformer $transformer */ /** @var RecurrenceTransformer $transformer */
@@ -180,7 +182,7 @@ class EditController extends Controller
public function update(RecurrenceFormRequest $request, Recurrence $recurrence) public function update(RecurrenceFormRequest $request, Recurrence $recurrence)
{ {
$data = $request->getAll(); $data = $request->getAll();
$this->recurring->update($recurrence, $data); $this->repository->update($recurrence, $data);
$request->session()->flash('success', (string) trans('firefly.updated_recurrence', ['title' => $recurrence->title])); $request->session()->flash('success', (string) trans('firefly.updated_recurrence', ['title' => $recurrence->title]));
Log::channel('audit')->info(sprintf('Updated recurrence #%d.', $recurrence->id), $data); Log::channel('audit')->info(sprintf('Updated recurrence #%d.', $recurrence->id), $data);

View File

@@ -45,7 +45,7 @@ class IndexController extends Controller
{ {
use GetConfigurationData; use GetConfigurationData;
private RecurringRepositoryInterface $recurringRepos; private RecurringRepositoryInterface $repository;
/** /**
* IndexController constructor. * IndexController constructor.
@@ -60,7 +60,7 @@ class IndexController extends Controller
app('view')->share('mainTitleIcon', 'fa-paint-brush'); app('view')->share('mainTitleIcon', 'fa-paint-brush');
app('view')->share('title', (string) trans('firefly.recurrences')); app('view')->share('title', (string) trans('firefly.recurrences'));
$this->recurringRepos = app(RecurringRepositoryInterface::class); $this->repository = app(RecurringRepositoryInterface::class);
return $next($request); return $next($request);
} }
@@ -79,7 +79,7 @@ class IndexController extends Controller
{ {
$page = 0 === (int) $request->get('page') ? 1 : (int) $request->get('page'); $page = 0 === (int) $request->get('page') ? 1 : (int) $request->get('page');
$pageSize = (int) app('preferences')->get('listPageSize', 50)->data; $pageSize = (int) app('preferences')->get('listPageSize', 50)->data;
$collection = $this->recurringRepos->get(); $collection = $this->repository->get();
$today = today(config('app.timezone')); $today = today(config('app.timezone'));
$year = today(config('app.timezone')); $year = today(config('app.timezone'));

View File

@@ -47,8 +47,7 @@ class ShowController extends Controller
{ {
use GetConfigurationData; use GetConfigurationData;
/** @var RecurringRepositoryInterface Recurring repository */ private RecurringRepositoryInterface $repository;
private $recurring;
/** /**
* IndexController constructor. * IndexController constructor.
@@ -64,7 +63,7 @@ class ShowController extends Controller
app('view')->share('mainTitleIcon', 'fa-paint-brush'); app('view')->share('mainTitleIcon', 'fa-paint-brush');
app('view')->share('title', (string) trans('firefly.recurrences')); app('view')->share('title', (string) trans('firefly.recurrences'));
$this->recurring = app(RecurringRepositoryInterface::class); $this->repository = app(RecurringRepositoryInterface::class);
return $next($request); return $next($request);
} }
@@ -87,6 +86,8 @@ class ShowController extends Controller
$admin = auth()->user(); $admin = auth()->user();
$enrichment = new RecurringEnrichment(); $enrichment = new RecurringEnrichment();
$enrichment->setUser($admin); $enrichment->setUser($admin);
/** @var Recurrence $recurrence */
$recurrence = $enrichment->enrichSingle($recurrence); $recurrence = $enrichment->enrichSingle($recurrence);
/** @var RecurrenceTransformer $transformer */ /** @var RecurrenceTransformer $transformer */
@@ -95,10 +96,10 @@ class ShowController extends Controller
$array = $transformer->transform($recurrence); $array = $transformer->transform($recurrence);
$groups = $this->recurring->getTransactions($recurrence); $groups = $this->repository->getTransactions($recurrence);
$today = today(config('app.timezone')); $today = today(config('app.timezone'));
$array['repeat_until'] = null !== $array['repeat_until'] ? new Carbon($array['repeat_until']) : null; $array['repeat_until'] = null !== $array['repeat_until'] ? new Carbon($array['repeat_until']) : null;
$array['journal_count'] = $this->recurring->getJournalCount($recurrence); $array['journal_count'] = $this->repository->getJournalCount($recurrence);
// transform dates back to Carbon objects and expand information // transform dates back to Carbon objects and expand information
foreach ($array['repetitions'] as $index => $repetition) { foreach ($array['repetitions'] as $index => $repetition) {
@@ -106,8 +107,8 @@ class ShowController extends Controller
$date = new Carbon($occurrence)->startOfDay(); $date = new Carbon($occurrence)->startOfDay();
$set = [ $set = [
'date' => $date, 'date' => $date,
'fired' => $this->recurring->createdPreviously($recurrence, $date) 'fired' => $this->repository->createdPreviously($recurrence, $date)
|| $this->recurring->getJournalCount($recurrence, $date) > 0, || $this->repository->getJournalCount($recurrence, $date) > 0,
]; ];
$array['repetitions'][$index]['occurrences'][$item] = $set; $array['repetitions'][$index]['occurrences'][$item] = $set;
} }

View File

@@ -28,6 +28,7 @@ use FireflyIII\Http\Controllers\Controller;
use FireflyIII\Http\Requests\TriggerRecurrenceRequest; use FireflyIII\Http\Requests\TriggerRecurrenceRequest;
use FireflyIII\Jobs\CreateRecurringTransactions; use FireflyIII\Jobs\CreateRecurringTransactions;
use FireflyIII\Models\Recurrence; use FireflyIII\Models\Recurrence;
use FireflyIII\Repositories\Recurring\RecurringRepositoryInterface;
use FireflyIII\Support\Facades\Preferences; use FireflyIII\Support\Facades\Preferences;
use Illuminate\Http\RedirectResponse; use Illuminate\Http\RedirectResponse;
use Illuminate\Support\Collection; use Illuminate\Support\Collection;
@@ -37,6 +38,29 @@ use Illuminate\Support\Collection;
*/ */
class TriggerController extends Controller class TriggerController extends Controller
{ {
private RecurringRepositoryInterface $repository;
/**
* IndexController constructor.
*/
public function __construct()
{
parent::__construct();
app('view')->share('showCategory', true);
// translations:
$this->middleware(
function ($request, $next) {
app('view')->share('mainTitleIcon', 'fa-paint-brush');
app('view')->share('title', (string) trans('firefly.recurrences'));
$this->repository = app(RecurringRepositoryInterface::class);
return $next($request);
}
);
}
public function trigger(Recurrence $recurrence, TriggerRecurrenceRequest $request): RedirectResponse public function trigger(Recurrence $recurrence, TriggerRecurrenceRequest $request): RedirectResponse
{ {
$all = $request->getAll(); $all = $request->getAll();

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