diff --git a/backend/internal/modules/wallet/repository.go b/backend/internal/modules/wallet/repository.go index 0c2ca3c..4ce8eba 100644 --- a/backend/internal/modules/wallet/repository.go +++ b/backend/internal/modules/wallet/repository.go @@ -4,6 +4,7 @@ import ( "crypto/rand" "encoding/hex" "fmt" + "math" "time" "hfb_sys/backend/internal/model" @@ -118,6 +119,7 @@ func (r *Repository) AdminLedger(query AdminLedgerQuery) (*PaginatedResult, erro func AppendEntries(tx *gorm.DB, entries ...Entry) error { for _, entry := range entries { + entry.Amount = roundWalletMoney(entry.Amount) if entry.Amount <= 0 { continue } @@ -169,25 +171,28 @@ func ensureAccount(tx *gorm.DB, userID uint64) error { } func applyEntry(account *model.WalletAccount, entry Entry) (float64, error) { + entry.Amount = roundWalletMoney(entry.Amount) + account.AvailableBalance = roundWalletMoney(account.AvailableBalance) + account.FrozenBalance = roundWalletMoney(account.FrozenBalance) switch entry.BalanceType { case "available": if entry.Direction == "in" { - account.AvailableBalance += entry.Amount + account.AvailableBalance = roundWalletMoney(account.AvailableBalance + entry.Amount) } else { if account.AvailableBalance < entry.Amount { return 0, ErrInsufficientBalance } - account.AvailableBalance -= entry.Amount + account.AvailableBalance = roundWalletMoney(account.AvailableBalance - entry.Amount) } return account.AvailableBalance, nil case "frozen": if entry.Direction == "in" { - account.FrozenBalance += entry.Amount + account.FrozenBalance = roundWalletMoney(account.FrozenBalance + entry.Amount) } else { if account.FrozenBalance < entry.Amount { return 0, ErrInsufficientBalance } - account.FrozenBalance -= entry.Amount + account.FrozenBalance = roundWalletMoney(account.FrozenBalance - entry.Amount) } return account.FrozenBalance, nil default: @@ -195,6 +200,10 @@ func applyEntry(account *model.WalletAccount, entry Entry) (float64, error) { } } +func roundWalletMoney(value float64) float64 { + return math.Round(value*100) / 100 +} + func toAccountDTO(account model.WalletAccount) *AccountDTO { return &AccountDTO{ UserID: account.UserID, diff --git a/backend/internal/modules/wallet/repository_test.go b/backend/internal/modules/wallet/repository_test.go new file mode 100644 index 0000000..d6b0c84 --- /dev/null +++ b/backend/internal/modules/wallet/repository_test.go @@ -0,0 +1,31 @@ +package wallet + +import ( + "testing" + + "hfb_sys/backend/internal/model" +) + +func TestApplyEntryRoundsMoneyBeforeComparing(t *testing.T) { + account := model.WalletAccount{ + UserID: 7, + FrozenBalance: 606.41, + } + entry := Entry{ + UserID: 7, + Direction: "out", + Amount: 406.41 + 200.00, + BalanceType: "frozen", + } + + balanceAfter, err := applyEntry(&account, entry) + if err != nil { + t.Fatalf("applyEntry() error = %v", err) + } + if balanceAfter != 0 { + t.Fatalf("balanceAfter = %v, want 0", balanceAfter) + } + if account.FrozenBalance != 0 { + t.Fatalf("FrozenBalance = %v, want 0", account.FrozenBalance) + } +}