v1.43.20 - FIX: Projeção de saldo inclui transações pendentes vencidas

This commit is contained in:
marcoitaloesp-ai 2025-12-16 20:10:54 +00:00 committed by GitHub
parent e92cc8cf1f
commit 580d318e85
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 83 additions and 7 deletions

View File

@ -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.43.20] - 2025-12-16
### Fixed
- **Projeção de Saldo - Transações Pendentes Vencidas**
- FIX: Projeção agora inclui transações pendentes vencidas (status='pending' e planned_date < hoje)
- Adicionadas transações pendentes futuras (planned_date entre hoje e fim do mês)
- Separação clara entre transações vencidas (overdue) e pendentes (pending_this_month)
- Response JSON atualizado com breakdown completo:
* `overdue.income` e `overdue.expense` (transações vencidas)
* `pending_this_month.pending_income` e `pending_expense` (transações futuras)
- Projeção inteligente agora considera: realizado + recorrências + passivos + vencidos + pendentes
## [1.43.19] - 2025-12-16
### Changed

View File

@ -1 +1 @@
1.43.19
1.43.20

View File

@ -916,8 +916,35 @@ public function projection(Request $request)
// =========================================================================
// 5. TRANSAÇÕES EM ATRASO (overdue)
// =========================================================================
$overdueIncome = 0;
$overdueExpense = 0;
// Transações pendentes vencidas (status='pending' e planned_date < hoje)
$overduePendingTransactions = DB::select("
SELECT
t.amount,
t.type,
COALESCE(a.currency, 'EUR') as currency
FROM transactions t
LEFT JOIN accounts a ON t.account_id = a.id
WHERE t.user_id = ?
AND t.status = 'pending'
AND t.planned_date < ?
AND t.deleted_at IS NULL
AND {$this->excludeTransfers()}
", [$this->userId, $today]);
foreach ($overduePendingTransactions as $row) {
$amount = abs($row->amount);
$converted = $this->convertToPrimaryCurrency($amount, $row->currency);
if ($row->type === 'credit') {
$overdueIncome += $converted;
} else {
$overdueExpense += $converted;
}
}
// Parcelas de passivos vencidas
$overdueInstallments = DB::select("
SELECT li.installment_amount as amount, la.currency
@ -940,16 +967,48 @@ public function projection(Request $request)
}
// =========================================================================
// 6. CÁLCULOS FINAIS DA PROJEÇÃO
// 6. TRANSAÇÕES PENDENTES ATÉ O FIM DO MÊS (planned_date entre hoje e fim do mês)
// =========================================================================
$pendingIncome = 0;
$pendingExpense = 0;
$pendingTransactions = DB::select("
SELECT
t.amount,
t.type,
COALESCE(a.currency, 'EUR') as currency
FROM transactions t
LEFT JOIN accounts a ON t.account_id = a.id
WHERE t.user_id = ?
AND t.status = 'pending'
AND t.planned_date >= ?
AND t.planned_date <= ?
AND t.deleted_at IS NULL
AND {$this->excludeTransfers()}
", [$this->userId, $today, $endOfMonth]);
foreach ($pendingTransactions as $row) {
$amount = abs($row->amount);
$converted = $this->convertToPrimaryCurrency($amount, $row->currency);
if ($row->type === 'credit') {
$pendingIncome += $converted;
} else {
$pendingExpense += $converted;
}
}
// =========================================================================
// 7. CÁLCULOS FINAIS DA PROJEÇÃO
// =========================================================================
// Projeção simples (extrapolação linear)
$simpleProjectedExpense = ($currExpense / $daysElapsed) * $daysInMonth;
$simpleProjectedIncome = ($currIncome / $daysElapsed) * $daysInMonth;
// Projeção inteligente: realizado + pendente (recorrências + passivos)
$smartProjectedIncome = $currIncome + $recurringIncome;
$smartProjectedExpense = $currExpense + $recurringExpense + $liabilityExpense;
// Projeção inteligente: realizado + pendente (todos os tipos)
$smartProjectedIncome = $currIncome + $recurringIncome + $overdueIncome + $pendingIncome;
$smartProjectedExpense = $currExpense + $recurringExpense + $liabilityExpense + $overdueExpense + $pendingExpense;
return response()->json([
'historical_average' => [
@ -968,10 +1027,15 @@ public function projection(Request $request)
'recurring_income' => round($recurringIncome, 2),
'recurring_expense' => round($recurringExpense, 2),
'liability_installments' => round($liabilityExpense, 2),
'total_pending_expense' => round($recurringExpense + $liabilityExpense, 2),
'pending_income' => round($pendingIncome, 2),
'pending_expense' => round($pendingExpense, 2),
'total_pending_income' => round($recurringIncome + $pendingIncome, 2),
'total_pending_expense' => round($recurringExpense + $liabilityExpense + $pendingExpense, 2),
],
'overdue' => [
'total' => round($overdueExpense, 2),
'income' => round($overdueIncome, 2),
'expense' => round($overdueExpense, 2),
'total' => round($overdueExpense - $overdueIncome, 2),
],
'projection' => [
// Valores principais (usa projeção inteligente)