208 lines
5.8 KiB
Go
208 lines
5.8 KiB
Go
package transaction
|
|
|
|
import (
|
|
"context"
|
|
"crypto/rand"
|
|
"errors"
|
|
"math/big"
|
|
|
|
"github.com/SamuelTariku/FortuneBet-Backend/internal/domain"
|
|
)
|
|
|
|
var (
|
|
ErrInvalidBetID = errors.New("invalid bet id")
|
|
ErrUserHasNotWonBet = errors.New("user has not won bet")
|
|
ErrUserHasAlreadyCashoutOut = errors.New("user has already cashout")
|
|
ErrTransactionNotVerified = errors.New("transaction hasn't been verified")
|
|
)
|
|
|
|
func (s *Service) GenerateCashoutID() (string, error) {
|
|
const chars = "abcdefghijklmnopqrstuvwxyz0123456789"
|
|
const length int = 13
|
|
charLen := big.NewInt(int64(len(chars)))
|
|
result := make([]byte, length)
|
|
|
|
for i := 0; i < length; i++ {
|
|
index, err := rand.Int(rand.Reader, charLen)
|
|
if err != nil {
|
|
// s.mongoLogger.Error("failed to generate random index for cashout ID",
|
|
// zap.Int("position", i),
|
|
// zap.Error(err),
|
|
// )
|
|
return "", err
|
|
}
|
|
result[i] = chars[index.Int64()]
|
|
}
|
|
|
|
return string(result), nil
|
|
}
|
|
|
|
func (s *Service) CreateShopBet(ctx context.Context, userID int64, role domain.Role, userCompanyID domain.ValidInt64, req domain.ShopBetReq) (domain.ShopBet, error) {
|
|
|
|
branchID, companyID, err := s.GetBranchByRole(ctx, req.BranchID, role, userID, userCompanyID)
|
|
|
|
if err != nil {
|
|
return domain.ShopBet{}, err
|
|
}
|
|
|
|
cashoutID, err := s.GenerateCashoutID()
|
|
|
|
if err != nil {
|
|
return domain.ShopBet{}, err
|
|
}
|
|
|
|
newBet, err := s.betSvc.PlaceBet(ctx, domain.CreateBetReq{
|
|
Outcomes: req.Outcomes,
|
|
Amount: req.Amount,
|
|
FullName: req.FullName,
|
|
PhoneNumber: req.PhoneNumber,
|
|
BranchID: branchID,
|
|
}, userID, role)
|
|
|
|
if err != nil {
|
|
return domain.ShopBet{}, err
|
|
}
|
|
|
|
newTransaction, err := s.CreateShopTransaction(ctx, domain.CreateShopTransaction{
|
|
Amount: domain.ToCurrency(req.Amount),
|
|
BranchID: *branchID,
|
|
CompanyID: *companyID,
|
|
UserID: userID,
|
|
Type: domain.TRANSACTION_BET,
|
|
FullName: req.FullName,
|
|
PhoneNumber: req.PhoneNumber,
|
|
PaymentOption: req.PaymentOption,
|
|
BankCode: domain.ValidString{
|
|
Value: req.BankCode,
|
|
Valid: req.BankCode != "",
|
|
},
|
|
BeneficiaryName: domain.ValidString{
|
|
Value: req.BeneficiaryName,
|
|
Valid: req.BeneficiaryName != "",
|
|
},
|
|
AccountName: domain.ValidString{
|
|
Value: req.AccountName,
|
|
Valid: req.AccountName != "",
|
|
},
|
|
AccountNumber: domain.ValidString{
|
|
Value: req.AccountNumber,
|
|
Valid: req.AccountNumber != "",
|
|
},
|
|
ReferenceNumber: domain.ValidString{
|
|
Value: req.ReferenceNumber,
|
|
Valid: req.ReferenceNumber != "",
|
|
},
|
|
Verified: false,
|
|
ApprovedBy: domain.ValidInt64{
|
|
Value: userID,
|
|
Valid: true,
|
|
},
|
|
})
|
|
|
|
return s.transactionStore.CreateShopBet(ctx, domain.CreateShopBet{
|
|
ShopTransactionID: newTransaction.ID,
|
|
CashoutID: cashoutID,
|
|
BetID: newBet.ID,
|
|
NumberOfOutcomes: int64(len(req.Outcomes)),
|
|
})
|
|
}
|
|
|
|
// func (s *Service) CreateShopBet(ctx context.Context, bet domain.CreateShopBet) (domain.ShopBet, error) {
|
|
// return s.transactionStore.CreateShopBet(ctx, bet)
|
|
// }
|
|
|
|
func (s *Service) CashoutBet(ctx context.Context, betID int64, userID int64, role domain.Role, req domain.CashoutReq) (domain.ShopTransaction, error) {
|
|
branchID, companyID, err := s.GetBranchByRole(ctx, req.BranchID, role, userID)
|
|
|
|
if err != nil {
|
|
return domain.ShopTransaction{}, nil
|
|
}
|
|
|
|
bet, err := s.GetShopBetByBetID(ctx, betID)
|
|
if err != nil {
|
|
// h.logger.Error("CashoutReq failed", "error", err)
|
|
return domain.ShopTransaction{}, ErrInvalidBetID
|
|
}
|
|
|
|
if bet.Status != domain.OUTCOME_STATUS_WIN {
|
|
// h.logger.Error("CashoutReq failed, bet has not won")
|
|
return domain.ShopTransaction{}, ErrUserHasNotWonBet
|
|
}
|
|
|
|
if bet.CashedOut {
|
|
// s.logger.Error(("Bet has already been cashed out"))
|
|
return domain.ShopTransaction{}, ErrUserHasAlreadyCashoutOut
|
|
}
|
|
|
|
if !bet.TransactionVerified {
|
|
return domain.ShopTransaction{}, ErrTransactionNotVerified
|
|
}
|
|
|
|
err = s.UpdateShopBetCashOut(ctx, bet.ID, true)
|
|
|
|
if err != nil {
|
|
return domain.ShopTransaction{}, err
|
|
}
|
|
|
|
return s.CreateShopTransaction(ctx, domain.CreateShopTransaction{
|
|
Amount: bet.Amount,
|
|
BranchID: *branchID,
|
|
CompanyID: *companyID,
|
|
UserID: userID,
|
|
Type: domain.TRANSACTION_CASHOUT,
|
|
FullName: bet.FullName,
|
|
PhoneNumber: bet.PhoneNumber,
|
|
PaymentOption: req.PaymentOption,
|
|
BankCode: domain.ValidString{
|
|
Value: req.BankCode,
|
|
Valid: req.BankCode != "",
|
|
},
|
|
BeneficiaryName: domain.ValidString{
|
|
Value: req.BeneficiaryName,
|
|
Valid: req.BeneficiaryName != "",
|
|
},
|
|
AccountName: domain.ValidString{
|
|
Value: req.AccountName,
|
|
Valid: req.AccountName != "",
|
|
},
|
|
AccountNumber: domain.ValidString{
|
|
Value: req.AccountNumber,
|
|
Valid: req.AccountNumber != "",
|
|
},
|
|
ReferenceNumber: domain.ValidString{
|
|
Value: req.ReferenceNumber,
|
|
Valid: req.ReferenceNumber != "",
|
|
},
|
|
Verified: false,
|
|
ApprovedBy: domain.ValidInt64{
|
|
Value: userID,
|
|
Valid: true,
|
|
},
|
|
})
|
|
|
|
}
|
|
|
|
func (s *Service) GetAllShopBet(ctx context.Context, filter domain.ShopBetFilter) ([]domain.ShopBetDetail, error) {
|
|
return s.transactionStore.GetAllShopBet(ctx, filter)
|
|
}
|
|
|
|
func (s *Service) GetShopBetByID(ctx context.Context, id int64) (domain.ShopBetDetail, error) {
|
|
return s.transactionStore.GetShopBetByBetID(ctx, id)
|
|
}
|
|
|
|
func (s *Service) GetShopBetByBetID(ctx context.Context, betID int64) (domain.ShopBetDetail, error) {
|
|
return s.transactionStore.GetShopBetByBetID(ctx, betID)
|
|
}
|
|
|
|
func (s *Service) GetShopBetByShopTransactionID(ctx context.Context, shopTransactionID int64) (domain.ShopBetDetail, error) {
|
|
return s.transactionStore.GetShopBetByShopTransactionID(ctx, shopTransactionID)
|
|
}
|
|
|
|
func (s *Service) UpdateShopBetCashOut(ctx context.Context, id int64, cashedOut bool) error {
|
|
return s.transactionStore.UpdateShopBetCashOut(ctx, id, cashedOut)
|
|
}
|
|
|
|
func (s *Service) UpdateShopBetCashoutID(ctx context.Context, id int64, cashoutID string) error {
|
|
return s.transactionStore.UpdateShopBetCashoutID(ctx, id, cashoutID)
|
|
}
|