Bicycle/App/Controller/IndexController.php
Egor Isaev ac1334c784 dev
2026-08-14 14:05:41 +03:00

106 lines
4.4 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<?php
/**
* @package Bicycle
* @author Egor Isaev
* @description IndexController.php
* @copyright (c) 03/06/2026
*/
namespace App\Controller;
use App\Repositories\AccountRepository;
use App\Repositories\BudgetRepository;
use App\Repositories\CategoryRepository;
use App\Repositories\GoalRepository;
use App\Repositories\TransactionRepository;
use App\Repositories\UserRepository;
use Services\Auth;
use System\Classes\Controller;
use System\Classes\MyException;
/**
* Дашборд — главная страница после входа (защищена, см. $_auth_protection).
*/
class IndexController extends Controller
{
protected bool $_auth_protection = true;
/**
* @return string
* @throws MyException
*/
public function indexAction(): string
{
$auth_user = Auth::instance()->getUser();
$user = (new UserRepository())->getByLogin($auth_user['login']);
$account_repo = new AccountRepository();
$accounts = $user ? $account_repo->getList('*', ['user_id' => $user->id, 'is_delete' => 0], '`order`') : [];
$archived_accounts = $user ? $account_repo->getList('*', ['user_id' => $user->id, 'is_delete' => 1], 'title') : [];
$total = array_sum(array_map(
static fn ($account) => $account->include_in_total && $account->currency === 'RUB' ? (float)$account->summa : 0,
$accounts ?: []
));
// «Всего по всем счетам» — без фильтра include_in_total, для строки под «Доступно сейчас»
// (см. дизайн-хендофф App/design_handoff_personal_finance). Валютные счета — та же
// сознательная недоделка, что и у $total выше: без Services\CurrencyRate конвертировать
// не во что, поэтому считаем только RUB (не показываем непересчитанную сумму как есть).
$total_all = array_sum(array_map(
static fn ($account) => $account->currency === 'RUB' ? (float)$account->summa : 0,
$accounts ?: []
));
$month = (int)date('n');
$year = (int)date('Y');
$category_repo = new CategoryRepository();
$budget_repo = new BudgetRepository();
$tree = $user ? $category_repo->getTree($user->id) : [];
$plan_month = $user ? array_map(
static fn ($months) => $months[$month]['plan_summ'] ?? 0.0,
$budget_repo->getYear($user->id, $year)
) : [];
// Факт за месяц — реальные transactions (таблица/репозиторий уже есть, UI для их ввода
// пока нет, поэтому в живой БД сумма обычно 0 — это корректный факт, не заглушка).
$fact_month = $user ? (new TransactionRepository())->getMonthActualByCategory($user->id, $year, $month) : [];
// % бюджета по расходам за месяц — план/факт только по expense-статьям (для плашки в шапке).
$expense_ids = [];
foreach ($tree as $items) {
foreach ($items as $c) {
if ($c->type === 'expense') {
$expense_ids[(int)$c->id] = true;
}
}
}
$plan_expense = 0.0;
$fact_expense = 0.0;
foreach ($expense_ids as $categorie_id => $_) {
$plan_expense += $plan_month[$categorie_id] ?? 0.0;
$fact_expense += $fact_month[$categorie_id] ?? 0.0;
}
$pct_expense = $plan_expense > 0 ? round($fact_expense / $plan_expense * 100) : null;
$goals = $user ? (new GoalRepository())->getForUser($user->id) : [];
return $this->render('index', [
'user' => $auth_user,
'accounts' => $accounts ?: [],
'archived_accounts' => $archived_accounts ?: [],
'total' => $total,
'total_all' => $total_all,
'tree' => $tree,
'plan_month' => $plan_month,
'fact_month' => $fact_month,
'pct_expense' => $pct_expense,
'goals' => $goals ?: [],
'month' => $month,
]);
}
}