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 }