diff --git a/CHANGELOG.md b/CHANGELOG.md index d7023fc..e0c14ac 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,18 @@ O formato segue [Keep a Changelog](https://keepachangelog.com/pt-BR/). Este projeto adota [Versionamento Semântico](https://semver.org/pt-BR/). +## [1.38.0] - 2025-12-15 + +### Added +- **Projeção de Saldo** - Agora considera transações em atraso + - Backend busca todas as transações pendentes (incluindo atrasadas) + - Processa transações atrasadas ANTES do ponto inicial da projeção + - Adiciona informações de transações em atraso no summary da API + - Frontend exibe alerta amarelo quando há transações em atraso incluídas + - Alerta mostra quantidade de transações e impacto no saldo + - Traduções completas: overdueIncluded, overdueTransactions, includedInProjection (pt-BR, en, es) + - Melhora precisão da projeção ao incluir todas as pendências + ## [1.37.0] - 2025-12-15 ### Added diff --git a/VERSION b/VERSION index bf50e91..ebeef2f 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -1.37.0 +1.38.0 diff --git a/backend/app/Http/Controllers/Api/ReportController.php b/backend/app/Http/Controllers/Api/ReportController.php index e69946c..a6ace8a 100644 --- a/backend/app/Http/Controllers/Api/ReportController.php +++ b/backend/app/Http/Controllers/Api/ReportController.php @@ -942,29 +942,45 @@ public function projectionChart(Request $request) ORDER BY li.due_date ", [$this->userId, $today->toDateString(), $endDate->toDateString()]); - // Buscar transações agendadas/pendentes + // Buscar transações agendadas/pendentes (incluindo atrasadas) $scheduledTransactions = DB::select(" SELECT t.effective_date as date, t.amount, t.type, - COALESCE(a.currency, 'EUR') as currency + COALESCE(a.currency, 'EUR') as currency, + CASE WHEN t.effective_date < ? THEN 1 ELSE 0 END as is_overdue FROM transactions t LEFT JOIN accounts a ON t.account_id = a.id WHERE t.user_id = ? AND t.status IN ('pending', 'scheduled') - AND t.effective_date >= ? AND t.effective_date <= ? AND t.deleted_at IS NULL ORDER BY t.effective_date - ", [$this->userId, $today->toDateString(), $endDate->toDateString()]); + ", [$today->toDateString(), $this->userId, $endDate->toDateString()]); - // Ponto inicial + // Separar transações atrasadas para processar primeiro + $overdueTransactions = array_filter($scheduledTransactions, fn($tx) => $tx->is_overdue); + $futureTransactions = array_filter($scheduledTransactions, fn($tx) => !$tx->is_overdue); + + // Processar transações atrasadas ANTES do ponto inicial + foreach ($overdueTransactions as $tx) { + $amount = $this->convertToPrimaryCurrency(abs($tx->amount), $tx->currency); + if ($tx->type === 'credit') { + $currentBalance += $amount; + } else { + $currentBalance -= $amount; + } + $runningBalance = $currentBalance; + } + + // Ponto inicial (já inclui o impacto das transações atrasadas) $dataPoints[] = [ 'date' => $today->toDateString(), 'balance' => round($runningBalance, 2), 'label' => $today->format('d/m'), 'isToday' => true, + 'has_overdue' => count($overdueTransactions) > 0, ]; // Gerar pontos até a data final @@ -1001,8 +1017,8 @@ public function projectionChart(Request $request) } } - // Somar transações agendadas neste período - foreach ($scheduledTransactions as $tx) { + // Somar transações agendadas neste período (apenas futuras) + foreach ($futureTransactions as $tx) { if ($tx->date > $periodStart && $tx->date <= $periodEnd) { $amount = $this->convertToPrimaryCurrency(abs($tx->amount), $tx->currency); if ($tx->type === 'credit') { @@ -1048,6 +1064,11 @@ public function projectionChart(Request $request) 'change' => round($finalBalance - $currentBalance, 2), 'change_percent' => $currentBalance != 0 ? round((($finalBalance - $currentBalance) / abs($currentBalance)) * 100, 1) : 0, 'negative_month' => $negativeMonth, + 'overdue_count' => count($overdueTransactions), + 'overdue_impact' => round(array_reduce($overdueTransactions, function($carry, $tx) { + $amount = $this->convertToPrimaryCurrency(abs($tx->amount), $tx->currency); + return $carry + ($tx->type === 'credit' ? $amount : -$amount); + }, 0), 2), ], 'period' => [ 'start' => $today->toDateString(), diff --git a/frontend/src/components/dashboard/BalanceProjectionChart.jsx b/frontend/src/components/dashboard/BalanceProjectionChart.jsx index 0de2e00..44be99c 100644 --- a/frontend/src/components/dashboard/BalanceProjectionChart.jsx +++ b/frontend/src/components/dashboard/BalanceProjectionChart.jsx @@ -228,7 +228,24 @@ const BalanceProjectionChart = () => {