feat: edit transactions

This commit is contained in:
juancwu 2026-05-03 23:16:08 +00:00
commit 283a157b29
11 changed files with 998 additions and 14 deletions

View file

@ -1,6 +1,7 @@
package repository
import (
"database/sql"
"time"
"git.juancwu.dev/juancwu/budgit/internal/model"
@ -11,6 +12,10 @@ import (
type TransactionRepository interface {
CreateBillAtomic(t *model.Transaction, newBalance decimal.Decimal, categoryID *string) error
CreateDepositAtomic(t *model.Transaction, newBalance decimal.Decimal) error
UpdateBillAtomic(t *model.Transaction, newBalance decimal.Decimal, categoryID *string) error
UpdateDepositAtomic(t *model.Transaction, newBalance decimal.Decimal) error
GetByID(id string) (*model.Transaction, error)
GetCategoryID(transactionID string) (*string, error)
ListByAccount(accountID string, limit, offset int) ([]*model.Transaction, error)
CountByAccount(accountID string) (int, error)
}
@ -79,6 +84,85 @@ func (r *transactionRepository) CreateDepositAtomic(t *model.Transaction, newBal
})
}
func (r *transactionRepository) UpdateBillAtomic(t *model.Transaction, newBalance decimal.Decimal, categoryID *string) error {
return WithTx(r.db, func(tx *sqlx.Tx) error {
updateTxn := `
UPDATE transactions
SET value = $1, title = $2, description = $3, occurred_at = $4, updated_at = $5
WHERE id = $6;
`
if _, err := tx.Exec(
updateTxn,
t.Value, t.Title, t.Description, t.OccurredAt, t.UpdatedAt, t.ID,
); err != nil {
return err
}
updateBalance := `UPDATE accounts SET balance = $1, updated_at = $2 WHERE id = $3;`
if _, err := tx.Exec(updateBalance, newBalance, time.Now(), t.AccountID); err != nil {
return err
}
if _, err := tx.Exec(`DELETE FROM transaction_categories WHERE transaction_id = $1;`, t.ID); err != nil {
return err
}
if categoryID != nil && *categoryID != "" {
linkCategory := `INSERT INTO transaction_categories (category_id, transaction_id) VALUES ($1, $2);`
if _, err := tx.Exec(linkCategory, *categoryID, t.ID); err != nil {
return err
}
}
return nil
})
}
func (r *transactionRepository) UpdateDepositAtomic(t *model.Transaction, newBalance decimal.Decimal) error {
return WithTx(r.db, func(tx *sqlx.Tx) error {
updateTxn := `
UPDATE transactions
SET value = $1, title = $2, description = $3, occurred_at = $4, updated_at = $5
WHERE id = $6;
`
if _, err := tx.Exec(
updateTxn,
t.Value, t.Title, t.Description, t.OccurredAt, t.UpdatedAt, t.ID,
); err != nil {
return err
}
updateBalance := `UPDATE accounts SET balance = $1, updated_at = $2 WHERE id = $3;`
if _, err := tx.Exec(updateBalance, newBalance, time.Now(), t.AccountID); err != nil {
return err
}
return nil
})
}
func (r *transactionRepository) GetByID(id string) (*model.Transaction, error) {
query := `
SELECT id, value, type, account_id, title, description, occurred_at, created_at, updated_at
FROM transactions
WHERE id = $1;
`
t := &model.Transaction{}
if err := r.db.Get(t, query, id); err != nil {
return nil, err
}
return t, nil
}
func (r *transactionRepository) GetCategoryID(transactionID string) (*string, error) {
var id string
err := r.db.Get(&id, `SELECT category_id FROM transaction_categories WHERE transaction_id = $1 LIMIT 1;`, transactionID)
if err != nil {
if err == sql.ErrNoRows {
return nil, nil
}
return nil, err
}
return &id, nil
}
func (r *transactionRepository) ListByAccount(accountID string, limit, offset int) ([]*model.Transaction, error) {
query := `
SELECT id, value, type, account_id, title, description, occurred_at, created_at, updated_at