diff --git a/.ci/php-cs-fixer/composer.lock b/.ci/php-cs-fixer/composer.lock index f4677bbe64..76f1d50e00 100644 --- a/.ci/php-cs-fixer/composer.lock +++ b/.ci/php-cs-fixer/composer.lock @@ -72,28 +72,29 @@ }, { "name": "composer/pcre", - "version": "3.3.2", + "version": "3.4.0", "source": { "type": "git", "url": "https://github.com/composer/pcre.git", - "reference": "b2bed4734f0cc156ee1fe9c0da2550420d99a21e" + "reference": "d5a341b3fb61f3001970940afb1d332968a183ed" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/composer/pcre/zipball/b2bed4734f0cc156ee1fe9c0da2550420d99a21e", - "reference": "b2bed4734f0cc156ee1fe9c0da2550420d99a21e", + "url": "https://api.github.com/repos/composer/pcre/zipball/d5a341b3fb61f3001970940afb1d332968a183ed", + "reference": "d5a341b3fb61f3001970940afb1d332968a183ed", "shasum": "" }, "require": { "php": "^7.4 || ^8.0" }, "conflict": { - "phpstan/phpstan": "<1.11.10" + "phpstan/phpstan": "<2.2.2" }, "require-dev": { - "phpstan/phpstan": "^1.12 || ^2", - "phpstan/phpstan-strict-rules": "^1 || ^2", - "phpunit/phpunit": "^8 || ^9" + "phpstan/phpstan": "^2", + "phpstan/phpstan-deprecation-rules": "^2", + "phpstan/phpstan-strict-rules": "^2", + "phpunit/phpunit": "^9" }, "type": "library", "extra": { @@ -131,7 +132,7 @@ ], "support": { "issues": "https://github.com/composer/pcre/issues", - "source": "https://github.com/composer/pcre/tree/3.3.2" + "source": "https://github.com/composer/pcre/tree/3.4.0" }, "funding": [ { @@ -141,13 +142,9 @@ { "url": "https://github.com/composer", "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/composer/composer", - "type": "tidelift" } ], - "time": "2024-11-12T16:29:46+00:00" + "time": "2026-06-07T11:47:49+00:00" }, { "name": "composer/semver", @@ -471,16 +468,16 @@ }, { "name": "friendsofphp/php-cs-fixer", - "version": "v3.95.4", + "version": "v3.95.8", "source": { "type": "git", "url": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer.git", - "reference": "3f8f68856837a77e1f1d870354eca3c8747f2f72" + "reference": "4140023f552ff02346df9b1329742532166f677f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/PHP-CS-Fixer/PHP-CS-Fixer/zipball/3f8f68856837a77e1f1d870354eca3c8747f2f72", - "reference": "3f8f68856837a77e1f1d870354eca3c8747f2f72", + "url": "https://api.github.com/repos/PHP-CS-Fixer/PHP-CS-Fixer/zipball/4140023f552ff02346df9b1329742532166f677f", + "reference": "4140023f552ff02346df9b1329742532166f677f", "shasum": "" }, "require": { @@ -498,7 +495,7 @@ "react/event-loop": "^1.5", "react/socket": "^1.16", "react/stream": "^1.4", - "sebastian/diff": "^4.0.6 || ^5.1.1 || ^6.0.2 || ^7.0 || ^8.0", + "sebastian/diff": "^4.0.6 || ^5.1.1 || ^6.0.2 || ^7.0 || ^8.0 || ^9.0", "symfony/console": "^5.4.47 || ^6.4.24 || ^7.0 || ^8.0", "symfony/event-dispatcher": "^5.4.45 || ^6.4.24 || ^7.0 || ^8.0", "symfony/filesystem": "^5.4.45 || ^6.4.24 || ^7.0 || ^8.0", @@ -514,16 +511,16 @@ "require-dev": { "facile-it/paraunit": "^1.3.1 || ^2.11.0", "infection/infection": "^0.32.7", - "justinrainbow/json-schema": "^6.8.0", + "justinrainbow/json-schema": "^6.9.0", "keradus/cli-executor": "^2.3", "mikey179/vfsstream": "^1.6.12", "php-coveralls/php-coveralls": "^2.9.1", "php-cs-fixer/phpunit-constraint-isidenticalstring": "^1.8", "php-cs-fixer/phpunit-constraint-xmlmatchesxsd": "^1.8", "phpunit/phpunit": "^9.6.34 || ^10.5.63 || ^11.5.55", - "symfony/polyfill-php85": "^1.37", - "symfony/var-dumper": "^5.4.48 || ^6.4.32 || ^7.4.4 || ^8.0.8", - "symfony/yaml": "^5.4.45 || ^6.4.30 || ^7.4.1 || ^8.0.11" + "symfony/polyfill-php85": "^1.38", + "symfony/var-dumper": "^5.4.48 || ^6.4.36 || ^7.4.8 || ^8.1.0", + "symfony/yaml": "^5.4.53 || ^6.4.41 || ^7.4.13 || ^8.1.0" }, "suggest": { "ext-dom": "For handling output formats in XML", @@ -564,7 +561,7 @@ ], "support": { "issues": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/issues", - "source": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/tree/v3.95.4" + "source": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/tree/v3.95.8" }, "funding": [ { @@ -572,7 +569,7 @@ "type": "github" } ], - "time": "2026-06-03T18:02:44+00:00" + "time": "2026-06-16T09:52:26+00:00" }, { "name": "psr/container", @@ -1255,29 +1252,29 @@ }, { "name": "sebastian/diff", - "version": "8.3.0", + "version": "9.0.0", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/diff.git", - "reference": "b36d33b6e796513de7cb7df053afb3f55eefcd47" + "reference": "a3fb6a298a265ff487a91bbea46e03cd01dbb226" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/b36d33b6e796513de7cb7df053afb3f55eefcd47", - "reference": "b36d33b6e796513de7cb7df053afb3f55eefcd47", + "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/a3fb6a298a265ff487a91bbea46e03cd01dbb226", + "reference": "a3fb6a298a265ff487a91bbea46e03cd01dbb226", "shasum": "" }, "require": { "php": ">=8.4" }, "require-dev": { - "phpunit/phpunit": "^13.0", - "symfony/process": "^7.2" + "phpunit/phpunit": "^13.2", + "symfony/process": "^7.4.13" }, "type": "library", "extra": { "branch-alias": { - "dev-main": "8.3-dev" + "dev-main": "9.0-dev" } }, "autoload": { @@ -1310,7 +1307,7 @@ "support": { "issues": "https://github.com/sebastianbergmann/diff/issues", "security": "https://github.com/sebastianbergmann/diff/security/policy", - "source": "https://github.com/sebastianbergmann/diff/tree/8.3.0" + "source": "https://github.com/sebastianbergmann/diff/tree/9.0.0" }, "funding": [ { @@ -1330,7 +1327,7 @@ "type": "tidelift" } ], - "time": "2026-05-15T04:58:09+00:00" + "time": "2026-06-05T03:04:51+00:00" }, { "name": "symfony/console", @@ -2131,16 +2128,16 @@ }, { "name": "symfony/polyfill-mbstring", - "version": "v1.38.1", + "version": "v1.38.2", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-mbstring.git", - "reference": "14c5439eec4ccff081ac14eca2dc57feb2a66d92" + "reference": "d3d318bad5e7a1bfbd026009c8bfb8d8f99ae6b6" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/14c5439eec4ccff081ac14eca2dc57feb2a66d92", - "reference": "14c5439eec4ccff081ac14eca2dc57feb2a66d92", + "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/d3d318bad5e7a1bfbd026009c8bfb8d8f99ae6b6", + "reference": "d3d318bad5e7a1bfbd026009c8bfb8d8f99ae6b6", "shasum": "" }, "require": { @@ -2192,7 +2189,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-mbstring/tree/v1.38.1" + "source": "https://github.com/symfony/polyfill-mbstring/tree/v1.38.2" }, "funding": [ { @@ -2212,7 +2209,7 @@ "type": "tidelift" } ], - "time": "2026-05-26T12:51:13+00:00" + "time": "2026-05-27T06:59:30+00:00" }, { "name": "symfony/polyfill-php80", diff --git a/app/Api/V1/Controllers/Insight/Income/TagController.php b/app/Api/V1/Controllers/Insight/Income/TagController.php index df99eef909..94be2ae461 100644 --- a/app/Api/V1/Controllers/Insight/Income/TagController.php +++ b/app/Api/V1/Controllers/Insight/Income/TagController.php @@ -158,7 +158,10 @@ final class TagController extends Controller 'currency_id' => (string) $foreignCurrencyId, 'currency_code' => $journal['foreign_currency_code'], ]; - $response[$foreignKey]['difference'] = bcadd((string) $response[$foreignKey]['difference'], Steam::positive($journal['foreign_amount'])); + $response[$foreignKey]['difference'] = bcadd( + (string) $response[$foreignKey]['difference'], + Steam::positive($journal['foreign_amount']) + ); $response[$foreignKey]['difference_float'] = (float) $response[$foreignKey]['difference']; } } diff --git a/app/Api/V1/Controllers/Insight/Transfer/TagController.php b/app/Api/V1/Controllers/Insight/Transfer/TagController.php index f92a7aa9f0..b7b85fd376 100644 --- a/app/Api/V1/Controllers/Insight/Transfer/TagController.php +++ b/app/Api/V1/Controllers/Insight/Transfer/TagController.php @@ -155,7 +155,10 @@ final class TagController extends Controller 'currency_id' => (string) $foreignCurrencyId, 'currency_code' => $journal['foreign_currency_code'], ]; - $response[$foreignKey]['difference'] = bcadd((string) $response[$foreignKey]['difference'], Steam::positive($journal['foreign_amount'])); + $response[$foreignKey]['difference'] = bcadd( + (string) $response[$foreignKey]['difference'], + Steam::positive($journal['foreign_amount']) + ); $response[$foreignKey]['difference_float'] = (float) $response[$foreignKey]['difference']; // intentional float } } diff --git a/app/Helpers/Functions/helpers.php b/app/Helpers/Functions/helpers.php index 7493feac55..67b220e23d 100644 --- a/app/Helpers/Functions/helpers.php +++ b/app/Helpers/Functions/helpers.php @@ -25,7 +25,6 @@ declare(strict_types=1); use Carbon\Carbon; use FireflyIII\Exceptions\FireflyException; use FireflyIII\Models\Account; -use FireflyIII\Models\Configuration; use FireflyIII\Repositories\Account\AccountRepositoryInterface; use FireflyIII\Support\Facades\Amount; use FireflyIII\Support\Facades\AppConfiguration; @@ -34,6 +33,7 @@ use FireflyIII\Support\Search\OperatorQuerySearch; use Illuminate\Support\Collection; use Illuminate\Support\Facades\Log; use League\CommonMark\GithubFlavoredMarkdownConverter; + use function Safe\mb_ord; use function Safe\preg_match; use function Safe\preg_replace_callback; @@ -42,7 +42,7 @@ if (!function_exists('env_default_when_empty')) { /** * @return null|mixed */ - function env_default_when_empty(mixed $value, bool | int | string | null $default = null): mixed + function env_default_when_empty(mixed $value, bool|int|string|null $default = null): mixed { if (null === $value) { return $default; @@ -55,24 +55,27 @@ if (!function_exists('env_default_when_empty')) { } } -if(!function_exists('parse_markdown')) { - function parse_markdown(string $string): string { +if (!function_exists('parse_markdown')) { + function parse_markdown(string $string): string + { $converter = new GithubFlavoredMarkdownConverter(['allow_unsafe_links' => false, 'max_nesting_level' => 5, 'html_input' => 'escape']); return (string) $converter->convert($string); } } -if(!function_exists('get_root_search_operator')) { - function get_root_search_operator(string $operator): string { +if (!function_exists('get_root_search_operator')) { + function get_root_search_operator(string $operator): string + { $result = OperatorQuerySearch::getRootOperator($operator); return str_replace('-', 'not_', $result); } } -if(!function_exists('get_app_configuration')) { - function get_app_configuration(string $name, mixed $default = null): mixed { +if (!function_exists('get_app_configuration')) { + function get_app_configuration(string $name, mixed $default = null): mixed + { try { return AppConfiguration::get($name, $default)?->data; } catch (FireflyException) { @@ -81,7 +84,7 @@ if(!function_exists('get_app_configuration')) { } } -if(!function_exists('format_amount_by_symbol')) { +if (!function_exists('format_amount_by_symbol')) { function format_amount_by_symbol(string $amount, ?string $symbol = null, ?int $decimalPlaces = null, ?bool $coloured = null): string { return Steam::formatAmountBySymbol($amount, $symbol, $decimalPlaces, $coloured); @@ -97,20 +100,20 @@ if (!function_exists('account_get_meta_field')) { if (null === $result) { return ''; } + return $result; } } - if (!function_exists('account_balance')) { - function account_balance(\FireflyIII\Models\Account $account): string + function account_balance(Account $account): string { /** @var Carbon $date */ - $date = now(); + $date = now(); // get the date from the current session. If it's in the future, keep `now()`. /** @var Carbon $session */ - $session = clone session('end', today(config('app.timezone'))->endOfMonth()); + $session = clone session('end', today(config('app.timezone'))->endOfMonth()); if ($session->lt($date)) { $date = $session->copy(); $date->endOfDay(); @@ -118,13 +121,13 @@ if (!function_exists('account_balance')) { Log::debug(sprintf('twig balance: Call finalAccountBalance with date/time "%s"', $date->toIso8601String())); // 2025-10-08 replace finalAccountBalance with accountsBalancesOptimized. - $info = Steam::accountsBalancesOptimized(new Collection()->push($account), $date)[$account->id]; + $info = Steam::accountsBalancesOptimized(new Collection()->push($account), $date)[$account->id]; // $info = Steam::finalAccountBalance($account, $date); $currency = Steam::getAccountCurrency($account); $primary = Amount::getPrimaryCurrency(); $convertToPrimary = Amount::convertToPrimary(); $usePrimary = $convertToPrimary && $primary->id !== $currency->id; - $currency ??= $primary; + $currency ??= $primary; $strings = []; foreach ($info as $key => $balance) { if ('balance' === $key) { @@ -150,7 +153,6 @@ if (!function_exists('account_balance')) { } return implode(', ', $strings); - } } @@ -173,14 +175,14 @@ if (!function_exists('blade_escape_js')) { return preg_replace_callback( '#[^a-zA-Z0-9,\._]#Su', static function ($matches) { - $char = $matches[0]; + $char = $matches[0]; /* * A few characters have short escape sequences in JSON and JavaScript. * Escape sequences supported only by JavaScript, not JSON, are omitted. * \" is also supported but omitted, because the resulting string is not HTML safe. */ - $short = match ($char) { + $short = match ($char) { '\\' => '\\\\', '/' => '\/', "\x08" => '\b', @@ -202,9 +204,9 @@ if (!function_exists('blade_escape_js')) { // Split characters outside the BMP into surrogate pairs // https://tools.ietf.org/html/rfc2781.html#section-2.1 - $u = $codepoint - 0x10_000; - $high = 0xD800 | ($u >> 10); - $low = 0xDC00 | ($u & 0x3FF); + $u = $codepoint - 0x10_000; + $high = 0xD800 | ($u >> 10); + $low = 0xDC00 | ($u & 0x3FF); return \sprintf('\u%04X\u%04X', $high, $low); }, diff --git a/app/Http/Controllers/Account/IndexController.php b/app/Http/Controllers/Account/IndexController.php index bd325252f1..4efe3eee2f 100644 --- a/app/Http/Controllers/Account/IndexController.php +++ b/app/Http/Controllers/Account/IndexController.php @@ -115,13 +115,13 @@ final class IndexController extends Controller $accounts->setPath(route('accounts.inactive.index', [$objectType])); return view('accounts.index', [ - 'objectType' => $objectType, - 'inactivePage' => $inactivePage, + 'objectType' => $objectType, + 'inactivePage' => $inactivePage, 'inactiveCount' => $inactiveCount, - 'subTitleIcon' => $subTitleIcon, - 'subTitle' => $subTitle, - 'page' => $page, - 'accounts' => $accounts, + 'subTitleIcon' => $subTitleIcon, + 'subTitle' => $subTitle, + 'page' => $page, + 'accounts' => $accounts, ]); } @@ -201,7 +201,7 @@ final class IndexController extends Controller return view('accounts.index', [ 'objectType' => $objectType, 'inactiveCount' => $inactiveCount, - 'inactivePage' => $inactivePage, + 'inactivePage' => $inactivePage, 'subTitleIcon' => $subTitleIcon, 'subTitle' => $subTitle, 'page' => $page, diff --git a/app/Http/Controllers/Bill/IndexController.php b/app/Http/Controllers/Bill/IndexController.php index 2009369ae0..07947c2c85 100644 --- a/app/Http/Controllers/Bill/IndexController.php +++ b/app/Http/Controllers/Bill/IndexController.php @@ -255,7 +255,10 @@ final class IndexController extends Controller if (count($bill['paid_dates']) < count($bill['pay_dates'])) { $count = count($bill['pay_dates']) - count($bill['paid_dates']); if ($count > 0) { - $avg = bcdiv(bcadd((string) $bill['amount_min'], (string) $bill['amount_max']), '2'); + $avg = bcdiv( + bcadd((string) $bill['amount_min'], (string) $bill['amount_max']), + '2' + ); $avg = bcmul($avg, (string) $count); $sums[$groupOrder][$currencyId]['total_left_to_pay'] = bcadd($sums[$groupOrder][$currencyId]['total_left_to_pay'], $avg); Log::debug( diff --git a/app/Http/Controllers/Budget/BudgetLimitController.php b/app/Http/Controllers/Budget/BudgetLimitController.php index 9632996690..b263d702a2 100644 --- a/app/Http/Controllers/Budget/BudgetLimitController.php +++ b/app/Http/Controllers/Budget/BudgetLimitController.php @@ -198,7 +198,13 @@ final class BudgetLimitController extends Controller if ($request->expectsJson()) { $array = $limit->toArray(); // add some extra metadata: - $spentArr = $this->opsRepository->sumExpenses($limit->start_date, $limit->end_date, null, new Collection()->push($budget), $currency); + $spentArr = $this->opsRepository->sumExpenses( + $limit->start_date, + $limit->end_date, + null, + new Collection()->push($budget), + $currency + ); $array['spent'] = $spentArr[$currency->id]['sum'] ?? '0'; $array['left_formatted'] = Amount::formatAnything($limit->transactionCurrency, bcadd($array['spent'], (string) $array['amount'])); $array['amount_formatted'] = Amount::formatAnything($limit->transactionCurrency, $limit['amount']); diff --git a/app/Http/Controllers/Budget/IndexController.php b/app/Http/Controllers/Budget/IndexController.php index 507187db73..b52cd75abf 100644 --- a/app/Http/Controllers/Budget/IndexController.php +++ b/app/Http/Controllers/Budget/IndexController.php @@ -284,7 +284,10 @@ final class IndexController extends Controller if (array_key_exists($currency->id, $spentArr) && array_key_exists('sum', $spentArr[$currency->id])) { $array['spent'][$currency->id]['spent'] = $spentArr[$currency->id]['sum']; - $array['spent'][$currency->id]['spent_outside'] = Steam::negative(bcsub($spentInLimits[$currency->id], $spentArr[$currency->id]['sum'])); + $array['spent'][$currency->id]['spent_outside'] = Steam::negative(bcsub( + $spentInLimits[$currency->id], + $spentArr[$currency->id]['sum'] + )); $array['spent'][$currency->id]['currency_id'] = $currency->id; $array['spent'][$currency->id]['currency_symbol'] = $currency->symbol; $array['spent'][$currency->id]['currency_decimal_places'] = $currency->decimal_places; diff --git a/app/Http/Controllers/Chart/BudgetController.php b/app/Http/Controllers/Chart/BudgetController.php index ad724137dc..f4b32fe5c5 100644 --- a/app/Http/Controllers/Chart/BudgetController.php +++ b/app/Http/Controllers/Chart/BudgetController.php @@ -539,7 +539,13 @@ final class BudgetController extends Controller } // get spent amount in this period for this currency. - $sum = $this->opsRepository->sumExpenses($currentStart, $currentEnd, $accounts, new Collection()->push($budget), $currency); + $sum = $this->opsRepository->sumExpenses( + $currentStart, + $currentEnd, + $accounts, + new Collection()->push($budget), + $currency + ); $amount = Steam::positive($sum[$currency->id]['sum'] ?? '0'); $chartData[0]['entries'][$title] = Steam::bcround($amount, $currency->decimal_places); diff --git a/app/Http/Controllers/HomeController.php b/app/Http/Controllers/HomeController.php index e67bdb6bc5..6cbe625b3b 100644 --- a/app/Http/Controllers/HomeController.php +++ b/app/Http/Controllers/HomeController.php @@ -107,18 +107,17 @@ final class HomeController extends Controller $request->session()->flash('warning', (string) trans('firefly.warning_much_data', ['days' => (int) $diff])); } - $request->session()->put('is_custom_range', $isCustomRange); Log::debug(sprintf('Set is_custom_range to %s', var_export($isCustomRange, return: true))); $request->session()->put('start', $start); Log::debug(sprintf('Set start to %s', $start->format('Y-m-d H:i:s'))); $request->session()->put('end', $end); Log::debug(sprintf('Set end to %s', $end->format('Y-m-d H:i:s'))); - if('true' === $request->input('redirect')) { + if ('true' === $request->input('redirect')) { return redirect(route('home')); } - return response()->json(['ok' => 'ok']); + return response()->json(['ok' => 'ok']); } /** @@ -135,6 +134,7 @@ final class HomeController extends Controller if (0 === $count) { return redirect(route('new-user.index')); } + // ignore v2. return $this->indexV1($repository); } @@ -145,7 +145,7 @@ final class HomeController extends Controller $pageTitle = (string) trans('firefly.main_dashboard_page_title'); $count = $repository->count($types); $subTitle = (string) trans('firefly.welcome_back'); - $subTitleIcon = 'bi-piggy-bank'; + $subTitleIcon = 'bi-piggy-bank'; $transactions = []; $frontpage = Preferences::getFresh('frontpageAccounts', $repository->getAccountsByType([AccountTypeEnum::ASSET->value])->pluck('id')->toArray()); $frontpageArray = $frontpage->data; @@ -192,5 +192,4 @@ final class HomeController extends Controller 'pageTitle' => $pageTitle, ]); } - } diff --git a/app/Http/Controllers/Transaction/IndexController.php b/app/Http/Controllers/Transaction/IndexController.php index f6fd768f30..e09f0d3025 100644 --- a/app/Http/Controllers/Transaction/IndexController.php +++ b/app/Http/Controllers/Transaction/IndexController.php @@ -111,6 +111,7 @@ final class IndexController extends Controller } $periods = $this->getTransactionPeriodOverview($objectType, $startPeriod, $endPeriod); + /** @var GroupCollectorInterface $collector */ $collector = app(GroupCollectorInterface::class); diff --git a/app/Jobs/CreateAutoBudgetLimits.php b/app/Jobs/CreateAutoBudgetLimits.php index 93cf5e9364..d61661dd50 100644 --- a/app/Jobs/CreateAutoBudgetLimits.php +++ b/app/Jobs/CreateAutoBudgetLimits.php @@ -122,7 +122,13 @@ class CreateAutoBudgetLimits implements ShouldQueue // if has one, calculate expenses and use that as a base. $repository = app(OperationsRepositoryInterface::class); $repository->setUser($autoBudget->budget->user); - $spent = $repository->sumExpenses($previousStart, $previousEnd, null, new Collection()->push($autoBudget->budget), $autoBudget->transactionCurrency); + $spent = $repository->sumExpenses( + $previousStart, + $previousEnd, + null, + new Collection()->push($autoBudget->budget), + $autoBudget->transactionCurrency + ); $currencyId = $autoBudget->transaction_currency_id; $spentAmount = $spent[$currencyId]['sum'] ?? '0'; Log::debug(sprintf('Spent in previous budget period (%s-%s) is %s', $previousStart->format('Y-m-d'), $previousEnd->format('Y-m-d'), $spentAmount)); @@ -212,7 +218,13 @@ class CreateAutoBudgetLimits implements ShouldQueue // if has one, calculate expenses and use that as a base. $repository = app(OperationsRepositoryInterface::class); $repository->setUser($autoBudget->budget->user); - $spent = $repository->sumExpenses($previousStart, $previousEnd, null, new Collection()->push($autoBudget->budget), $autoBudget->transactionCurrency); + $spent = $repository->sumExpenses( + $previousStart, + $previousEnd, + null, + new Collection()->push($autoBudget->budget), + $autoBudget->transactionCurrency + ); $currencyId = $autoBudget->transaction_currency_id; $spentAmount = $spent[$currencyId]['sum'] ?? '0'; Log::debug(sprintf('Spent in previous budget period (%s-%s) is %s', $previousStart->format('Y-m-d'), $previousEnd->format('Y-m-d'), $spentAmount)); diff --git a/app/Listeners/Model/TransactionGroup/ProcessesUpdatedTransactionGroup.php b/app/Listeners/Model/TransactionGroup/ProcessesUpdatedTransactionGroup.php index e912dc705b..009e1c9ca3 100644 --- a/app/Listeners/Model/TransactionGroup/ProcessesUpdatedTransactionGroup.php +++ b/app/Listeners/Model/TransactionGroup/ProcessesUpdatedTransactionGroup.php @@ -118,17 +118,19 @@ class ProcessesUpdatedTransactionGroup $all = $group->transactionJournals()->get()->pluck('id')->toArray(); - /** @var Account|null $sourceAccount */ + /** @var null|Account $sourceAccount */ $sourceAccount = $first->transactions()->where('amount', '<', '0')->first()?->account; - /** @var Account|null $destAccount */ + /** @var null|Account $destAccount */ $destAccount = $first->transactions()->where('amount', '>', '0')->first()?->account; - if(null === $destAccount) { + if (null === $destAccount) { Log::warning(sprintf('Group #%d (journal #%d) has no destination account. Break.', $group->id, $first->id)); + return 0; } - if(null === $sourceAccount) { + if (null === $sourceAccount) { Log::warning(sprintf('Group #%d (journal #%d) has no source account. Break.', $group->id, $first->id)); + return 0; } diff --git a/app/Models/InvitedUser.php b/app/Models/InvitedUser.php index c6eda69916..1a577fc7ca 100644 --- a/app/Models/InvitedUser.php +++ b/app/Models/InvitedUser.php @@ -32,7 +32,6 @@ use FireflyIII\User; use Illuminate\Auth\AuthenticationException; use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\Relations\BelongsTo; -use Symfony\Component\HttpKernel\Exception\NotFoundHttpException; /** * @property Carbon $expires diff --git a/app/Models/TransactionGroup.php b/app/Models/TransactionGroup.php index 4ee22788c4..a3528313a1 100644 --- a/app/Models/TransactionGroup.php +++ b/app/Models/TransactionGroup.php @@ -81,6 +81,7 @@ class TransactionGroup extends Model return $group; } + throw new NotFoundHttpException(); } Log::debug('Found no group.'); diff --git a/app/Providers/AppServiceProvider.php b/app/Providers/AppServiceProvider.php index 0621840d6d..000f9b6f04 100644 --- a/app/Providers/AppServiceProvider.php +++ b/app/Providers/AppServiceProvider.php @@ -24,7 +24,6 @@ declare(strict_types=1); namespace FireflyIII\Providers; use FireflyIII\Models\Account; -use FireflyIII\Repositories\Account\AccountRepositoryInterface; use Illuminate\Support\Facades\Blade; use Illuminate\Support\Facades\Log; use Illuminate\Support\Facades\Response; @@ -33,6 +32,7 @@ use Illuminate\Support\Facades\Schema; use Illuminate\Support\ServiceProvider; use Laravel\Passport\Passport; use Override; + use function Safe\preg_match; /** @@ -52,7 +52,7 @@ class AppServiceProvider extends ServiceProvider Response::macro('api', function (array $value) { $headers = ['Cache-Control' => 'no-store']; - $uuid = (string)request()->header('X-Trace-Id'); + $uuid = (string) request()->header('X-Trace-Id'); if ('' !== trim($uuid) && 1 === preg_match('/^[a-f\d]{8}(-[a-f\d]{4}){4}[a-f\d]{8}$/i', trim($uuid))) { $headers['X-Trace-Id'] = $uuid; } @@ -60,35 +60,33 @@ class AppServiceProvider extends ServiceProvider return response()->json($value)->withHeaders($headers); }); + // // blade extension for active top menu sub menu (like "accounts") + // // TODO DO NOT USE ME + // Blade::directive('menuSubActive', function (string $route): string { + // $route = trim($route, "'"); + // $name = Route::getCurrentRoute()->getName() ?? ''; + // Log::debug(sprintf('menuSubActive("%s", "%s")', $route, $name)); + // if (str_contains($name, $route)) { + // return 'menu-open'; + // } + // + // return ''; + // }); -// // blade extension for active top menu sub menu (like "accounts") -// // TODO DO NOT USE ME -// Blade::directive('menuSubActive', function (string $route): string { -// $route = trim($route, "'"); -// $name = Route::getCurrentRoute()->getName() ?? ''; -// Log::debug(sprintf('menuSubActive("%s", "%s")', $route, $name)); -// if (str_contains($name, $route)) { -// return 'menu-open'; -// } -// -// return ''; -// }); + // // blade extension for active top menu sub menu item (like "accounts" => "asset accounts) + // // TODO DO NOT USE ME + // Blade::directive('menuSubItemActive', function (string $routeAndType): string { + // + // }); -// // blade extension for active top menu sub menu item (like "accounts" => "asset accounts) -// // TODO DO NOT USE ME -// Blade::directive('menuSubItemActive', function (string $routeAndType): string { -// -// }); - - -// // TODO @deprecated -// // blade extension for account balance. -// Blade::directive('balance', function (string $account): string { -// var_dump($account); -// exit; -// return $account; -// return 'blablabla'; -// }); + // // TODO @deprecated + // // blade extension for account balance. + // Blade::directive('balance', function (string $account): string { + // var_dump($account); + // exit; + // return $account; + // return 'blablabla'; + // }); // TODO @deprecated // blade extension @@ -101,14 +99,14 @@ class AppServiceProvider extends ServiceProvider return ''; }); Blade::if('partialroute', function (string $route, string $firstParam = ''): bool { - $name = Route::getCurrentRoute()->getName() ?? ''; + $name = Route::getCurrentRoute()->getName() ?? ''; if ('' === $firstParam && str_contains($name, $route)) { return true; } /** @var null|array $params */ $params = Route::getCurrentRoute()->parameters(); - $params ??= []; + $params ??= []; $objectType = $params['objectType'] ?? ''; return $objectType === $firstParam && str_contains($name, $route); diff --git a/app/Services/Internal/Update/JournalUpdateService.php b/app/Services/Internal/Update/JournalUpdateService.php index d22006e69e..1165d2fa5a 100644 --- a/app/Services/Internal/Update/JournalUpdateService.php +++ b/app/Services/Internal/Update/JournalUpdateService.php @@ -213,8 +213,11 @@ class JournalUpdateService $result = $this->transactionJournal->transactions()->where('amount', '>', 0)->first(); $this->destinationTransaction = $result; } - if(null === $this->destinationTransaction) { - throw new FireflyException(sprintf('Destination transaction for transaction group #%d could not be found.', $this->transactionGroup->transaction_group_id ?? 0)); + if (null === $this->destinationTransaction) { + throw new FireflyException(sprintf( + 'Destination transaction for transaction group #%d could not be found.', + $this->transactionGroup->transaction_group_id ?? 0 + )); } return $this->destinationTransaction; diff --git a/app/Support/Blade/Navigation.php b/app/Support/Blade/Navigation.php index 1bdcda8dcc..5795b5cdfe 100644 --- a/app/Support/Blade/Navigation.php +++ b/app/Support/Blade/Navigation.php @@ -1,4 +1,7 @@ getName() ?? ''; Log::debug(sprintf('menuItemActive("%s" = "%s")', $route, $name)); if ($name === $route) { @@ -35,7 +39,9 @@ class Navigation return ''; } - public static function menuItemActivePartial(string $route): string { + + public static function menuItemActivePartial(string $route): string + { $name = Route::getCurrentRoute()->getName() ?? ''; Log::debug(sprintf('menuItemActivePartial("%s" starts with "%s")', $name, $route)); if (str_starts_with($name, $route)) { @@ -45,17 +51,8 @@ class Navigation return ''; } - public static function menuSubItemActive(string $route, string $objectType): string { - $name = Route::getCurrentRoute()->getName() ?? ''; - Log::debug(sprintf('menuSubItemActive("%s" = "%s","%s" = "%s")', $route, $name, $objectType, Route::getCurrentRoute()->parameter('objectType'))); - if ($name === $route && $objectType === Route::getCurrentRoute()->parameter('objectType')) { - return 'active'; - } - - return ''; - } - - public static function menuOpenPartial(string $route): string { + public static function menuOpenPartial(string $route): string + { $name = Route::getCurrentRoute()->getName() ?? ''; Log::debug(sprintf('menuOpenPartial("%s" starts with "%s")', $name, $route)); if (str_starts_with($name, $route)) { @@ -64,4 +61,15 @@ class Navigation return ''; } + + public static function menuSubItemActive(string $route, string $objectType): string + { + $name = Route::getCurrentRoute()->getName() ?? ''; + Log::debug(sprintf('menuSubItemActive("%s" = "%s","%s" = "%s")', $route, $name, $objectType, Route::getCurrentRoute()->parameter('objectType'))); + if ($name === $route && $objectType === Route::getCurrentRoute()->parameter('objectType')) { + return 'active'; + } + + return ''; + } } diff --git a/app/Support/Http/Controllers/AugumentData.php b/app/Support/Http/Controllers/AugumentData.php index a3a940b1ba..a507156873 100644 --- a/app/Support/Http/Controllers/AugumentData.php +++ b/app/Support/Http/Controllers/AugumentData.php @@ -222,7 +222,14 @@ trait AugumentData $currentEnd->addMonth(); } // primary currency amount. - $expenses = $opsRepository->sumExpenses($currentStart, $currentEnd, null, $budgetCollection, $entry->transactionCurrency, $this->convertToPrimary); + $expenses = $opsRepository->sumExpenses( + $currentStart, + $currentEnd, + null, + $budgetCollection, + $entry->transactionCurrency, + $this->convertToPrimary + ); $spent = $expenses[$currency->id]['sum'] ?? '0'; $entry->pc_spent = $spent; diff --git a/app/Support/Http/Controllers/GetConfigurationData.php b/app/Support/Http/Controllers/GetConfigurationData.php index 6428c307e2..b0fdfc1358 100644 --- a/app/Support/Http/Controllers/GetConfigurationData.php +++ b/app/Support/Http/Controllers/GetConfigurationData.php @@ -62,13 +62,13 @@ trait GetConfigurationData $steps = []; if (is_array($elements) && count($elements) > 0) { foreach ($elements as $key => $options) { - $currentStep = $options; + $currentStep = $options; // get the text: $currentStep['text'] = (string) trans('intro.'.$route.'_'.$key); // save in array: - $steps[] = $currentStep; + $steps[] = $currentStep; } } Log::debug(sprintf('Total basic steps for %s is %d', $routeKey, count($steps))); @@ -195,13 +195,13 @@ trait GetConfigurationData $elements = config(sprintf('intro.%s', $routeKey.'_'.$specificPage)); if (is_array($elements) && count($elements) > 0) { foreach ($elements as $key => $options) { - $currentStep = $options; + $currentStep = $options; // get the text: $currentStep['text'] = (string) trans('intro.'.$route.'_'.$specificPage.'_'.$key); // save in array: - $steps[] = $currentStep; + $steps[] = $currentStep; } } } diff --git a/app/Support/Http/Controllers/PeriodOverview.php b/app/Support/Http/Controllers/PeriodOverview.php index 9fe656b6af..d005212338 100644 --- a/app/Support/Http/Controllers/PeriodOverview.php +++ b/app/Support/Http/Controllers/PeriodOverview.php @@ -155,7 +155,7 @@ trait PeriodOverview 'revenue' => 'earned', 'transfer' => 'transferred', 'transfers' => 'transferred', - 'all' => 'all', + 'all' => 'all', ]; if (!array_key_exists($type, $setTypes)) { throw new FireflyException(sprintf('[c] Cannot deal with type "%s"', $type)); diff --git a/app/Support/JsonApi/Enrichments/RecurringEnrichment.php b/app/Support/JsonApi/Enrichments/RecurringEnrichment.php index d0c09bf027..2428353cb0 100644 --- a/app/Support/JsonApi/Enrichments/RecurringEnrichment.php +++ b/app/Support/JsonApi/Enrichments/RecurringEnrichment.php @@ -354,7 +354,11 @@ class RecurringEnrichment implements EnrichmentInterface /** @var RecurrenceRepetition $repetition */ foreach ($set as $repetition) { - $recurrence = $this->collection->filter(static fn (Recurrence $item): bool => (int) $item->id === (int) $repetition->recurrence_id)->first(); + $recurrence = $this->collection->filter( + static fn (Recurrence $item): bool => (int) $item->id === (int) $repetition->recurrence_id + ) + ->first() + ; $fromDate = clone ($recurrence->latest_date ?? $recurrence->first_date); $recurrenceId = (int) $repetition->recurrence_id; $repId = (int) $repetition->id; diff --git a/app/Support/Steam.php b/app/Support/Steam.php index f95a6fea35..2ec70d6535 100644 --- a/app/Support/Steam.php +++ b/app/Support/Steam.php @@ -43,6 +43,7 @@ use Psr\Container\ContainerExceptionInterface; use Psr\Container\NotFoundExceptionInterface; use Safe\Exceptions\UrlException; use ValueError; + use function Safe\parse_url; use function Safe\preg_replace; @@ -56,13 +57,12 @@ class Steam * properly gets the balance of a range. */ public function accountsBalancesInRange( - Collection $accounts, - Carbon $start, - Carbon $end, + Collection $accounts, + Carbon $start, + Carbon $end, ?TransactionCurrency $primary = null, - ?bool $convertToPrimary = null - ): array - { + ?bool $convertToPrimary = null + ): array { return [ $this->accountsBalancesOptimized($accounts, $start, $primary, $convertToPrimary, inclusive: false), $this->accountsBalancesOptimized($accounts, $end, $primary, $convertToPrimary), @@ -70,54 +70,54 @@ class Steam } public function accountsBalancesOptimized( - Collection $accounts, - Carbon $date, + Collection $accounts, + Carbon $date, ?TransactionCurrency $primary = null, - ?bool $convertToPrimary = null, - bool $inclusive = true - ): array - { + ?bool $convertToPrimary = null, + bool $inclusive = true + ): array { // Log::debug(sprintf('accountsBalancesOptimized: Called for %d account(s) with date/time "%s" (inclusive: %s)', $accounts->count(), $date->toIso8601String(), var_export($inclusive, true))); - $result = []; + $result = []; $convertToPrimary ??= Amount::convertToPrimary(); $primary ??= Amount::getPrimaryCurrency(); - $currencies = $this->getCurrencies($accounts); + $currencies = $this->getCurrencies($accounts); // balance(s) in all currencies for ALL accounts. $arrayOfSums = Transaction::query() - ->whereIn('account_id', $accounts->pluck('id')->toArray()) - ->leftJoin('transaction_journals', 'transaction_journals.id', '=', 'transactions.transaction_journal_id') - ->leftJoin('transaction_currencies', 'transaction_currencies.id', '=', 'transactions.transaction_currency_id') - ->where('transaction_journals.date', $inclusive ? '<=' : '<', $date->format('Y-m-d H:i:s')) - ->whereNull('transaction_journals.deleted_at') - ->groupBy(['transactions.account_id', 'transaction_currencies.code']) - ->get(['transactions.account_id', 'transaction_currencies.code', DB::raw('SUM(transactions.amount) as sum_of_amount')]) - ->toArray(); + ->whereIn('account_id', $accounts->pluck('id')->toArray()) + ->leftJoin('transaction_journals', 'transaction_journals.id', '=', 'transactions.transaction_journal_id') + ->leftJoin('transaction_currencies', 'transaction_currencies.id', '=', 'transactions.transaction_currency_id') + ->where('transaction_journals.date', $inclusive ? '<=' : '<', $date->format('Y-m-d H:i:s')) + ->whereNull('transaction_journals.deleted_at') + ->groupBy(['transactions.account_id', 'transaction_currencies.code']) + ->get(['transactions.account_id', 'transaction_currencies.code', DB::raw('SUM(transactions.amount) as sum_of_amount')]) + ->toArray() + ; // Log::debug('Array of sums: ', $arrayOfSums); /** @var Account $account */ foreach ($accounts as $account) { - $return = ['pc_balance' => '0', 'balance' => '0']; // this key is overwritten right away, but I must remember it is always created. - $currency = $currencies[$account->id]; + $return = ['pc_balance' => '0', 'balance' => '0']; // this key is overwritten right away, but I must remember it is always created. + $currency = $currencies[$account->id]; // second array - $accountSums = array_filter($arrayOfSums, static fn(array $entry): bool => $entry['account_id'] === $account->id); + $accountSums = array_filter($arrayOfSums, static fn (array $entry): bool => $entry['account_id'] === $account->id); if (0 === count($accountSums)) { $result[$account->id] = $return; continue; } - $sumsByCode = []; + $sumsByCode = []; foreach ($accountSums as $accountSum) { // $accountSum = array_values($accountSum)[0]; - $sumOfAmount = (string)$accountSum['sum_of_amount']; + $sumOfAmount = (string) $accountSum['sum_of_amount']; $sumOfAmount = $this->floatalize('' === $sumOfAmount ? '0' : $sumOfAmount); $sumsByCode[$accountSum['code']] = $sumOfAmount; } // Log::debug('All balances are (joined)', $others); // if there is no request to convert, take this as "balance" and "pc_balance". - $return['balance'] = $sumsByCode[$currency->code] ?? '0'; + $return['balance'] = $sumsByCode[$currency->code] ?? '0'; if (!$convertToPrimary) { unset($return['pc_balance']); @@ -132,7 +132,7 @@ class Steam } // either way, the balance is always combined with the virtual balance: - $virtualBalance = (string)('' === (string)$account->virtual_balance ? '0' : $account->virtual_balance); + $virtualBalance = (string) ('' === (string) $account->virtual_balance ? '0' : $account->virtual_balance); if ($convertToPrimary) { // the primary currency balance is combined with a converted virtual_balance: @@ -189,10 +189,10 @@ class Steam // Log::debug(sprintf('Trying bcround("%s",%d)', $number, $precision)); if (str_contains($number, '.')) { if ('-' !== $number[0]) { - return bcadd($number, '0.' . str_repeat('0', $precision) . '5', $precision); + return bcadd($number, '0.'.str_repeat('0', $precision).'5', $precision); } - return bcsub($number, '0.' . str_repeat('0', $precision) . '5', $precision); + return bcsub($number, '0.'.str_repeat('0', $precision).'5', $precision); } return $number; @@ -334,17 +334,15 @@ class Steam "balance": balance in the account's currency OR user's primary currency if the account has no currency --> "pc_balance": balance in the user's primary currency, with all amounts converted to the primary currency. "EUR": balance in EUR (or whatever currencies the account has balance in) - TXT - )] + TXT)] public function finalAccountBalance( - Account $account, - Carbon $date, + Account $account, + Carbon $date, ?TransactionCurrency $primary = null, - ?bool $convertToPrimary = null, - bool $inclusive = true - ): array - { - $cache = new CacheProperties(); + ?bool $convertToPrimary = null, + bool $inclusive = true + ): array { + $cache = new CacheProperties(); $cache->addProperty($account->id); $cache->addProperty($date); if ($cache->has()) { @@ -360,25 +358,26 @@ class Steam $primary = Amount::getPrimaryCurrencyByUserGroup($account->user->userGroup); } // account balance thing. - $currencyPresent = property_exists($account, 'meta') && array_key_exists('currency', $account->meta) && null !== $account->meta['currency']; + $currencyPresent = property_exists($account, 'meta') && array_key_exists('currency', $account->meta) && null !== $account->meta['currency']; if ($currencyPresent) { $accountCurrency = $account->meta['currency']; } if (!$currencyPresent) { $accountCurrency = $this->getAccountCurrency($account); } - $hasCurrency = null !== $accountCurrency; - $currency = $hasCurrency ? $accountCurrency : $primary; - $return = ['pc_balance' => '0', 'balance' => '0']; // this key is overwritten right away, but I must remember it is always created. + $hasCurrency = null !== $accountCurrency; + $currency = $hasCurrency ? $accountCurrency : $primary; + $return = ['pc_balance' => '0', 'balance' => '0']; // this key is overwritten right away, but I must remember it is always created. // balance(s) in all currencies. - $array = $account + $array = $account ->transactions() ->leftJoin('transaction_journals', 'transaction_journals.id', '=', 'transactions.transaction_journal_id') ->leftJoin('transaction_currencies', 'transaction_currencies.id', '=', 'transactions.transaction_currency_id') ->where('transaction_journals.date', $inclusive ? '<=' : '<', $date->format('Y-m-d H:i:s')) ->get(['transaction_currencies.code', 'transactions.amount']) - ->toArray(); - $others = $this->groupAndSumTransactions($array, 'code', 'amount'); + ->toArray() + ; + $others = $this->groupAndSumTransactions($array, 'code', 'amount'); Log::debug('All balances are (joined)', $others); // if there is no request to convert, take this as "balance" and "pc_balance". $return['balance'] = $others[$currency->code] ?? '0'; @@ -395,7 +394,7 @@ class Steam } // either way, the balance is always combined with the virtual balance: - $virtualBalance = (string)('' === (string)$account->virtual_balance ? '0' : $account->virtual_balance); + $virtualBalance = (string) ('' === (string) $account->virtual_balance ? '0' : $account->virtual_balance); if ($convertToPrimary) { // the primary currency balance is combined with a converted virtual_balance: @@ -411,7 +410,7 @@ class Steam // Log::debug(sprintf('Virtual balance makes the (primary currency) total %s', $return['balance'])); } - $final = array_merge($return, $others); + $final = array_merge($return, $others); Log::debug('Final balance is', $final); $cache->store($final); @@ -429,7 +428,7 @@ class Steam Log::debug(sprintf('called finalAccountBalanceInRange(#%d, %s, %s)', $account->id, $start->format('Y-m-d H:i:s'), $end->format('Y-m-d H:i:s'))); // set up cache - $cache = new CacheProperties(); + $cache = new CacheProperties(); $cache->addProperty($account->id); $cache->addProperty('final-balance-in-range'); $cache->addProperty($start); @@ -441,15 +440,15 @@ class Steam return $cache->get(); } - $balances = []; - $formatted = $start->format('Y-m-d'); + $balances = []; + $formatted = $start->format('Y-m-d'); Log::debug('Get first balance to start.'); // 2025-10-08 replaced finalAccountBalance with accountsBalancesOptimized: - $primaryCurrency = Amount::getPrimaryCurrencyByUserGroup($account->user->userGroup); - $startBalance = $this->accountsBalancesOptimized(new Collection()->push($account), $start, $primaryCurrency, $convertToPrimary, false)[$account->id]; - $accountCurrency = $this->getAccountCurrency($account); - $hasCurrency = $accountCurrency instanceof TransactionCurrency; - $currency = $accountCurrency ?? $primaryCurrency; + $primaryCurrency = Amount::getPrimaryCurrencyByUserGroup($account->user->userGroup); + $startBalance = $this->accountsBalancesOptimized(new Collection()->push($account), $start, $primaryCurrency, $convertToPrimary, false)[$account->id]; + $accountCurrency = $this->getAccountCurrency($account); + $hasCurrency = $accountCurrency instanceof TransactionCurrency; + $currency = $accountCurrency ?? $primaryCurrency; Log::debug(sprintf('Currency is %s', $currency->code)); // set start balances: @@ -461,14 +460,14 @@ class Steam Log::debug(sprintf('Also set start balance in %s', $primaryCurrency->code)); $startBalance[$primaryCurrency->code] ??= '0'; } - $currencies = [$currency->id => $currency, $primaryCurrency->id => $primaryCurrency]; + $currencies = [$currency->id => $currency, $primaryCurrency->id => $primaryCurrency]; $balances[$formatted] = $startBalance; Log::debug('Final start balance: ', $startBalance); // sums up the balance changes per day. Log::debug(sprintf('Date >= %s and <= %s', $start->format('Y-m-d H:i:s'), $end->format('Y-m-d H:i:s'))); - $set = $account + $set = $account ->transactions() ->leftJoin('transaction_journals', 'transactions.transaction_journal_id', '=', 'transaction_journals.id') ->where('transaction_journals.date', '>=', $start->format('Y-m-d H:i:s')) @@ -477,50 +476,51 @@ class Steam ->groupBy('transactions.transaction_currency_id') ->orderBy('transaction_journals.date', 'ASC') ->whereNull('transaction_journals.deleted_at') - ->get(['transaction_journals.date', 'transactions.transaction_currency_id', DB::raw('SUM(transactions.amount) AS sum_of_day')]); + ->get(['transaction_journals.date', 'transactions.transaction_currency_id', DB::raw('SUM(transactions.amount) AS sum_of_day')]) + ; - $currentBalance = $startBalance; - $converter = new ExchangeRateConverter(); + $currentBalance = $startBalance; + $converter = new ExchangeRateConverter(); /** @var Transaction $entry */ foreach ($set as $entry) { // get date object - $carbon = new Carbon($entry->date, $entry->date_tz); - $carbonKey = $carbon->format('Y-m-d'); + $carbon = new Carbon($entry->date, $entry->date_tz); + $carbonKey = $carbon->format('Y-m-d'); // make sure sum is a string: - $sumOfDay = (string)($entry->sum_of_day ?? '0'); + $sumOfDay = (string) ($entry->sum_of_day ?? '0'); // #10426 make sure sum is not in scientific notation. - $sumOfDay = $this->floatalize($sumOfDay); + $sumOfDay = $this->floatalize($sumOfDay); // find currency of this entry, does not have to exist. $currencies[$entry->transaction_currency_id] ??= Amount::getTransactionCurrencyById($entry->transaction_currency_id); // make sure this $entry has its own $entryCurrency /** @var TransactionCurrency $entryCurrency */ - $entryCurrency = $currencies[$entry->transaction_currency_id]; + $entryCurrency = $currencies[$entry->transaction_currency_id]; Log::debug(sprintf('Processing transaction(s) on moment %s', $carbon->format('Y-m-d H:i:s'))); // add amount to current balance in currency code. - $currentBalance[$entryCurrency->code] ??= '0'; - $currentBalance[$entryCurrency->code] = bcadd($sumOfDay, (string)$currentBalance[$entryCurrency->code]); + $currentBalance[$entryCurrency->code] ??= '0'; + $currentBalance[$entryCurrency->code] = bcadd($sumOfDay, (string) $currentBalance[$entryCurrency->code]); // if not requested to convert to primary currency, add the amount to "balance", do nothing else. if (!$convertToPrimary) { - $currentBalance['balance'] = bcadd((string)$currentBalance['balance'], $sumOfDay); + $currentBalance['balance'] = bcadd((string) $currentBalance['balance'], $sumOfDay); } // if convert to primary currency add the converted amount to "pc_balance". // if there is a request to convert, convert to "pc_balance" and use "balance" for whichever amount is in the primary currency. if ($convertToPrimary) { $pcSumOfDay = $converter->convert($entryCurrency, $primaryCurrency, $carbon, $sumOfDay); - $currentBalance['pc_balance'] = bcadd((string)($currentBalance['pc_balance'] ?? '0'), $pcSumOfDay); + $currentBalance['pc_balance'] = bcadd((string) ($currentBalance['pc_balance'] ?? '0'), $pcSumOfDay); // if it's the same currency as the entry, also add to balance (see other code). if ($currency->id === $entryCurrency->id) { - $currentBalance['balance'] = bcadd((string)$currentBalance['balance'], $sumOfDay); + $currentBalance['balance'] = bcadd((string) $currentBalance['balance'], $sumOfDay); } } // add to final array. - $balances[$carbonKey] = $currentBalance; + $balances[$carbonKey] = $currentBalance; Log::debug(sprintf('Updated entry [%s]', $carbonKey), $currentBalance); } $cache->store($balances); @@ -537,32 +537,74 @@ class Steam */ public function floatalize(string $value): string { - $value = strtoupper($value); + $value = strtoupper($value); if (!str_contains($value, 'E')) { return $value; } Log::debug(sprintf('Floatalizing %s', $value)); - $number = substr($value, 0, (int)strpos($value, 'E')); + $number = substr($value, 0, (int) strpos($value, 'E')); if (str_contains($number, '.')) { - $post = strlen(substr($number, (int)strpos($number, '.') + 1)); - $mantis = substr($value, (int)strpos($value, 'E') + 1); + $post = strlen(substr($number, (int) strpos($number, '.') + 1)); + $mantis = substr($value, (int) strpos($value, 'E') + 1); if ($mantis < 0) { - $post += abs((int)$mantis); + $post += abs((int) $mantis); } // TODO careless float could break financial math. - return number_format((float)$value, $post, '.', ''); + return number_format((float) $value, $post, '.', ''); } // TODO careless float could break financial math. - return number_format((float)$value, 0, '.', ''); + return number_format((float) $value, 0, '.', ''); + } + + public function formatAmountByCode(string $amount, string $code, ?bool $coloured = null): string + { + $coloured ??= true; + + try { + $currency = Amount::getTransactionCurrencyByCode($code); + } catch (FireflyException) { + Log::error(sprintf('Could not find currency with code "%s". Fallback to primary currency.', $code)); + $currency = Amount::getPrimaryCurrency(); + Log::error(sprintf('Fallback currency is "%s".', $currency->code)); + } + + return Amount::formatAnything($currency, $amount, $coloured); + } + + /** + * Will format the amount by the currency related to the given account. + */ + public function formatAmountBySymbol(string $amount, ?string $symbol = null, ?int $decimalPlaces = null, ?bool $coloured = null): string + { + if (null === $symbol) { + $message = sprintf( + 'formatAmountBySymbol("%s", %s, %d, %s) was called without a symbol. Please browse to /flush to clear your cache.', + $amount, + var_export($symbol, true), + $decimalPlaces, + var_export($coloured, true) + ); + Log::error($message); + $currency = Amount::getPrimaryCurrency(); + } + if (null !== $symbol) { + $decimalPlaces ??= 2; + $coloured ??= true; + $currency = new TransactionCurrency(); + $currency->symbol = $symbol; + $currency->decimal_places = $decimalPlaces; + } + + return Amount::formatAnything($currency, $amount, $coloured); } public function getAccountCurrency(Account $account): ?TransactionCurrency { - $type = $account->accountType->type; - $list = config('firefly.valid_currency_account_types'); + $type = $account->accountType->type; + $list = config('firefly.valid_currency_account_types'); // return null if not in this list. if (!in_array($type, $list, true)) { @@ -573,7 +615,7 @@ class Steam return null; } - return Amount::getTransactionCurrencyById((int)$result->data); + return Amount::getTransactionCurrencyById((int) $result->data); } public function getHostName(string $ipAddress): string @@ -587,11 +629,11 @@ class Steam $hostName = $ipAddress; } - if ('' !== (string)$hostName && $hostName !== $ipAddress) { + if ('' !== (string) $hostName && $hostName !== $ipAddress) { $host = $hostName; } - return (string)$host; + return (string) $host; } /** @@ -615,18 +657,19 @@ class Steam { $list = []; - $set = auth() + $set = auth() ->user() ->transactions() ->whereIn('transactions.account_id', $accounts) ->groupBy(['transactions.account_id', 'transaction_journals.user_id']) - ->get(['transactions.account_id', DB::raw('MAX(transaction_journals.date) AS max_date')]); + ->get(['transactions.account_id', DB::raw('MAX(transaction_journals.date) AS max_date')]) + ; /** @var Transaction $entry */ foreach ($set as $entry) { - $date = new Carbon($entry->max_date, config('app.timezone')); + $date = new Carbon($entry->max_date, config('app.timezone')); $date->setTimezone(config('app.timezone')); - $list[(int)$entry->account_id] = $date; + $list[(int) $entry->account_id] = $date; } return $list; @@ -642,14 +685,14 @@ class Steam if (null !== $cached) { return $cached; } - $locale = Preferences::get('locale', config('firefly.default_locale', 'equal'))->data; + $locale = Preferences::get('locale', config('firefly.default_locale', 'equal'))->data; if (is_array($locale)) { $locale = 'equal'; } if ('equal' === $locale) { $locale = $this->getLanguage(); } - $locale = (string)$locale; + $locale = (string) $locale; // Check for Windows to replace the locale correctly. if ('WIN' === strtoupper(substr(PHP_OS, 0, 3))) { @@ -689,7 +732,7 @@ class Steam public function getSafeUrl(string $unknownUrl, string $safeUrl): string { // Log::debug(sprintf('getSafeUrl(%s, %s)', $unknownUrl, $safeUrl)); - $returnUrl = $safeUrl; + $returnUrl = $safeUrl; // die('in get safe url'); try { @@ -752,24 +795,24 @@ class Steam // has a K in it, remove the K and multiply by 1024. $bytes = bcmul(rtrim($string, 'k'), '1024'); - return (int)$bytes; + return (int) $bytes; } if (false !== stripos($string, 'm')) { // has a M in it, remove the M and multiply by 1048576. $bytes = bcmul(rtrim($string, 'm'), '1048576'); - return (int)$bytes; + return (int) $bytes; } if (false !== stripos($string, 'g')) { // has a G in it, remove the G and multiply by (1024)^3. $bytes = bcmul(rtrim($string, 'g'), '1073741824'); - return (int)$bytes; + return (int) $bytes; } - return (int)$string; + return (int) $string; } public function positive(string $amount): string @@ -808,12 +851,12 @@ class Steam if (null === $preference) { $singleton->setPreference($key, $currency); } - $current = $amount; + $current = $amount; if ($currency->id !== $primary->id) { $current = $converter->convert($currency, $primary, $date, $amount); Log::debug(sprintf('Convert %s %s to %s %s', $currency->code, $amount, $primary->code, $current)); } - $total = bcadd((string)$current, $total); + $total = bcadd((string) $current, $total); } return $total; @@ -827,18 +870,18 @@ class Steam $primary = Amount::getPrimaryCurrency(); $currencies[$primary->id] = $primary; - $ids = $accounts->pluck('id')->toArray(); - $result = AccountMeta::query()->whereIn('account_id', $ids)->where('name', 'currency_id')->get(); + $ids = $accounts->pluck('id')->toArray(); + $result = AccountMeta::query()->whereIn('account_id', $ids)->where('name', 'currency_id')->get(); /** @var AccountMeta $item */ foreach ($result as $item) { - $integer = (int)$item->data; + $integer = (int) $item->data; if (0 !== $integer) { - $accountPreferences[(int)$item->account_id] = $integer; + $accountPreferences[(int) $item->account_id] = $integer; } } // collect those currencies, skip primary because we already have it. - $set = TransactionCurrency::query()->whereIn('id', $accountPreferences)->where('id', '!=', $primary->id)->get(); + $set = TransactionCurrency::query()->whereIn('id', $accountPreferences)->where('id', '!=', $primary->id)->get(); foreach ($set as $item) { $currencies[$item->id] = $item; } @@ -849,7 +892,7 @@ class Steam $currencyPresent = property_exists($account, 'meta') && array_key_exists('currency', $account->meta) && null !== $account->meta['currency']; if ($currencyPresent) { $currencyId = $account->meta['currency']->id; - $currencies[$currencyId] ??= $account->meta['currency']; + $currencies[$currencyId] ??= $account->meta['currency']; $accountCurrencies[$accountId] = $account->meta['currency']; } if (!$currencyPresent && !array_key_exists($accountId, $accountPreferences)) { @@ -869,51 +912,9 @@ class Steam foreach ($array as $item) { $groupKey = $item[$group] ?? 'unknown'; - $return[$groupKey] = bcadd($return[$groupKey] ?? '0', (string)$item[$field]); + $return[$groupKey] = bcadd($return[$groupKey] ?? '0', (string) $item[$field]); } return $return; } - - /** - * Will format the amount by the currency related to the given account. - */ - public function formatAmountBySymbol(string $amount, ?string $symbol = null, ?int $decimalPlaces = null, ?bool $coloured = null): string - { - if (null === $symbol) { - $message = sprintf( - 'formatAmountBySymbol("%s", %s, %d, %s) was called without a symbol. Please browse to /flush to clear your cache.', - $amount, - var_export($symbol, true), - $decimalPlaces, - var_export($coloured, true) - ); - Log::error($message); - $currency = Amount::getPrimaryCurrency(); - } - if (null !== $symbol) { - $decimalPlaces ??= 2; - $coloured ??= true; - $currency = new TransactionCurrency(); - $currency->symbol = $symbol; - $currency->decimal_places = $decimalPlaces; - } - - return Amount::formatAnything($currency, $amount, $coloured); - } - - public function formatAmountByCode(string $amount, string $code, ?bool $coloured = null): string - { - $coloured ??= true; - - try { - $currency = Amount::getTransactionCurrencyByCode($code); - } catch (FireflyException) { - Log::error(sprintf('Could not find currency with code "%s". Fallback to primary currency.', $code)); - $currency = Amount::getPrimaryCurrency(); - Log::error(sprintf('Fallback currency is "%s".', $currency->code)); - } - - return Amount::formatAnything($currency, $amount, $coloured); - } } diff --git a/app/View/Components/Dashboard/Boxes.php b/app/View/Components/Dashboard/Boxes.php index 07b2967d08..fb21010366 100644 --- a/app/View/Components/Dashboard/Boxes.php +++ b/app/View/Components/Dashboard/Boxes.php @@ -1,5 +1,7 @@ route = $route; + $this->route = $route; $this->linkTitle = $linkTitle; } /** * Get the view / contents that represent the component. */ - public function render(): View|Closure|string + public function render(): Closure|string|View { return view('components.elements.card-footer-with-menu'); } diff --git a/app/View/Components/Elements/CardHeaderWithMenu.php b/app/View/Components/Elements/CardHeaderWithMenu.php index 4613358e9b..202fe5d8f5 100644 --- a/app/View/Components/Elements/CardHeaderWithMenu.php +++ b/app/View/Components/Elements/CardHeaderWithMenu.php @@ -1,5 +1,7 @@ cardTitle = $cardTitle; - $this->route = $route; + $this->route = $route; $this->linkTitle = $linkTitle; } /** * Get the view / contents that represent the component. */ - public function render(): View|Closure|string + public function render(): Closure|string|View { return view('components.elements.card-header-with-menu'); } diff --git a/app/View/Components/Elements/TransactionAmount.php b/app/View/Components/Elements/TransactionAmount.php index 98ffb9ad51..88ad6f3b49 100644 --- a/app/View/Components/Elements/TransactionAmount.php +++ b/app/View/Components/Elements/TransactionAmount.php @@ -1,5 +1,7 @@ type = $type; - $this->amount = $amount; - $this->foreign = $foreign; - $this->account = $account; + $this->type = $type; + $this->amount = $amount; + $this->foreign = $foreign; + $this->account = $account; $this->pcAmount = $pcAmount; } /** * Get the view / contents that represent the component. */ - public function render(): View|Closure|string + public function render(): Closure|string|View { return view('components.elements.transaction-amount'); } diff --git a/app/View/Components/Elements/TransactionRunningBalance.php b/app/View/Components/Elements/TransactionRunningBalance.php index fec7e92a4d..9b5423169a 100644 --- a/app/View/Components/Elements/TransactionRunningBalance.php +++ b/app/View/Components/Elements/TransactionRunningBalance.php @@ -1,5 +1,7 @@ balanceDirty = $balanceDirty ?? false; - $this->currency = $currency; - $this->foreign= $foreign; - $this->type = $type; - $this->source = $source; - $this->destination = $destination; - $this->account = $account; + $this->currency = $currency; + $this->foreign = $foreign; + $this->type = $type; + $this->source = $source; + $this->destination = $destination; + $this->account = $account; } /** * Get the view / contents that represent the component. */ - public function render(): View|Closure|string + public function render(): Closure|string|View { return view('components.elements.transaction-running-balance'); } diff --git a/app/View/Components/Elements/TransactionTypeIcon.php b/app/View/Components/Elements/TransactionTypeIcon.php index b43ec3e848..dcc57160fd 100644 --- a/app/View/Components/Elements/TransactionTypeIcon.php +++ b/app/View/Components/Elements/TransactionTypeIcon.php @@ -1,5 +1,7 @@ route = $route; + $this->route = $route; $this->objectType = $objectType; - $this->type= $type; + $this->type = $type; } /** * Get the view / contents that represent the component. */ - public function render(): View|Closure|string + public function render(): Closure|string|View { return view('components.empty-page'); } diff --git a/app/View/Components/Generic/Amount.php b/app/View/Components/Generic/Amount.php index ee3a4a17d6..386dde2b66 100644 --- a/app/View/Components/Generic/Amount.php +++ b/app/View/Components/Generic/Amount.php @@ -1,5 +1,7 @@ accounts = $accounts; + $this->accounts = $accounts; $this->objectType = $objectType; } /** * Get the view / contents that represent the component. */ - public function render(): View|Closure|string + public function render(): Closure|string|View { return view('components.lists.accounts'); } - - } diff --git a/app/View/Components/Lists/GroupsLarge.php b/app/View/Components/Lists/GroupsLarge.php index eaa9be33ff..8f70aeeb18 100644 --- a/app/View/Components/Lists/GroupsLarge.php +++ b/app/View/Components/Lists/GroupsLarge.php @@ -1,5 +1,7 @@ groups = $groups; + $this->groups = $groups; $this->account = $account; } /** * Get the view / contents that represent the component. */ - public function render(): View|Closure|string + public function render(): Closure|string|View { return view('components.lists.groups-large'); } diff --git a/app/View/Components/Lists/GroupsTiny.php b/app/View/Components/Lists/GroupsTiny.php index 2813c9d120..945101d7f2 100644 --- a/app/View/Components/Lists/GroupsTiny.php +++ b/app/View/Components/Lists/GroupsTiny.php @@ -1,5 +1,7 @@ periods =$periods; + $this->periods = $periods; } /** * Get the view / contents that represent the component. */ - public function render(): View|Closure|string + public function render(): Closure|string|View { return view('components.lists.periods'); } diff --git a/app/View/Components/Lists/PiggyBanks.php b/app/View/Components/Lists/PiggyBanks.php index 586a8f2aed..79c42429cc 100644 --- a/app/View/Components/Lists/PiggyBanks.php +++ b/app/View/Components/Lists/PiggyBanks.php @@ -1,5 +1,7 @@ piggyBanks = $piggyBanks; @@ -20,7 +23,7 @@ class PiggyBanks extends Component /** * Get the view / contents that represent the component. */ - public function render(): View|Closure|string + public function render(): Closure|string|View { return view('components.lists.piggy-banks'); } diff --git a/app/View/Components/Lists/Subscriptions.php b/app/View/Components/Lists/Subscriptions.php index e182531b45..dc86f01242 100644 --- a/app/View/Components/Lists/Subscriptions.php +++ b/app/View/Components/Lists/Subscriptions.php @@ -1,10 +1,11 @@ bills = $bills; - $this->sums = $sums; + $this->bills = $bills; + $this->sums = $sums; $this->totals = $totals; } /** * Get the view / contents that represent the component. */ - public function render(): View|Closure|string + public function render(): Closure|string|View { return view('components.lists.subscriptions'); } diff --git a/app/View/Components/Transaction/Messages.php b/app/View/Components/Transaction/Messages.php index 3b0892f56c..373517f456 100644 --- a/app/View/Components/Transaction/Messages.php +++ b/app/View/Components/Transaction/Messages.php @@ -1,5 +1,7 @@ optionalFields = $optionalFields; + $this->optionalFields = $optionalFields; $this->optionalDateFields = $optionalDateFields; } /** * Get the view / contents that represent the component. */ - public function render(): View|Closure|string + public function render(): Closure|string|View { return view('components.transaction.split'); } diff --git a/app/View/Components/Transaction/TabList.php b/app/View/Components/Transaction/TabList.php index 28ec63930a..bf11a17f2b 100644 --- a/app/View/Components/Transaction/TabList.php +++ b/app/View/Components/Transaction/TabList.php @@ -1,5 +1,7 @@ =0.8.16 <=0.18", "php": "^8.0", "ramsey/collection": "^1.2 || ^2.0" }, @@ -5908,9 +5910,9 @@ ], "support": { "issues": "https://github.com/ramsey/uuid/issues", - "source": "https://github.com/ramsey/uuid/tree/4.9.2" + "source": "https://github.com/ramsey/uuid/tree/4.9.3" }, - "time": "2025-12-14T04:43:48+00:00" + "time": "2026-06-18T03:57:49+00:00" }, { "name": "rcrowe/twigbridge", @@ -8140,16 +8142,16 @@ }, { "name": "symfony/polyfill-deepclone", - "version": "v1.37.0", + "version": "v1.40.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-deepclone.git", - "reference": "2ca9e9e75ead5174f2b44613a646bdc9338b8eb4" + "reference": "dca4ccba5f360070b574414dce4c1e7a559844fa" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-deepclone/zipball/2ca9e9e75ead5174f2b44613a646bdc9338b8eb4", - "reference": "2ca9e9e75ead5174f2b44613a646bdc9338b8eb4", + "url": "https://api.github.com/repos/symfony/polyfill-deepclone/zipball/dca4ccba5f360070b574414dce4c1e7a559844fa", + "reference": "dca4ccba5f360070b574414dce4c1e7a559844fa", "shasum": "" }, "require": { @@ -8203,7 +8205,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-deepclone/tree/v1.37.0" + "source": "https://github.com/symfony/polyfill-deepclone/tree/v1.40.0" }, "funding": [ { @@ -8223,7 +8225,7 @@ "type": "tidelift" } ], - "time": "2026-04-26T13:03:27+00:00" + "time": "2026-06-12T07:27:17+00:00" }, { "name": "symfony/polyfill-intl-grapheme", @@ -10491,28 +10493,29 @@ }, { "name": "composer/pcre", - "version": "3.3.2", + "version": "3.4.0", "source": { "type": "git", "url": "https://github.com/composer/pcre.git", - "reference": "b2bed4734f0cc156ee1fe9c0da2550420d99a21e" + "reference": "d5a341b3fb61f3001970940afb1d332968a183ed" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/composer/pcre/zipball/b2bed4734f0cc156ee1fe9c0da2550420d99a21e", - "reference": "b2bed4734f0cc156ee1fe9c0da2550420d99a21e", + "url": "https://api.github.com/repos/composer/pcre/zipball/d5a341b3fb61f3001970940afb1d332968a183ed", + "reference": "d5a341b3fb61f3001970940afb1d332968a183ed", "shasum": "" }, "require": { "php": "^7.4 || ^8.0" }, "conflict": { - "phpstan/phpstan": "<1.11.10" + "phpstan/phpstan": "<2.2.2" }, "require-dev": { - "phpstan/phpstan": "^1.12 || ^2", - "phpstan/phpstan-strict-rules": "^1 || ^2", - "phpunit/phpunit": "^8 || ^9" + "phpstan/phpstan": "^2", + "phpstan/phpstan-deprecation-rules": "^2", + "phpstan/phpstan-strict-rules": "^2", + "phpunit/phpunit": "^9" }, "type": "library", "extra": { @@ -10550,7 +10553,7 @@ ], "support": { "issues": "https://github.com/composer/pcre/issues", - "source": "https://github.com/composer/pcre/tree/3.3.2" + "source": "https://github.com/composer/pcre/tree/3.4.0" }, "funding": [ { @@ -10560,13 +10563,9 @@ { "url": "https://github.com/composer", "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/composer/composer", - "type": "tidelift" } ], - "time": "2024-11-12T16:29:46+00:00" + "time": "2026-06-07T11:47:49+00:00" }, { "name": "driftingly/rector-laravel", @@ -11791,16 +11790,16 @@ }, { "name": "phpunit/php-code-coverage", - "version": "14.2.1", + "version": "14.2.2", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-code-coverage.git", - "reference": "ed4f43a9a69d6be9f92d50397044ccb862bd8133" + "reference": "10d7da3628a99289cdf4c662dd7f0d73f1baec83" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/ed4f43a9a69d6be9f92d50397044ccb862bd8133", - "reference": "ed4f43a9a69d6be9f92d50397044ccb862bd8133", + "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/10d7da3628a99289cdf4c662dd7f0d73f1baec83", + "reference": "10d7da3628a99289cdf4c662dd7f0d73f1baec83", "shasum": "" }, "require": { @@ -11857,7 +11856,7 @@ "support": { "issues": "https://github.com/sebastianbergmann/php-code-coverage/issues", "security": "https://github.com/sebastianbergmann/php-code-coverage/security/policy", - "source": "https://github.com/sebastianbergmann/php-code-coverage/tree/14.2.1" + "source": "https://github.com/sebastianbergmann/php-code-coverage/tree/14.2.2" }, "funding": [ { @@ -11877,7 +11876,7 @@ "type": "tidelift" } ], - "time": "2026-06-07T09:07:04+00:00" + "time": "2026-06-08T11:50:38+00:00" }, { "name": "phpunit/php-file-iterator", @@ -12174,16 +12173,16 @@ }, { "name": "phpunit/phpunit", - "version": "13.2.0", + "version": "13.2.1", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/phpunit.git", - "reference": "3796ea973f1e7698f0d432c1c66662af9764fd9a" + "reference": "60da0ff1e10a0f72ee18a24117ec3b613a346bba" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/3796ea973f1e7698f0d432c1c66662af9764fd9a", - "reference": "3796ea973f1e7698f0d432c1c66662af9764fd9a", + "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/60da0ff1e10a0f72ee18a24117ec3b613a346bba", + "reference": "60da0ff1e10a0f72ee18a24117ec3b613a346bba", "shasum": "" }, "require": { @@ -12197,7 +12196,7 @@ "phar-io/manifest": "^2.0.4", "phar-io/version": "^3.2.1", "php": ">=8.4.1", - "phpunit/php-code-coverage": "^14.2", + "phpunit/php-code-coverage": "^14.2.2", "phpunit/php-file-iterator": "^7.0.0", "phpunit/php-invoker": "^7.0.0", "phpunit/php-text-template": "^6.0.0", @@ -12254,7 +12253,7 @@ "support": { "issues": "https://github.com/sebastianbergmann/phpunit/issues", "security": "https://github.com/sebastianbergmann/phpunit/security/policy", - "source": "https://github.com/sebastianbergmann/phpunit/tree/13.2.0" + "source": "https://github.com/sebastianbergmann/phpunit/tree/13.2.1" }, "funding": [ { @@ -12262,25 +12261,25 @@ "type": "other" } ], - "time": "2026-06-05T03:13:07+00:00" + "time": "2026-06-15T13:14:22+00:00" }, { "name": "rector/rector", - "version": "2.4.5", + "version": "2.4.6", "source": { "type": "git", "url": "https://github.com/rectorphp/rector.git", - "reference": "cbd86024be5014d3c14d9f0b3f7aae8ecbffd62c" + "reference": "9b9e5c76618e4d359f65b54ca2eabcad3d1761ee" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/rectorphp/rector/zipball/cbd86024be5014d3c14d9f0b3f7aae8ecbffd62c", - "reference": "cbd86024be5014d3c14d9f0b3f7aae8ecbffd62c", + "url": "https://api.github.com/repos/rectorphp/rector/zipball/9b9e5c76618e4d359f65b54ca2eabcad3d1761ee", + "reference": "9b9e5c76618e4d359f65b54ca2eabcad3d1761ee", "shasum": "" }, "require": { "php": "^7.4|^8.0", - "phpstan/phpstan": "^2.1.56" + "phpstan/phpstan": "^2.2.2" }, "conflict": { "rector/rector-doctrine": "*", @@ -12314,7 +12313,7 @@ ], "support": { "issues": "https://github.com/rectorphp/rector/issues", - "source": "https://github.com/rectorphp/rector/tree/2.4.5" + "source": "https://github.com/rectorphp/rector/tree/2.4.6" }, "funding": [ { @@ -12322,7 +12321,7 @@ "type": "github" } ], - "time": "2026-05-26T21:03:22+00:00" + "time": "2026-06-17T11:56:28+00:00" }, { "name": "sebastian/cli-parser", @@ -13593,16 +13592,16 @@ }, { "name": "webmozart/assert", - "version": "2.4.0", + "version": "2.4.1", "source": { "type": "git", "url": "https://github.com/webmozarts/assert.git", - "reference": "9007ea6f45ecf352a9422b36644e4bfc039b9155" + "reference": "2ccb7c2e821038c03a3e6e1700c570c158c55f70" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/webmozarts/assert/zipball/9007ea6f45ecf352a9422b36644e4bfc039b9155", - "reference": "9007ea6f45ecf352a9422b36644e4bfc039b9155", + "url": "https://api.github.com/repos/webmozarts/assert/zipball/2ccb7c2e821038c03a3e6e1700c570c158c55f70", + "reference": "2ccb7c2e821038c03a3e6e1700c570c158c55f70", "shasum": "" }, "require": { @@ -13653,9 +13652,9 @@ ], "support": { "issues": "https://github.com/webmozarts/assert/issues", - "source": "https://github.com/webmozarts/assert/tree/2.4.0" + "source": "https://github.com/webmozarts/assert/tree/2.4.1" }, - "time": "2026-05-20T13:07:01+00:00" + "time": "2026-06-15T15:31:57+00:00" } ], "aliases": [], diff --git a/config/firefly.php b/config/firefly.php index 832c56aaf9..2a11dd3050 100644 --- a/config/firefly.php +++ b/config/firefly.php @@ -78,8 +78,8 @@ return [ 'running_balance_column' => (bool)env_default_when_empty(env('USE_RUNNING_BALANCE'), true), // this is only the default value, is not used. // see cer.php for exchange rates feature flag. ], -'version' => 'develop/2026-06-08', -'build_time' => 1780917755, +'version' => 'branch-adminlte', +'build_time' => 1781841027, 'api_version' => '2.1.0', // field is no longer used. 'db_version' => 28, // field is no longer used. @@ -390,7 +390,7 @@ return [ AccountTypeEnum::MORTGAGE->value => AccountTypeEnum::MORTGAGE->value, ], 'transactionTypesByType' => [ - 'all' => ['Withdrawal','Deposit','Transfer'], + 'all' => ['Withdrawal', 'Deposit', 'Transfer'], 'expenses' => ['Withdrawal'], 'withdrawal' => ['Withdrawal'], 'revenue' => ['Deposit'], diff --git a/package-lock.json b/package-lock.json index 49b1528137..3c2c7d23b4 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,5 +1,5 @@ { - "name": "release", + "name": "firefly-iii", "lockfileVersion": 3, "requires": true, "packages": { diff --git a/resources/assets/v1/src/locales/ru.json b/resources/assets/v1/src/locales/ru.json index eaf48367b6..ea286acb7a 100644 --- a/resources/assets/v1/src/locales/ru.json +++ b/resources/assets/v1/src/locales/ru.json @@ -32,7 +32,7 @@ "transaction_journal_information": "\u0418\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044f \u043e \u0442\u0440\u0430\u043d\u0437\u0430\u043a\u0446\u0438\u0438", "submission_options": "\u041e\u043f\u0446\u0438\u0438 \u043e\u0442\u043f\u0440\u0430\u0432\u043a\u0438", "apply_rules_checkbox": "\u041f\u0440\u0438\u043c\u0435\u043d\u0438\u0442\u044c \u043f\u0440\u0430\u0432\u0438\u043b\u0430", - "fire_webhooks_checkbox": "Fire webhooks", + "fire_webhooks_checkbox": "\u0417\u0430\u043f\u0443\u0441\u043a\u0430\u0442\u044c \u0432\u0435\u0431\u0445\u0443\u043a\u0438", "no_budget_pointer": "\u041f\u043e\u0445\u043e\u0436\u0435, \u0443 \u0432\u0430\u0441 \u043f\u043e\u043a\u0430 \u043d\u0435\u0442 \u0431\u044e\u0434\u0436\u0435\u0442\u043e\u0432. \u0412\u044b \u0434\u043e\u043b\u0436\u043d\u044b \u0441\u043e\u0437\u0434\u0430\u0442\u044c \u0438\u0445 \u043d\u0430 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0435 \u0411\u044e\u0434\u0436\u0435\u0442\u044b<\/a>. \u0411\u044e\u0434\u0436\u0435\u0442\u044b \u043c\u043e\u0433\u0443\u0442 \u043f\u043e\u043c\u043e\u0447\u044c \u0432\u0430\u043c \u043e\u0442\u0441\u043b\u0435\u0436\u0438\u0432\u0430\u0442\u044c \u0440\u0430\u0441\u0445\u043e\u0434\u044b.", "no_bill_pointer": "\u041f\u043e\u0445\u043e\u0436\u0435, \u0443 \u0432\u0430\u0441 \u043f\u043e\u043a\u0430 \u043d\u0435\u0442 \u043f\u043e\u0434\u043f\u0438\u0441\u043a\u0438. \u0412\u0430\u043c \u0441\u043b\u0435\u0434\u0443\u0435\u0442 \u0441\u043e\u0437\u0434\u0430\u0442\u044c \u0435\u0435 \u043d\u0430 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0435 \u043f\u043e\u0434\u043f\u0438\u0441\u043a\u0438<\/a>. \u041f\u043e\u0434\u043f\u0438\u0441\u043a\u0438 \u043c\u043e\u0433\u0443\u0442 \u043f\u043e\u043c\u043e\u0447\u044c \u0432\u0430\u043c \u043e\u0442\u0441\u043b\u0435\u0436\u0438\u0432\u0430\u0442\u044c \u0440\u0430\u0441\u0445\u043e\u0434\u044b.", "source_account": "\u0421\u0447\u0451\u0442-\u0438\u0441\u0442\u043e\u0447\u043d\u0438\u043a", diff --git a/resources/lang/en_US/firefly.php b/resources/lang/en_US/firefly.php index d9075d9cc2..ea2ade9cec 100644 --- a/resources/lang/en_US/firefly.php +++ b/resources/lang/en_US/firefly.php @@ -46,10 +46,10 @@ return [ 'YTD' => 'YTD', 'welcome_back' => 'What\'s playing?', 'main_dashboard_page_title' => 'Home', - 'view_documentation' => 'View documentation', + 'view_documentation' => 'View documentation', 'everything' => 'Everything', 'today' => 'today', - 'organization' => 'Organization', + 'organization' => 'Organization', 'customRange' => 'Custom range', 'date_range' => 'Date range', 'apply' => 'Apply', @@ -1866,7 +1866,7 @@ return [ 'update_budget_amount_range' => 'Update (expected) available amount between :start and :end', 'set_budget_limit_title' => 'Set budgeted amount for budget :budget between :start and :end', 'set_budget_limit' => 'Set budgeted amount', - 'add_budget_limit_currency'=> 'Set budgeted amount in another currency', + 'add_budget_limit_currency' => 'Set budgeted amount in another currency', 'budget_period_navigator' => 'Period navigator', 'info_on_available_amount' => 'What do I have available?', 'available_amount_indication' => 'Use these amounts to get an indication of what your total budget could be.', @@ -2118,7 +2118,7 @@ return [ 'wait_loading_data' => 'Please wait for your information to load...', 'wait_attachments' => 'Please wait for the attachments to upload.', 'errors_upload' => 'The upload has failed. Please check your browser console for the error.', - 'upload_too_large' => 'The upload has failed, the file is too large. Please try again.', + 'upload_too_large' => 'The upload has failed, the file is too large. Please try again.', 'amount_foreign_if' => 'Amount in foreign currency, if any', 'amount_destination_account' => 'Amount in the currency of the destination account', 'edit_transaction_title' => 'Edit transaction ":description"', @@ -2900,7 +2900,7 @@ return [ 'box_left_to_spend_in_currency' => 'Left to spend (:currency)', 'box_net_worth_in_currency' => 'Net worth (:currency)', 'box_spend_per_day' => 'Left to spend per day: :amount', - 'box_no_budgeted'=> 'No money was budgeted for this period', + 'box_no_budgeted' => 'No money was budgeted for this period', // debug page 'debug_page' => 'Debug page',