table} t LEFT JOIN categories c ON c.id = t.categorie_id LEFT JOIN accounts af ON af.id = t.account_f_id LEFT JOIN accounts ai ON ai.id = t.account_in_id WHERE t.user_id = :user_id ORDER BY t.date DESC, t.id DESC LIMIT {$limit}"; $stmt = $this->pdo->prepare($sql); $stmt->execute(['user_id' => $user_id]); return $stmt->fetchAll(PDO::FETCH_OBJ); } /** * Агрегат income/expense по месяцам за год. * * @param int $user_id * @param int $year * @return array> [month => ['income'=>..., 'expense'=>...]] */ public function getMonthlyTotals(int $user_id, int $year): array { $sql = "SELECT MONTH(date) AS month, type, SUM(summa * COALESCE(rate_to_rub, 1)) AS total FROM {$this->table} WHERE user_id = :user_id AND YEAR(date) = :year AND type IN ('income','expense') GROUP BY MONTH(date), type ORDER BY MONTH(date)"; $stmt = $this->pdo->prepare($sql); $stmt->execute(['user_id' => $user_id, 'year' => $year]); $result = []; foreach ($stmt->fetchAll(PDO::FETCH_ASSOC) as $row) { $result[(int)$row['month']][$row['type']] = (float)$row['total']; } return $result; } /** * Расходы за месяц по категориям (топ 8) — для кругового распределения на аналитике. * * @param int $user_id * @param int $year * @param int $month * @return object[] [{title, total}] */ public function getMonthExpenseByCategory(int $user_id, int $year, int $month): array { $sql = "SELECT c.id AS categorie_id, c.title, SUM(t.summa * COALESCE(t.rate_to_rub, 1)) AS total FROM {$this->table} t JOIN categories c ON c.id = t.categorie_id WHERE t.user_id = :user_id AND t.type = 'expense' AND YEAR(t.date) = :year AND MONTH(t.date) = :month GROUP BY c.id, c.title ORDER BY total DESC LIMIT 8"; $stmt = $this->pdo->prepare($sql); $stmt->execute(['user_id' => $user_id, 'year' => $year, 'month' => $month]); return $stmt->fetchAll(PDO::FETCH_OBJ); } /** * Факт за месяц по статьям — сумма реальных операций (income/expense, не transfer — у тех * categorie_id = null), в рублях (см. бюджет_текущий_план.md — summa * COALESCE(rate_to_rub, 1)). * Для дашборда/плана: план/факт по категории. * * @param int $user_id * @param int $year * @param int $month * @return array [categorie_id => сумма] */ public function getMonthActualByCategory(int $user_id, int $year, int $month): array { $sql = "SELECT categorie_id, SUM(summa * COALESCE(rate_to_rub, 1)) AS s FROM $this->table WHERE user_id = :user_id AND categorie_id IS NOT NULL AND YEAR(date) = :year AND MONTH(date) = :month GROUP BY categorie_id"; $stmt = $this->pdo->prepare($sql); $stmt->execute(['user_id' => $user_id, 'year' => $year, 'month' => $month]); $result = []; foreach ($stmt->fetchAll(PDO::FETCH_ASSOC) as $row) { $result[(int)$row['categorie_id']] = (float)$row['s']; } return $result; } }