From 9cd91729acb95bc13e44f175393cf10dc5c0794a Mon Sep 17 00:00:00 2001 From: James Cole Date: Wed, 10 Jun 2026 20:37:05 +0200 Subject: [PATCH] Expand v3 layout. --- app/Helpers/Functions/helpers.php | 16 +- app/Http/Controllers/HomeController.php | 29 +-- app/Providers/AppServiceProvider.php | 34 ++- app/Support/Blade/Navigation.php | 67 ++++++ app/Support/Steam.php | 226 ++++++++++-------- app/View/Components/Lists/Accounts.php | 9 +- resources/views/accounts/index.blade.php | 81 ++++--- .../views/components/layout/sidebar.blade.php | 26 +- .../components/layout/user-menu.blade.php | 20 +- .../views/components/lists/accounts.blade.php | 152 ++++++------ resources/views/index.blade.php | 18 +- 11 files changed, 388 insertions(+), 290 deletions(-) create mode 100644 app/Support/Blade/Navigation.php diff --git a/app/Helpers/Functions/helpers.php b/app/Helpers/Functions/helpers.php index 6c2b8d575e..66471a65a7 100644 --- a/app/Helpers/Functions/helpers.php +++ b/app/Helpers/Functions/helpers.php @@ -24,7 +24,8 @@ declare(strict_types=1); use Carbon\Carbon; use FireflyIII\Exceptions\FireflyException; -use FireflyIII\Models\TransactionCurrency; +use FireflyIII\Models\Account; +use FireflyIII\Repositories\Account\AccountRepositoryInterface; use FireflyIII\Support\Facades\Amount; use FireflyIII\Support\Facades\Steam; use Illuminate\Support\Collection; @@ -50,6 +51,19 @@ if (!function_exists('env_default_when_empty')) { } } +if (!function_exists('bladeAccountGetMetaField')) { + function bladeAccountGetMetaField(Account $account, string $field): string + { + /** @var AccountRepositoryInterface $repository */ + $repository = app(AccountRepositoryInterface::class); + $result = $repository->getMetaValue($account, $field); + if (null === $result) { + return ''; + } + return $result; + } +} + if (!function_exists('bladeAccountBalance')) { function bladeAccountBalance(\FireflyIII\Models\Account $account): string diff --git a/app/Http/Controllers/HomeController.php b/app/Http/Controllers/HomeController.php index f7d3a23ca3..e67bdb6bc5 100644 --- a/app/Http/Controllers/HomeController.php +++ b/app/Http/Controllers/HomeController.php @@ -53,7 +53,7 @@ final class HomeController extends Controller { parent::__construct(); app('view')->share('title', 'Firefly III'); - app('view')->share('mainTitleIcon', 'fa-fire'); + app('view')->share('mainTitleIcon', 'bi-fire'); $this->middleware(Installer::class); } @@ -135,15 +135,8 @@ final class HomeController extends Controller if (0 === $count) { return redirect(route('new-user.index')); } - - if ('v1' === (string) config('view.layout')) { - return $this->indexV1($repository); - } - if ('v2' === (string) config('view.layout')) { - return $this->indexV2(); - } - - throw new FireflyException('Invalid layout configuration'); + // ignore v2. + return $this->indexV1($repository); } private function indexV1(AccountRepositoryInterface $repository): mixed @@ -152,6 +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'; $transactions = []; $frontpage = Preferences::getFresh('frontpageAccounts', $repository->getAccountsByType([AccountTypeEnum::ASSET->value])->pluck('id')->toArray()); $frontpageArray = $frontpage->data; @@ -188,6 +182,7 @@ final class HomeController extends Controller return view('index', [ 'count' => $count, + 'subTitleIcon' => $subTitleIcon, 'subTitle' => $subTitle, 'transactions' => $transactions, 'billCount' => $billCount, @@ -198,18 +193,4 @@ final class HomeController extends Controller ]); } - private function indexV2(): mixed - { - $subTitle = (string) trans('firefly.welcome_back'); - $pageTitle = (string) trans('firefly.main_dashboard_page_title'); - - $start = session('start', today(config('app.timezone'))->startOfMonth()); - $end = session('end', today(config('app.timezone'))->endOfMonth()); - - /** @var User $user */ - $user = auth()->user(); - event(new SystemRequestedVersionCheck($user)); - - return view('index', ['subTitle' => $subTitle, 'start' => $start, 'end' => $end, 'pageTitle' => $pageTitle]); - } } diff --git a/app/Providers/AppServiceProvider.php b/app/Providers/AppServiceProvider.php index 1190032367..0accfde8a2 100644 --- a/app/Providers/AppServiceProvider.php +++ b/app/Providers/AppServiceProvider.php @@ -24,6 +24,7 @@ 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; @@ -32,7 +33,6 @@ use Illuminate\Support\Facades\Schema; use Illuminate\Support\ServiceProvider; use Laravel\Passport\Passport; use Override; - use function Safe\preg_match; /** @@ -49,9 +49,10 @@ class AppServiceProvider extends ServiceProvider Passport::$validateKeyPermissions = false; Schema::defaultStringLength(191); + 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; } @@ -59,24 +60,37 @@ class AppServiceProvider extends ServiceProvider return response()->json($value)->withHeaders($headers); }); - // blade extension for active menu link - Blade::directive('menuItemActive', function (string $route): string { + + // 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('menuItemActive("%s", "%s")', $route, $name)); - if (str_contains($route, $name)) { - return 'active'; + 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 { + + }); + + + // TODO @deprecated // blade extension for account balance. Blade::directive('balance', function (string $account): string { - var_dump($account);exit; + var_dump($account); + exit; return $account; return 'blablabla'; }); + // TODO @deprecated // blade extension Blade::directive('activeXRoutePartial', function (string $route): string { $name = Route::getCurrentRoute()->getName() ?? ''; @@ -87,14 +101,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/Support/Blade/Navigation.php b/app/Support/Blade/Navigation.php new file mode 100644 index 0000000000..1bdcda8dcc --- /dev/null +++ b/app/Support/Blade/Navigation.php @@ -0,0 +1,67 @@ +. + */ + +namespace FireflyIII\Support\Blade; + +use Illuminate\Support\Facades\Log; +use Illuminate\Support\Facades\Route; + +class Navigation +{ + public static function menuItemActive (string $route): string { + $name = Route::getCurrentRoute()->getName() ?? ''; + Log::debug(sprintf('menuItemActive("%s" = "%s")', $route, $name)); + if ($name === $route) { + return 'active'; + } + + return ''; + } + 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)) { + return 'active'; + } + + 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 { + $name = Route::getCurrentRoute()->getName() ?? ''; + Log::debug(sprintf('menuOpenPartial("%s" starts with "%s")', $name, $route)); + if (str_starts_with($name, $route)) { + return 'menu-open'; + } + + return ''; + } +} diff --git a/app/Support/Steam.php b/app/Support/Steam.php index 5d5a3ef3fc..f95a6fea35 100644 --- a/app/Support/Steam.php +++ b/app/Support/Steam.php @@ -43,7 +43,6 @@ use Psr\Container\ContainerExceptionInterface; use Psr\Container\NotFoundExceptionInterface; use Safe\Exceptions\UrlException; use ValueError; - use function Safe\parse_url; use function Safe\preg_replace; @@ -57,12 +56,13 @@ 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,15 +334,17 @@ 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()) { @@ -358,26 +360,25 @@ 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'; @@ -394,7 +395,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: @@ -410,7 +411,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); @@ -428,7 +429,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); @@ -440,15 +441,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: @@ -460,14 +461,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')) @@ -476,51 +477,50 @@ 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,32 @@ 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 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 +573,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 +587,11 @@ class Steam $hostName = $ipAddress; } - if ('' !== (string) $hostName && $hostName !== $ipAddress) { + if ('' !== (string)$hostName && $hostName !== $ipAddress) { $host = $hostName; } - return (string) $host; + return (string)$host; } /** @@ -615,19 +615,18 @@ 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; @@ -643,14 +642,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))) { @@ -690,7 +689,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 { @@ -753,24 +752,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 @@ -809,12 +808,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; @@ -828,18 +827,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; } @@ -850,7 +849,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)) { @@ -870,7 +869,7 @@ 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; @@ -902,4 +901,19 @@ class Steam 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/Lists/Accounts.php b/app/View/Components/Lists/Accounts.php index 1a4f25298c..6927ca564a 100644 --- a/app/View/Components/Lists/Accounts.php +++ b/app/View/Components/Lists/Accounts.php @@ -10,14 +10,15 @@ use Illuminate\View\Component; class Accounts extends Component { - public LengthAwarePaginator|null $accounts = null; + public LengthAwarePaginator $accounts; public string $objectType = ''; /** * Create a new component instance. */ - public function __construct() + public function __construct(LengthAwarePaginator $accounts, string $objectType) { - // + $this->accounts = $accounts; + $this->objectType = $objectType; } /** @@ -27,4 +28,6 @@ class Accounts extends Component { return view('components.lists.accounts'); } + + } diff --git a/resources/views/accounts/index.blade.php b/resources/views/accounts/index.blade.php index 7e5d2e1304..b131bae585 100644 --- a/resources/views/accounts/index.blade.php +++ b/resources/views/accounts/index.blade.php @@ -4,56 +4,59 @@
-
-

- {{ $subTitle }} -

-
-
- - +
+
+
+
{{ trans('firefly.asset_accounts') }}
+
+
- -
-
-

+

- + @if($inactiveCount > 0) +

+ + + {{ trans_choice('firefly.inactive_account_link', $inactiveCount) }} + + + +

+ @endif + @if($inactivePage) +

+ + {{ trans('firefly.all_accounts_inactive') }} + + {{ trans('firefly.active_account_link', ['count' => $inactiveCount]) }} + + + +

+ @endif
@endif diff --git a/resources/views/components/layout/sidebar.blade.php b/resources/views/components/layout/sidebar.blade.php index af7b04d142..23aff2d79c 100644 --- a/resources/views/components/layout/sidebar.blade.php +++ b/resources/views/components/layout/sidebar.blade.php @@ -10,14 +10,14 @@ - - - - - - - - diff --git a/resources/views/components/lists/accounts.blade.php b/resources/views/components/lists/accounts.blade.php index bae703a601..46a2315fcc 100644 --- a/resources/views/components/lists/accounts.blade.php +++ b/resources/views/components/lists/accounts.blade.php @@ -1,4 +1,4 @@ -
+
{{ $accounts->links('pagination.bootstrap-4') }}
@@ -38,111 +38,113 @@ @foreach($accounts as $account) - {% if objectType == "asset" %} + @if('asset' === $objectType) - {% endif %} - {% if objectType == 'liabilities' %} + @endif + @if('liabilities' === $objectType) - {% endif %} - - {% if objectType != 'liabilities' %} + @endif + + @if('liabilities' !== $objectType) - {% endif %} - {% if objectType == 'liabilities' %} + @endif + @if('liabilities' === $objectType) - {% endif %} + @endif - {# hide last activity to make room for other stuff #} - {% if objectType != 'liabilities' %} - {% if account.lastActivityDate %} + {{-- hide last activity to make room for other stuff --}} + @if('liabilities' !== $objectType) + @if($account->lastActivityDate) - {% else %} + @else - {% endif %} - {% endif %} + @endif + @endif - @@ -151,6 +153,6 @@ @endforeach
{{ $account->name }} - {% if account.location %} - - {% endif %} - {% if account.attachments.count() > 0 %} - - {% endif %} + @if($account->location) + + @endif + @if($account->attachments->count() > 0) + + @endif {{ $account->accountTypeString }} {{ trans('firefly.liability_direction_' . $account->liability_direction . '_short') }} {{ $account->interest }}% ({{ strtolower($account->interestPeriod) }}) - {% for key, balance in account.endBalances %} + @foreach($account->endBalances as $key => $balance) - {% if 'balance' == key %} - {% if not convertToPrimary %} - {{ formatAmountBySymbol($balance, $account->currency->symbol, $account->currency->decimal_places) }} - {% endif %} - {% elseif 'pc_balance' == key %} - {% if convertToPrimary %} - {{ formatAmountBySymbol($balance, $primaryCurrency->symbol, $primaryCurrency->decimal_places) }} - {% endif %} - {% else %} - ({{ formatAmountByCode($balance, $key) }}) - {% endif %} + @if('balance' === $key) + @if(!$convertToPrimary) + {!! \FireflyIII\Support\Facades\Steam::formatAmountBySymbol($balance, $account->currency->symbol, $account->currency->decimal_places) !!} + @endif + @elseif('pc_balance' === $key) + @if($convertToPrimary) + {!! \FireflyIII\Support\Facades\Steam::formatAmountBySymbol($balance, $primaryCurrency->symbol, $primaryCurrency->decimal_places) !!} + @endif + @else + ({!! \FireflyIII\Support\Facades\Steam::formatAmountByCode($balance, $key) !!}) + @endif - {% endfor %} + @endforeach - {% if '-' != account.current_debt %} + @if('' !== $account->current_debt) - {{ formatAmountBySymbol($account->current_debt, $account->currency->symbol, $account->currency->decimal_places, false) }} + {!! \FireflyIII\Support\Facades\Steam::formatAmountBySymbol($account->current_debt, $account->currency->symbol, $account->currency->decimal_places, false) !!} - {% endif %} + @endif
-
+
{{ $accounts->links('pagination.bootstrap-4')}}
diff --git a/resources/views/index.blade.php b/resources/views/index.blade.php index c0c59ce248..2fa08871d7 100644 --- a/resources/views/index.blade.php +++ b/resources/views/index.blade.php @@ -7,9 +7,9 @@
-
-
- +
+
@@ -21,7 +21,7 @@
-
-
+
@@ -59,7 +59,7 @@
@foreach($transactions as $data)
-
+ @@ -123,7 +123,7 @@ @if($billCount > 0)