feat: add currency to accounts
This commit is contained in:
parent
4be5385db7
commit
ca0fec563e
21 changed files with 627 additions and 63 deletions
|
|
@ -3,11 +3,21 @@ package repository
|
|||
import (
|
||||
"database/sql"
|
||||
"errors"
|
||||
"time"
|
||||
|
||||
"git.juancwu.dev/juancwu/budgit/internal/model"
|
||||
"github.com/jmoiron/sqlx"
|
||||
"github.com/shopspring/decimal"
|
||||
)
|
||||
|
||||
// AllocationConversion describes the converted amount/target for a single
|
||||
// allocation row when an account's currency is changed.
|
||||
type AllocationConversion struct {
|
||||
ID string
|
||||
Amount decimal.Decimal
|
||||
TargetAmount *decimal.Decimal
|
||||
}
|
||||
|
||||
var ErrAccountNotFound = errors.New("account not found")
|
||||
|
||||
type AccountRepository interface {
|
||||
|
|
@ -16,6 +26,9 @@ type AccountRepository interface {
|
|||
BySpaceID(spaceID string) ([]*model.Account, error)
|
||||
Rename(id, name string) error
|
||||
Delete(id string) error
|
||||
// ChangeCurrency atomically updates an account's currency and balance and
|
||||
// rewrites each provided allocation's amount/target in the new currency.
|
||||
ChangeCurrency(accountID, newCurrency string, newBalance decimal.Decimal, allocationConversions []AllocationConversion) error
|
||||
}
|
||||
|
||||
type accountRepository struct {
|
||||
|
|
@ -27,9 +40,9 @@ func NewAccountRepository(db *sqlx.DB) AccountRepository {
|
|||
}
|
||||
|
||||
func (r *accountRepository) Create(account *model.Account) error {
|
||||
query := `INSERT INTO accounts (id, name, space_id, created_at, updated_at)
|
||||
VALUES ($1, $2, $3, $4, $5);`
|
||||
_, err := r.db.Exec(query, account.ID, account.Name, account.SpaceID, account.CreatedAt, account.UpdatedAt)
|
||||
query := `INSERT INTO accounts (id, name, space_id, currency, created_at, updated_at)
|
||||
VALUES ($1, $2, $3, $4, $5, $6);`
|
||||
_, err := r.db.Exec(query, account.ID, account.Name, account.SpaceID, account.Currency, account.CreatedAt, account.UpdatedAt)
|
||||
return err
|
||||
}
|
||||
|
||||
|
|
@ -64,3 +77,24 @@ func (r *accountRepository) Delete(id string) error {
|
|||
_, err := r.db.Exec(query, id)
|
||||
return err
|
||||
}
|
||||
|
||||
func (r *accountRepository) ChangeCurrency(accountID, newCurrency string, newBalance decimal.Decimal, allocationConversions []AllocationConversion) error {
|
||||
return WithTx(r.db, func(tx *sqlx.Tx) error {
|
||||
now := time.Now()
|
||||
if _, err := tx.Exec(
|
||||
`UPDATE accounts SET currency = $1, balance = $2, updated_at = $3 WHERE id = $4;`,
|
||||
newCurrency, newBalance, now, accountID,
|
||||
); err != nil {
|
||||
return err
|
||||
}
|
||||
for _, c := range allocationConversions {
|
||||
if _, err := tx.Exec(
|
||||
`UPDATE allocations SET amount = $1, target_amount = $2, updated_at = $3 WHERE id = $4;`,
|
||||
c.Amount, c.TargetAmount, now, c.ID,
|
||||
); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
})
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue