Yimaru-BackEnd/internal/repository/wallet.go

260 lines
7.8 KiB
Go

package repository
import (
"context"
"fmt"
dbgen "github.com/SamuelTariku/FortuneBet-Backend/gen/db"
"github.com/SamuelTariku/FortuneBet-Backend/internal/domain"
)
func convertDBWallet(wallet dbgen.Wallet) domain.Wallet {
return domain.Wallet{
ID: wallet.ID,
Balance: domain.Currency(wallet.Balance),
IsWithdraw: wallet.IsWithdraw,
IsBettable: wallet.IsBettable,
IsTransferable: wallet.IsTransferable,
IsActive: wallet.IsActive,
UserID: wallet.UserID,
UpdatedAt: wallet.UpdatedAt.Time,
CreatedAt: wallet.CreatedAt.Time,
}
}
func convertCreateWallet(wallet domain.CreateWallet) dbgen.CreateWalletParams {
return dbgen.CreateWalletParams{
IsWithdraw: wallet.IsWithdraw,
IsBettable: wallet.IsBettable,
IsTransferable: wallet.IsTransferable,
UserID: wallet.UserID,
}
}
func convertDBCustomerWallet(customerWallet dbgen.CustomerWallet) domain.CustomerWallet {
return domain.CustomerWallet{
ID: customerWallet.ID,
RegularID: customerWallet.RegularWalletID,
StaticID: customerWallet.StaticWalletID,
CustomerID: customerWallet.CustomerID,
}
}
func convertCreateCustomerWallet(customerWallet domain.CreateCustomerWallet) dbgen.CreateCustomerWalletParams {
return dbgen.CreateCustomerWalletParams{
CustomerID: customerWallet.CustomerID,
RegularWalletID: customerWallet.RegularWalletID,
StaticWalletID: customerWallet.StaticWalletID,
}
}
func convertDBGetCustomerWallet(customerWallet dbgen.GetCustomerWalletRow) domain.GetCustomerWallet {
return domain.GetCustomerWallet{
ID: customerWallet.ID,
RegularID: customerWallet.RegularID,
RegularBalance: domain.Currency(customerWallet.RegularBalance),
StaticID: customerWallet.StaticID,
StaticBalance: domain.Currency(customerWallet.StaticBalance),
CustomerID: customerWallet.CustomerID,
RegularUpdatedAt: customerWallet.RegularUpdatedAt.Time,
StaticUpdatedAt: customerWallet.StaticUpdatedAt.Time,
CreatedAt: customerWallet.CreatedAt.Time,
}
}
func (s *Store) CreateWallet(ctx context.Context, wallet domain.CreateWallet) (domain.Wallet, error) {
newWallet, err := s.queries.CreateWallet(ctx, convertCreateWallet(wallet))
if err != nil {
return domain.Wallet{}, err
}
return convertDBWallet(newWallet), nil
}
func (s *Store) CreateCustomerWallet(ctx context.Context, customerWallet domain.CreateCustomerWallet) (domain.CustomerWallet, error) {
newCustomerWallet, err := s.queries.CreateCustomerWallet(ctx, convertCreateCustomerWallet(customerWallet))
if err != nil {
return domain.CustomerWallet{}, err
}
return convertDBCustomerWallet(newCustomerWallet), nil
}
func (s *Store) GetWalletByID(ctx context.Context, id int64) (domain.Wallet, error) {
wallet, err := s.queries.GetWalletByID(ctx, id)
if err != nil {
return domain.Wallet{}, err
}
return convertDBWallet(wallet), nil
}
func (s *Store) GetAllWallets(ctx context.Context) ([]domain.Wallet, error) {
wallets, err := s.queries.GetAllWallets(ctx)
if err != nil {
return nil, err
}
var result []domain.Wallet = make([]domain.Wallet, 0, len(wallets))
for _, wallet := range wallets {
result = append(result, convertDBWallet(wallet))
}
return result, nil
}
func (s *Store) GetWalletsByUser(ctx context.Context, userID int64) ([]domain.Wallet, error) {
wallets, err := s.queries.GetWalletByUserID(ctx, userID)
if err != nil {
return nil, err
}
var result []domain.Wallet = make([]domain.Wallet, 0, len(wallets))
for _, wallet := range wallets {
result = append(result, convertDBWallet(wallet))
}
return result, nil
}
func (s *Store) GetCustomerWallet(ctx context.Context, customerID int64) (domain.GetCustomerWallet, error) {
customerWallet, err := s.queries.GetCustomerWallet(ctx, customerID)
if err != nil {
return domain.GetCustomerWallet{}, err
}
return convertDBGetCustomerWallet(customerWallet), nil
}
func (s *Store) GetAllBranchWallets(ctx context.Context) ([]domain.BranchWallet, error) {
wallets, err := s.queries.GetAllBranchWallets(ctx)
if err != nil {
return nil, err
}
var result []domain.BranchWallet = make([]domain.BranchWallet, 0, len(wallets))
for _, wallet := range wallets {
result = append(result, domain.BranchWallet{
ID: wallet.ID,
Balance: domain.Currency(wallet.Balance),
IsActive: wallet.IsActive,
UpdatedAt: wallet.UpdatedAt.Time,
CreatedAt: wallet.CreatedAt.Time,
Name: wallet.Name,
Location: wallet.Location,
BranchManagerID: wallet.BranchManagerID,
CompanyID: wallet.CompanyID,
IsSelfOwned: wallet.IsSelfOwned,
})
}
return result, nil
}
func (s *Store) UpdateBalance(ctx context.Context, id int64, balance domain.Currency) error {
err := s.queries.UpdateBalance(ctx, dbgen.UpdateBalanceParams{
ID: id,
Balance: int64(balance),
})
return err
}
func (s *Store) UpdateWalletActive(ctx context.Context, id int64, isActive bool) error {
err := s.queries.UpdateWalletActive(ctx, dbgen.UpdateWalletActiveParams{
ID: id,
IsActive: isActive,
})
return err
}
// GetBalanceSummary returns wallet balance summary
func (s *Store) GetBalanceSummary(ctx context.Context, filter domain.ReportFilter) (domain.BalanceSummary, error) {
var summary domain.BalanceSummary
query := `SELECT
COALESCE(SUM(balance), 0) as total_balance,
COALESCE(SUM(CASE WHEN is_active = true THEN balance ELSE 0 END), 0) as active_balance,
COALESCE(SUM(CASE WHEN is_active = false THEN balance ELSE 0 END), 0) as inactive_balance,
COALESCE(SUM(CASE WHEN is_bettable = true THEN balance ELSE 0 END), 0) as bettable_balance,
COALESCE(SUM(CASE WHEN is_bettable = false THEN balance ELSE 0 END), 0) as non_bettable_balance
FROM wallets`
args := []interface{}{}
argPos := 1
// Add filters if provided
if filter.CompanyID.Valid {
query += fmt.Sprintf(" WHERE user_id IN (SELECT id FROM users WHERE company_id = $%d)", argPos)
args = append(args, filter.CompanyID.Value)
argPos++
} else if filter.BranchID.Valid {
query += fmt.Sprintf(" WHERE user_id IN (SELECT user_id FROM branch_cashiers WHERE branch_id = $%d)", argPos)
args = append(args, filter.BranchID.Value)
argPos++
} else if filter.UserID.Valid {
query += fmt.Sprintf(" WHERE user_id = $%d", argPos)
args = append(args, filter.UserID.Value)
argPos++
}
if filter.StartTime.Valid {
query += fmt.Sprintf(" AND %screated_at >= $%d", func() string {
if len(args) == 0 {
return ""
}
return " "
}(), argPos)
args = append(args, filter.StartTime.Value)
argPos++
}
if filter.EndTime.Valid {
query += fmt.Sprintf(" AND created_at <= $%d", argPos)
args = append(args, filter.EndTime.Value)
argPos++
}
row := s.conn.QueryRow(ctx, query, args...)
err := row.Scan(
&summary.TotalBalance,
&summary.ActiveBalance,
&summary.InactiveBalance,
&summary.BettableBalance,
&summary.NonBettableBalance,
)
if err != nil {
return domain.BalanceSummary{}, fmt.Errorf("failed to get balance summary: %w", err)
}
return summary, nil
}
func (s *Store) GetTotalWallets(ctx context.Context, filter domain.ReportFilter) (int64, error) {
query := `SELECT COUNT(*) FROM wallets WHERE is_active = true`
args := []interface{}{}
argPos := 1
// Add filters if provided
if filter.StartTime.Valid {
query += fmt.Sprintf(" AND %screated_at >= $%d", func() string {
if len(args) == 0 {
return " WHERE "
}
return " AND "
}(), argPos)
args = append(args, filter.StartTime.Value)
argPos++
}
if filter.EndTime.Valid {
query += fmt.Sprintf(" AND created_at <= $%d", argPos)
args = append(args, filter.EndTime.Value)
argPos++
}
var total int64
row := s.conn.QueryRow(ctx, query, args...)
err := row.Scan(&total)
if err != nil {
return 0, fmt.Errorf("failed to get wallet counts: %w", err)
}
return total, nil
}