v1.43.20 - FIX: Projeção de saldo inclui transações pendentes vencidas
This commit is contained in:
parent
e92cc8cf1f
commit
580d318e85
12
CHANGELOG.md
12
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/).
|
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
|
## [1.43.19] - 2025-12-16
|
||||||
|
|
||||||
### Changed
|
### Changed
|
||||||
|
|||||||
@ -916,8 +916,35 @@ public function projection(Request $request)
|
|||||||
// =========================================================================
|
// =========================================================================
|
||||||
// 5. TRANSAÇÕES EM ATRASO (overdue)
|
// 5. TRANSAÇÕES EM ATRASO (overdue)
|
||||||
// =========================================================================
|
// =========================================================================
|
||||||
|
$overdueIncome = 0;
|
||||||
$overdueExpense = 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
|
// Parcelas de passivos vencidas
|
||||||
$overdueInstallments = DB::select("
|
$overdueInstallments = DB::select("
|
||||||
SELECT li.installment_amount as amount, la.currency
|
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)
|
// Projeção simples (extrapolação linear)
|
||||||
$simpleProjectedExpense = ($currExpense / $daysElapsed) * $daysInMonth;
|
$simpleProjectedExpense = ($currExpense / $daysElapsed) * $daysInMonth;
|
||||||
$simpleProjectedIncome = ($currIncome / $daysElapsed) * $daysInMonth;
|
$simpleProjectedIncome = ($currIncome / $daysElapsed) * $daysInMonth;
|
||||||
|
|
||||||
// Projeção inteligente: realizado + pendente (recorrências + passivos)
|
// Projeção inteligente: realizado + pendente (todos os tipos)
|
||||||
$smartProjectedIncome = $currIncome + $recurringIncome;
|
$smartProjectedIncome = $currIncome + $recurringIncome + $overdueIncome + $pendingIncome;
|
||||||
$smartProjectedExpense = $currExpense + $recurringExpense + $liabilityExpense;
|
$smartProjectedExpense = $currExpense + $recurringExpense + $liabilityExpense + $overdueExpense + $pendingExpense;
|
||||||
|
|
||||||
return response()->json([
|
return response()->json([
|
||||||
'historical_average' => [
|
'historical_average' => [
|
||||||
@ -968,10 +1027,15 @@ public function projection(Request $request)
|
|||||||
'recurring_income' => round($recurringIncome, 2),
|
'recurring_income' => round($recurringIncome, 2),
|
||||||
'recurring_expense' => round($recurringExpense, 2),
|
'recurring_expense' => round($recurringExpense, 2),
|
||||||
'liability_installments' => round($liabilityExpense, 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' => [
|
'overdue' => [
|
||||||
'total' => round($overdueExpense, 2),
|
'income' => round($overdueIncome, 2),
|
||||||
|
'expense' => round($overdueExpense, 2),
|
||||||
|
'total' => round($overdueExpense - $overdueIncome, 2),
|
||||||
],
|
],
|
||||||
'projection' => [
|
'projection' => [
|
||||||
// Valores principais (usa projeção inteligente)
|
// Valores principais (usa projeção inteligente)
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user