feat: cumulative balance with carried_over in finance summary
All checks were successful
CI / ci (push) Successful in 14s
All checks were successful
CI / ci (push) Successful in 14s
This commit is contained in:
@@ -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"`
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
Reference in New Issue
Block a user