Yimaru-BackEnd/internal/repository/institutions.go

191 lines
5.4 KiB
Go

package repository
import (
"context"
"database/sql"
"errors"
dbgen "github.com/SamuelTariku/FortuneBet-Backend/gen/db"
"github.com/SamuelTariku/FortuneBet-Backend/internal/domain"
"github.com/jackc/pgx/v5/pgtype"
)
type BankRepository interface {
CreateBank(ctx context.Context, bank *domain.Bank) error
GetBankByID(ctx context.Context, id int) (*domain.Bank, error)
GetAllBanks(
ctx context.Context,
countryID *int,
isActive *bool,
searchTerm *string,
page int,
pageSize int,
) ([]domain.Bank, int64, error)
UpdateBank(ctx context.Context, bank *domain.Bank) error
DeleteBank(ctx context.Context, id int) error
}
type BankRepo struct {
store *Store
}
func NewBankRepository(store *Store) BankRepository {
return &BankRepo{store: store}
}
func (r *BankRepo) CreateBank(ctx context.Context, bank *domain.Bank) error {
params := dbgen.CreateBankParams{
Slug: bank.Slug,
Swift: bank.Swift,
Name: bank.Name,
AcctLength: int32(bank.AcctLength),
CountryID: int32(bank.CountryID),
IsMobilemoney: pgtype.Int4{Int32: int32(bank.IsMobileMoney), Valid: true},
IsActive: int32(bank.IsActive),
IsRtgs: int32(bank.IsRTGS),
Active: int32(bank.Active),
Is24hrs: pgtype.Int4{Int32: int32(bank.Is24Hrs), Valid: true},
Currency: bank.Currency,
BankLogo: pgtype.Text{String: bank.BankLogo, Valid: true},
}
createdBank, err := r.store.queries.CreateBank(ctx, params)
if err != nil {
return err
}
// Update the ID and timestamps on the passed struct
bank.ID = int(createdBank.ID)
bank.CreatedAt = createdBank.CreatedAt.Time
bank.UpdatedAt = createdBank.UpdatedAt.Time
return nil
}
func (r *BankRepo) GetBankByID(ctx context.Context, id int) (*domain.Bank, error) {
dbBank, err := r.store.queries.GetBankByID(ctx, int64(id))
if err != nil {
if errors.Is(err, sql.ErrNoRows) {
return nil, nil
}
return nil, err
}
return mapDBBankToDomain(&dbBank), nil
}
func (r *BankRepo) GetAllBanks(
ctx context.Context,
countryID *int,
isActive *bool,
searchTerm *string,
page int,
pageSize int,
) ([]domain.Bank, int64, error) {
// Set default pagination values if not provided
if page < 1 {
page = 1
}
if pageSize < 1 || pageSize > 100 {
pageSize = 50
}
offset := (page - 1) * pageSize
params := dbgen.GetAllBanksParams{
CountryID: pgtype.Int4{},
IsActive: pgtype.Int4{},
SearchTerm: pgtype.Text{},
Limit: pgtype.Int4{Int32: int32(pageSize), Valid: true},
Offset: pgtype.Int4{Int32: int32(offset), Valid: true},
}
if countryID != nil {
params.CountryID = pgtype.Int4{Int32: int32(*countryID), Valid: true}
}
if isActive != nil {
var activeInt int32
if *isActive {
activeInt = 1
} else {
activeInt = 0
}
params.IsActive = pgtype.Int4{Int32: activeInt, Valid: true}
}
if searchTerm != nil {
params.SearchTerm = pgtype.Text{String: *searchTerm, Valid: true}
}
// Get paginated results
dbBanks, err := r.store.queries.GetAllBanks(ctx, params)
if err != nil {
return nil, 0, err
}
// Get total count for pagination
var countCountryID int32
if params.CountryID.Valid {
countCountryID = params.CountryID.Int32
}
total, err := r.store.queries.CountBanks(ctx, dbgen.CountBanksParams{
CountryID: countCountryID,
IsActive: params.IsActive.Int32,
})
if err != nil {
return nil, 0, err
}
banks := make([]domain.Bank, len(dbBanks))
for i, b := range dbBanks {
banks[i] = *mapDBBankToDomain(&b)
}
return banks, total, nil
}
func (r *BankRepo) UpdateBank(ctx context.Context, bank *domain.Bank) error {
params := dbgen.UpdateBankParams{
ID: int64(bank.ID),
Slug: pgtype.Text{String: bank.Slug, Valid: true},
Swift: pgtype.Text{String: bank.Swift, Valid: true},
Name: pgtype.Text{String: bank.Name, Valid: true},
AcctLength: pgtype.Int4{Int32: int32(bank.AcctLength), Valid: true},
CountryID: pgtype.Int4{Int32: int32(bank.CountryID), Valid: true},
IsMobilemoney: pgtype.Int4{Int32: int32(bank.IsMobileMoney), Valid: true},
IsActive: pgtype.Int4{Int32: int32(bank.IsActive), Valid: true},
IsRtgs: pgtype.Int4{Int32: int32(bank.IsRTGS), Valid: true},
Active: pgtype.Int4{Int32: int32(bank.Active), Valid: true},
Is24hrs: pgtype.Int4{Int32: int32(bank.Is24Hrs), Valid: true},
Currency: pgtype.Text{String: bank.Currency, Valid: true},
BankLogo: pgtype.Text{String: bank.BankLogo, Valid: true},
}
updatedBank, err := r.store.queries.UpdateBank(ctx, params)
if err != nil {
return err
}
// update timestamps in domain struct
bank.UpdatedAt = updatedBank.UpdatedAt.Time
return nil
}
func (r *BankRepo) DeleteBank(ctx context.Context, id int) error {
return r.store.queries.DeleteBank(ctx, int64(id))
}
// Helper to map DB struct to domain
func mapDBBankToDomain(dbBank *dbgen.Bank) *domain.Bank {
return &domain.Bank{
ID: int(dbBank.ID),
Slug: dbBank.Slug,
Swift: dbBank.Swift,
Name: dbBank.Name,
AcctLength: int(dbBank.AcctLength),
CountryID: int(dbBank.CountryID),
IsMobileMoney: int(dbBank.IsMobilemoney.Int32),
IsActive: int(dbBank.IsActive),
IsRTGS: int(dbBank.IsRtgs),
Active: int(dbBank.Active),
Is24Hrs: int(dbBank.Is24hrs.Int32),
CreatedAt: dbBank.CreatedAt.Time,
UpdatedAt: dbBank.UpdatedAt.Time,
Currency: dbBank.Currency,
BankLogo: dbBank.BankLogo.String,
}
}