Yimaru-BackEnd/internal/services/bonus/service.go

114 lines
3.6 KiB
Go

package bonus
import (
"context"
"errors"
"math"
"time"
"github.com/SamuelTariku/FortuneBet-Backend/internal/domain"
"github.com/SamuelTariku/FortuneBet-Backend/internal/pkgs/helpers"
"github.com/SamuelTariku/FortuneBet-Backend/internal/services/settings"
"github.com/SamuelTariku/FortuneBet-Backend/internal/services/wallet"
"go.uber.org/zap"
)
type Service struct {
bonusStore BonusStore
walletSvc *wallet.Service
settingSvc *settings.Service
mongoLogger *zap.Logger
}
func NewService(bonusStore BonusStore, walletSvc *wallet.Service, settingSvc *settings.Service, mongoLogger *zap.Logger) *Service {
return &Service{
bonusStore: bonusStore,
walletSvc: walletSvc,
settingSvc: settingSvc,
mongoLogger: mongoLogger,
}
}
var (
ErrWelcomeBonusNotActive = errors.New("welcome bonus is not active")
ErrWelcomeBonusCountReached = errors.New("welcome bonus max deposit count reached")
)
func (s *Service) ProcessWelcomeBonus(ctx context.Context, amount domain.Currency, companyID int64, userID int64) error {
settingsList, err := s.settingSvc.GetOverrideSettingsList(ctx, companyID)
if err != nil {
s.mongoLogger.Error("Failed to get settings",
zap.Int64("companyID", companyID),
zap.Error(err))
return err
}
if !settingsList.WelcomeBonusActive {
return ErrWelcomeBonusNotActive
}
wallet, err := s.walletSvc.GetCustomerWallet(ctx, userID)
if err != nil {
return err
}
stats, err := s.walletSvc.GetTransferStats(ctx, wallet.ID)
if err != nil {
return err
}
if stats.TotalDeposits > settingsList.WelcomeBonusCount {
return ErrWelcomeBonusCountReached
}
newBalance := math.Min(float64(amount)*float64(settingsList.WelcomeBonusMultiplier), float64(settingsList.WelcomeBonusCap))
_, err = s.CreateUserBonus(ctx, domain.CreateBonus{
Name: "Welcome Bonus",
Description: "Awarded when the user logged in for the first time",
UserID: userID,
BonusCode: helpers.GenerateFastCode(),
RewardAmount: domain.Currency(newBalance),
ExpiresAt: time.Now().Add(time.Duration(settingsList.WelcomeBonusExpire) * 24 * time.Hour),
})
if err != nil {
return err
}
// TODO: Add a claim function that adds to the static wallet when the user inputs his bonus code
// _, err = s.walletSvc.AddToWallet(ctx, wallet.StaticID, domain.ToCurrency(float32(newBalance)), domain.ValidInt64{}, domain.TRANSFER_DIRECT, domain.PaymentDetails{},
// fmt.Sprintf("Added %v to static wallet because of deposit bonus using multiplier %v", newBalance, settingsList.WelcomeBonusMultiplier),
// )
// if err != nil {
// return err
// }
return nil
}
func (s *Service) CreateUserBonus(ctx context.Context, bonus domain.CreateBonus) (domain.UserBonus, error) {
return s.bonusStore.CreateUserBonus(ctx, bonus)
}
func (s *Service) GetAllUserBonuses(ctx context.Context) ([]domain.UserBonus, error) {
return s.bonusStore.GetAllUserBonuses(ctx)
}
func (s *Service) GetBonusesByUserID(ctx context.Context, userID int64) ([]domain.UserBonus, error) {
return s.bonusStore.GetBonusesByUserID(ctx, userID)
}
func (s *Service) GetBonusByID(ctx context.Context, bonusID int64) (domain.UserBonus, error) {
return s.bonusStore.GetBonusByID(ctx, bonusID)
}
func (s *Service) GetBonusStats(ctx context.Context, filter domain.BonusFilter) (domain.BonusStats, error) {
return s.bonusStore.GetBonusStats(ctx, filter)
}
func (s *Service) UpdateUserBonus(ctx context.Context, bonusID int64, IsClaimed bool) error {
return s.bonusStore.UpdateUserBonus(ctx, bonusID, IsClaimed)
}
func (s *Service) DeleteUserBonus(ctx context.Context, bonusID int64) error {
return s.bonusStore.DeleteUserBonus(ctx, bonusID)
}