feat: cumulative balance with carried_over in finance summary
All checks were successful
CI / ci (push) Successful in 14s

This commit is contained in:
Cosmo
2026-03-01 05:22:56 +00:00
parent e782367ef0
commit 9e06341564
2 changed files with 22 additions and 2 deletions

View File

@@ -73,6 +73,7 @@ type UpdateFinanceTransactionRequest struct {
} }
type FinanceSummary struct { type FinanceSummary struct {
CarriedOver float64 `json:"carried_over"`
Balance float64 `json:"balance"` Balance float64 `json:"balance"`
TotalIncome float64 `json:"total_income"` TotalIncome float64 `json:"total_income"`
TotalExpense float64 `json:"total_expense"` TotalExpense float64 `json:"total_expense"`

View File

@@ -237,15 +237,34 @@ func (r *FinanceRepository) DeleteTransaction(id, userID int64) error {
func (r *FinanceRepository) GetSummary(userID int64, month, year int) (*model.FinanceSummary, error) { func (r *FinanceRepository) GetSummary(userID int64, month, year int) (*model.FinanceSummary, error) {
summary := &model.FinanceSummary{} summary := &model.FinanceSummary{}
// First day of selected month and last day of selected month
firstDay := time.Date(year, time.Month(month), 1, 0, 0, 0, 0, time.UTC)
lastDay := firstDay.AddDate(0, 1, -1)
// Carried over: balance of all transactions BEFORE the selected month
err := r.db.QueryRow(`SELECT COALESCE(SUM(CASE WHEN type='income' THEN amount ELSE -amount END), 0)
FROM finance_transactions WHERE user_id=$1 AND date < $2`,
userID, firstDay).Scan(&summary.CarriedOver)
if err != nil {
return nil, err
}
// Total income & expense for the month // Total income & expense for the month
err := r.db.QueryRow(`SELECT COALESCE(SUM(CASE WHEN type='income' THEN amount ELSE 0 END),0), err = r.db.QueryRow(`SELECT COALESCE(SUM(CASE WHEN type='income' THEN amount ELSE 0 END),0),
COALESCE(SUM(CASE WHEN type='expense' THEN amount ELSE 0 END),0) COALESCE(SUM(CASE WHEN type='expense' THEN amount ELSE 0 END),0)
FROM finance_transactions WHERE user_id=$1 AND EXTRACT(MONTH FROM date)=$2 AND EXTRACT(YEAR FROM date)=$3`, FROM finance_transactions WHERE user_id=$1 AND EXTRACT(MONTH FROM date)=$2 AND EXTRACT(YEAR FROM date)=$3`,
userID, month, year).Scan(&summary.TotalIncome, &summary.TotalExpense) userID, month, year).Scan(&summary.TotalIncome, &summary.TotalExpense)
if err != nil { if err != nil {
return nil, err return nil, err
} }
summary.Balance = summary.TotalIncome - summary.TotalExpense
// Cumulative balance: all transactions up to end of selected month
err = r.db.QueryRow(`SELECT COALESCE(SUM(CASE WHEN type='income' THEN amount ELSE -amount END), 0)
FROM finance_transactions WHERE user_id=$1 AND date <= $2`,
userID, lastDay).Scan(&summary.Balance)
if err != nil {
return nil, err
}
// By category // By category
rows, err := r.db.Query(`SELECT c.id, c.name, c.emoji, t.type, SUM(t.amount) as amount rows, err := r.db.Query(`SELECT c.id, c.name, c.emoji, t.type, SUM(t.amount) as amount