Yimaru-BackEnd/internal/repository/referal.go

286 lines
8.9 KiB
Go

package repository
import (
"context"
"database/sql"
"errors"
"fmt"
"strconv"
dbgen "github.com/SamuelTariku/FortuneBet-Backend/gen/db"
"github.com/SamuelTariku/FortuneBet-Backend/internal/domain"
"github.com/jackc/pgx/v5/pgtype"
)
type ReferralRepository interface {
CreateReferral(ctx context.Context, referral *domain.Referral) error
GetReferralByCode(ctx context.Context, code string) (*domain.Referral, error)
UpdateReferral(ctx context.Context, referral *domain.Referral) error
GetReferralStats(ctx context.Context, userID int64, companyID int64) (*domain.ReferralStats, error)
GetSettings(ctx context.Context) (*domain.ReferralSettings, error)
UpdateSettings(ctx context.Context, settings *domain.ReferralSettings) error
CreateSettings(ctx context.Context, settings *domain.ReferralSettings) error
GetReferralByReferredID(ctx context.Context, referredID int64) (*domain.Referral, error)
GetReferralCountByID(ctx context.Context, referrerID int64) (int64, error)
GetActiveReferralByReferrerID(ctx context.Context, referrerID int64) (*domain.Referral, error)
UpdateUserReferalCode(ctx context.Context, codedata domain.UpdateUserReferalCode) error
}
type ReferralRepo struct {
store *Store
}
func NewReferralRepository(store *Store) ReferralRepository {
return &ReferralRepo{store: store}
}
func (r *ReferralRepo) UpdateUserReferalCode(ctx context.Context, codedata domain.UpdateUserReferalCode) error {
params := dbgen.UpdateReferralCodeParams{
ID: codedata.UserID,
ReferralCode: pgtype.Text{
String: codedata.Code,
Valid: true,
},
}
return r.store.queries.UpdateReferralCode(ctx, params)
}
func (r *ReferralRepo) CreateReferral(ctx context.Context, referral *domain.Referral) error {
rewardAmount := pgtype.Numeric{}
if err := rewardAmount.Scan(strconv.Itoa(int(referral.RewardAmount))); err != nil {
return err
}
params := dbgen.CreateReferralParams{
ReferralCode: referral.ReferralCode,
ReferrerID: referral.ReferrerID,
Status: dbgen.Referralstatus(referral.Status),
RewardAmount: rewardAmount,
ExpiresAt: pgtype.Timestamptz{Time: referral.ExpiresAt, Valid: true},
CompanyID: referral.CompanyID,
}
_, err := r.store.queries.CreateReferral(ctx, params)
return err
}
func (r *ReferralRepo) GetReferralByCode(ctx context.Context, code string) (*domain.Referral, error) {
dbReferral, err := r.store.queries.GetReferralByCode(ctx, code)
if err != nil {
if errors.Is(err, sql.ErrNoRows) {
return nil, nil
}
return nil, err
}
return r.mapToDomainReferral(&dbReferral), nil
}
func (r *ReferralRepo) UpdateReferral(ctx context.Context, referral *domain.Referral) error {
var referredID pgtype.Int8
if referral.ReferredID != nil {
referredID = pgtype.Int8{Int64: *referral.ReferredID, Valid: true}
}
params := dbgen.UpdateReferralParams{
ID: referral.ID,
ReferredID: referredID,
Status: dbgen.Referralstatus(referral.Status),
}
_, err := r.store.queries.UpdateReferral(ctx, params)
return err
}
func (r *ReferralRepo) GetReferralStats(ctx context.Context, userID int64, companyID int64) (*domain.ReferralStats, error) {
stats, err := r.store.queries.GetReferralStats(ctx, dbgen.GetReferralStatsParams{
ReferrerID: userID,
CompanyID: companyID,
})
if err != nil {
return nil, err
}
return &domain.ReferralStats{
TotalReferrals: int(stats.TotalReferrals),
CompletedReferrals: int(stats.CompletedReferrals),
TotalRewardEarned: stats.TotalRewardEarned.(float64),
PendingRewards: stats.PendingRewards.(float64),
}, nil
}
func (r *ReferralRepo) GetSettings(ctx context.Context) (*domain.ReferralSettings, error) {
settings, err := r.store.queries.GetReferralSettings(ctx)
if err != nil {
if errors.Is(err, sql.ErrNoRows) {
return nil, nil
}
return nil, err
}
return r.mapToDomainSettings(&settings), nil
}
func (r *ReferralRepo) UpdateSettings(ctx context.Context, settings *domain.ReferralSettings) error {
rewardAmount := pgtype.Numeric{}
if err := rewardAmount.Scan(settings.ReferralRewardAmount); err != nil {
return err
}
cashbackPercentage := pgtype.Numeric{}
if err := cashbackPercentage.Scan(settings.CashbackPercentage); err != nil {
return err
}
betReferralBonusPercentage := pgtype.Numeric{}
if err := betReferralBonusPercentage.Scan(settings.BetReferralBonusPercentage); err != nil {
return err
}
params := dbgen.UpdateReferralSettingsParams{
ID: settings.ID,
ReferralRewardAmount: rewardAmount,
CashbackPercentage: cashbackPercentage,
BetReferralBonusPercentage: betReferralBonusPercentage, // New field
MaxReferrals: settings.MaxReferrals,
ExpiresAfterDays: settings.ExpiresAfterDays,
UpdatedBy: settings.UpdatedBy,
}
_, err := r.store.queries.UpdateReferralSettings(ctx, params)
return err
}
func (r *ReferralRepo) CreateSettings(ctx context.Context, settings *domain.ReferralSettings) error {
rewardAmount := pgtype.Numeric{}
if err := rewardAmount.Scan(fmt.Sprintf("%f", settings.ReferralRewardAmount)); err != nil {
return err
}
cashbackPercentage := pgtype.Numeric{}
if err := cashbackPercentage.Scan(fmt.Sprintf("%f", settings.CashbackPercentage)); err != nil {
return err
}
betReferralBonusPercentage := pgtype.Numeric{}
if err := betReferralBonusPercentage.Scan(fmt.Sprintf("%f", settings.BetReferralBonusPercentage)); err != nil {
return err
}
params := dbgen.CreateReferralSettingsParams{
ReferralRewardAmount: rewardAmount,
CashbackPercentage: cashbackPercentage,
BetReferralBonusPercentage: betReferralBonusPercentage, // New field
MaxReferrals: settings.MaxReferrals,
ExpiresAfterDays: settings.ExpiresAfterDays,
UpdatedBy: settings.UpdatedBy,
}
_, err := r.store.queries.CreateReferralSettings(ctx, params)
return err
}
func (r *ReferralRepo) GetReferralByReferredID(ctx context.Context, referredID int64) (*domain.Referral, error) {
dbReferral, err := r.store.queries.GetReferralByReferredID(ctx, pgtype.Int8{Int64: referredID, Valid: true})
if err != nil {
if errors.Is(err, sql.ErrNoRows) {
return nil, nil
}
return nil, err
}
return r.mapToDomainReferral(&dbReferral), nil
}
func (r *ReferralRepo) GetReferralCountByID(ctx context.Context, referrerID int64) (int64, error) {
count, err := r.store.queries.GetReferralCountByID(ctx, referrerID)
if err != nil {
if errors.Is(err, sql.ErrNoRows) {
return 0, nil
}
return 0, err
}
return count, nil
}
func (r *ReferralRepo) GetActiveReferralByReferrerID(ctx context.Context, referrerID int64) (*domain.Referral, error) {
referral, err := r.store.queries.GetActiveReferralByReferrerID(ctx, referrerID)
if err != nil {
if errors.Is(err, sql.ErrNoRows) {
return &domain.Referral{}, nil
}
return &domain.Referral{}, err
}
return r.mapToDomainReferral(&referral), nil
}
func (r *ReferralRepo) mapToDomainReferral(dbRef *dbgen.Referral) *domain.Referral {
var referredID *int64
if dbRef.ReferredID.Valid {
referredID = &dbRef.ReferredID.Int64
}
rewardAmount := 0.0
if dbRef.RewardAmount.Valid {
if f8, err := dbRef.RewardAmount.Float64Value(); err == nil {
rewardAmount = f8.Float64
}
}
cashbackAmount := 0.0
if dbRef.CashbackAmount.Valid {
if f8, err := dbRef.CashbackAmount.Float64Value(); err == nil {
cashbackAmount = f8.Float64
}
}
return &domain.Referral{
ID: dbRef.ID,
ReferralCode: dbRef.ReferralCode,
ReferrerID: dbRef.ReferrerID,
ReferredID: referredID,
Status: domain.ReferralStatus(dbRef.Status),
RewardAmount: rewardAmount,
CashbackAmount: cashbackAmount,
CreatedAt: dbRef.CreatedAt.Time,
UpdatedAt: dbRef.UpdatedAt.Time,
ExpiresAt: dbRef.ExpiresAt.Time,
}
}
func (r *ReferralRepo) mapToDomainSettings(dbSettings *dbgen.ReferralSetting) *domain.ReferralSettings {
rewardAmount := 0.0
if dbSettings.ReferralRewardAmount.Valid {
if f8, err := dbSettings.ReferralRewardAmount.Float64Value(); err == nil {
rewardAmount = f8.Float64
}
}
cashbackPercentage := 0.0
if dbSettings.CashbackPercentage.Valid {
if f8, err := dbSettings.CashbackPercentage.Float64Value(); err == nil {
cashbackPercentage = f8.Float64
}
}
betReferralBonusPercentage := 0.0
if dbSettings.BetReferralBonusPercentage.Valid {
if f8, err := dbSettings.BetReferralBonusPercentage.Float64Value(); err == nil {
betReferralBonusPercentage = f8.Float64
}
}
return &domain.ReferralSettings{
ID: dbSettings.ID,
ReferralRewardAmount: rewardAmount,
CashbackPercentage: cashbackPercentage,
BetReferralBonusPercentage: betReferralBonusPercentage, // New field
MaxReferrals: dbSettings.MaxReferrals,
ExpiresAfterDays: dbSettings.ExpiresAfterDays,
UpdatedBy: dbSettings.UpdatedBy,
CreatedAt: dbSettings.CreatedAt.Time,
UpdatedAt: dbSettings.UpdatedAt.Time,
Version: dbSettings.Version,
}
}