Yimaru-BackEnd/internal/repository/direct_deposit.go

197 lines
4.9 KiB
Go

package repository
import (
"context"
"time"
dbgen "github.com/SamuelTariku/FortuneBet-Backend/gen/db"
"github.com/SamuelTariku/FortuneBet-Backend/internal/domain"
"github.com/jackc/pgx/v5/pgtype"
)
type DirectDepositRepository interface {
CreateDirectDeposit(ctx context.Context, deposit *domain.DirectDeposit) error
GetDirectDepositsByStatus(ctx context.Context, status string, page int, pageSize int) ([]domain.DirectDeposit, int64, error)
ApproveDirectDeposit(ctx context.Context, depositID int, adminID int) error
RejectDirectDeposit(ctx context.Context, depositID int, adminID int, reason string) error
DeleteDirectDeposit(ctx context.Context, id int) error
GetDirectDepositByID(ctx context.Context, id int) (*domain.DirectDeposit, error)
}
type DirectDepositRepo struct {
store *Store
}
func NewDirectDepositRepository(store *Store) DirectDepositRepository {
return &DirectDepositRepo{store: store}
}
func (r *DirectDepositRepo) CreateDirectDeposit(ctx context.Context, deposit *domain.DirectDeposit) error {
params := dbgen.CreateDirectDepositParams{
CustomerID: pgtype.Int8{Int64: int64(deposit.CustomerID)},
WalletID: pgtype.Int8{Int64: int64(deposit.WalletID)},
BankName: pgtype.Text{String: deposit.BankName},
AccountNumber: pgtype.Text{String: deposit.AccountNumber},
AccountHolder: pgtype.Text{String: deposit.AccountHolder},
Amount: pgtype.Numeric{Exp: int32(deposit.Amount)},
ReferenceNumber: pgtype.Text{String: deposit.ReferenceNumber},
TransferScreenshot: pgtype.Text{String: deposit.TransferScreenshot},
}
dbDeposit, err := r.store.queries.CreateDirectDeposit(ctx, params)
if err != nil {
return err
}
// Map back to domain struct
deposit.ID = int(dbDeposit.ID)
deposit.Status = dbDeposit.Status.String
deposit.CreatedAt = dbDeposit.CreatedAt.Time
return nil
}
func (r *DirectDepositRepo) GetDirectDepositsByStatus(
ctx context.Context,
status string,
page int,
pageSize int,
) ([]domain.DirectDeposit, int64, error) {
// Default pagination rules
if page < 1 {
page = 1
}
if pageSize < 1 || pageSize > 100 {
pageSize = 50
}
offset := (page - 1) * pageSize
params := dbgen.GetDirectDepositsByStatusParams{
Status: pgtype.Text{String: status},
Limit: int32(pageSize),
Offset: int32(offset),
}
dbItems, err := r.store.queries.GetDirectDepositsByStatus(ctx, params)
if err != nil {
return nil, 0, err
}
total, err := r.store.queries.CountDirectDepositsByStatus(ctx, pgtype.Text{String: status})
if err != nil {
return nil, 0, err
}
deposits := make([]domain.DirectDeposit, len(dbItems))
for i, d := range dbItems {
deposits[i] = *mapDBDirectDepositToDomain(&d)
}
return deposits, total, nil
}
func (r *DirectDepositRepo) ApproveDirectDeposit(
ctx context.Context,
depositID int,
adminID int,
) error {
params := dbgen.ApproveDirectDepositParams{
ID: int64(depositID),
ApprovedBy: pgtype.Int8{Int64: int64(adminID)},
}
err := r.store.queries.ApproveDirectDeposit(ctx, params)
if err != nil {
return err
}
return nil
}
func (r *DirectDepositRepo) GetDirectDepositByID(
ctx context.Context,
id int,
) (*domain.DirectDeposit, error) {
dbDeposit, err := r.store.queries.GetDirectDepositByID(ctx, int64(id))
if err != nil {
return nil, err
}
deposit := mapDBDirectDepositToDomain(&dbDeposit)
return deposit, nil
}
func (r *DirectDepositRepo) DeleteDirectDeposit(
ctx context.Context,
id int,
) error {
err := r.store.queries.DeleteDirectDeposit(ctx, int64(id))
if err != nil {
return err
}
return nil
}
func (r *DirectDepositRepo) RejectDirectDeposit(
ctx context.Context,
depositID int,
adminID int,
reason string,
) error {
params := dbgen.RejectDirectDepositParams{
ID: int64(depositID),
ApprovedBy: pgtype.Int8{Int64: int64(adminID)},
RejectionReason: pgtype.Text{String: reason},
}
err := r.store.queries.RejectDirectDeposit(ctx, params)
if err != nil {
return err
}
return nil
}
func mapDBDirectDepositToDomain(d *dbgen.DirectDeposit) *domain.DirectDeposit {
var approvedBy *int
if d.ApprovedBy.Valid {
v := int(d.ApprovedBy.Int64)
approvedBy = &v
}
var approvedAt *time.Time
if d.ApprovedAt.Valid {
t := d.ApprovedAt.Time
approvedAt = &t
}
var rejectionReason *string
if d.RejectionReason.Valid {
r := d.RejectionReason.String
rejectionReason = &r
}
return &domain.DirectDeposit{
ID: int(d.ID),
CustomerID: int(d.CustomerID.Int64),
WalletID: int(d.WalletID.Int64),
BankName: d.BankName.String,
AccountNumber: d.AccountNumber.String,
AccountHolder: d.AccountHolder.String,
Amount: float64(d.Amount.Exp),
ReferenceNumber: d.ReferenceNumber.String,
TransferScreenshot: d.TransferScreenshot.String,
Status: d.Status.String,
CreatedAt: d.CreatedAt.Time,
ApprovedBy: approvedBy,
ApprovedAt: approvedAt,
RejectionReason: rejectionReason,
}
}