コード例 #1
0
        public async Task <MakeBetResponseDto> MakeBet(MakeBet cmd, string ipAddress)
        {
            var validationResult = CheckBets.IsValid(cmd.Bet);

            if (!validationResult.getIsValid())
            {
                throw new BadRequestException(Constants.InvalidBetExceptionTest);
            }

            var user = await _dbHelper.GetUserAsync(_securityService.CurrentUser.Id, User.ControlFlags.Basic | User.ControlFlags.Bets);

            if (user.RowVersion != cmd.RowVersion)
            {
                throw new ConcurrencyException();
            }

            var winningNumber = new Random().Next(0, 36);

            var(spinId, won, wonAmount) = user.MakeBat(cmd, CheckBets.EstimateWin, winningNumber, validationResult.getBetAmount(), ipAddress);

            await _dbHelper.UpdateUserAsync(user, cmd.RowVersion);

            return(new MakeBetResponseDto
            {
                WinningNumber = winningNumber,
                Won = won,
                SpinId = spinId,
                WonAmount = wonAmount,
            });
        }
コード例 #2
0
        private void CheckBet(string betString, decimal betAmount)
        {
            if (!CheckBets.IsValid(betString).getIsValid())
            {
                throw new BetNotCorrectException("Bet String Not Correct");
            }

            if (betAmount >= Balance)
            {
                throw new BetNotCorrectException("Inefficient Balance");
            }
        }
コード例 #3
0
        public async Task <BetDto> Handle(MakeBetCommand request, CancellationToken cancellationToken)
        {
            var user = await _queryRepository.FindUserById(_currentUserService.CurrentUserId)
                       ?? throw new UserNotFoundException();

            string betString = Convert.ToString(request.BetString);

            CheckBet(betString, request.BetAmount, user.Balance);

            int winningNumber = new Random().Next(0, 36);

            var wonAmount = CheckBets.EstimateWin(betString, winningNumber);

            BetStatus betStatus = wonAmount > 0 ? BetStatus.Won : BetStatus.Lost;

            var jackpotAmount = await _queryRepository.GetCurrentJackpot();

            jackpotAmount += request.BetAmount * 0.01M;
            user.Balance  -= request.BetAmount;

            var bet = new BetEntity
            {
                SpinId        = request.SpinId,
                BetAmount     = request.BetAmount,
                BetString     = betString,
                IpAddress     = _currentUserService.IpAddress,
                JackpotAmount = jackpotAmount,
                UserId        = _currentUserService.CurrentUserId,
                WonAmount     = wonAmount,
                BetStatus     = betStatus,
                CreatedAt     = DateTime.Now
            };
            await _commandRepository.MakeBet(bet, user.Balance, winningNumber);

            return(new BetDto {
                SpinId = bet.SpinId, BetStatus = bet.BetStatus, WonAmount = bet.WonAmount, WinningNumber = winningNumber
            });
        }
コード例 #4
0
        /// <summary>
        /// Make bet
        /// </summary>
        /// <param name="request"> Request from User</param>
        /// <param name="UserId"> current user's Id</param>
        /// <param name="IpAddress">User's IP address</param>
        /// <returns></returns>
        public async Task <BetRow> MakeBet(BetRequest request, int UserId, string IpAddress)
        {
            GenerateSpin();
            int SpinId = await _queryrepository.GetActiveSpin();

            int UserBetPermisson = await _queryrepository.ChekUserBetPermission(SpinId, UserId);

            if (UserBetPermisson > 0)
            {
                throw new ArgumentException("You already have the bet on the current spin, please wait or generate new spin");
            }
            IsBetValidResponse ibvr = CheckBets.IsValid(Convert.ToString(request.BetString));

            if (!ibvr.getIsValid() || ibvr.getBetAmount() <= 0)
            {
                throw new IncorrectBetException("Bet is not in correct format");
            }
            else
            {
                BetRow     betRow  = new BetRow();
                BetCommand command = new BetCommand();
                command.SpinId     = SpinId;
                command.IpAddress  = IpAddress;
                command.UserId     = UserId;
                command.BetAmount  = ibvr.getBetAmount();
                command.WonAmount  = 0;
                command.Status     = BetStatus.Lose;
                command.IsActive   = true;
                command.CreateDate = DateTime.Now;
                command.BetString  = Convert.ToString(request.BetString);

                var UserBalance = await _queryrepository.GetUserBalance(UserId);

                if (UserBalance < command.BetAmount)
                {
                    throw new ArgumentException("you have not enough balance for bet");
                }
                else
                {
                    decimal JakpotAmount = await _queryrepository.CurrentJackpot();

                    int BetId = await _commandrepository.MakeBet(command);

                    JakpotAmount += (ibvr.getBetAmount() * 0.01M);
                    UserBalance  -= (int)command.BetAmount;
                    _commandrepository.UpdateJackpot(JakpotAmount);
                    _commandrepository.UpdateUserBalance(UserId, UserBalance);
                    Random rnd       = new Random();
                    int    WinNumber = rnd.Next(0, 36);
                    // _commandrepository.SetSpinWiningNumber(WinNumber);
                    _commandrepository.SetWinNumber(SpinId, WinNumber);
                    int WinMoney = CheckBets.EstimateWin(Convert.ToString(request.BetString), WinNumber);
                    if (WinMoney > 0)
                    {
                        _commandrepository.UpdateBet(BetId, WinMoney);
                        UserBalance += WinMoney;
                        _commandrepository.UpdateUserBalance(UserId, UserBalance);
                    }
                    betRow.SpinID     = SpinId;
                    betRow.Status     = "Bet accepted";
                    betRow.WInNumber  = WinNumber;
                    betRow.WonAmount  = WinMoney;
                    betRow.CreateDate = DateTime.Now;
                }
                return(betRow);
            }
        }
コード例 #5
0
        public RoundBetResponseModel PlaceBet(int userId, RoundBetRequestModel model, string ipAddress)
        {
            // you never know when user will be deleted so maybe some check
            var user = _dbContext.Users.FirstOrDefault(x => x.DeleteDate == null && x.Id == userId);

            if (user == null)
            {
                return(new RoundBetResponseModel
                {
                    Success = false,
                    ErrorCode = ErrorCode.NotFound,
                    DeveloperMessage = $"User not found with {userId} id",
                });
            }
            var isBetValid = CheckBets.IsValid(model.BetString);

            if (!isBetValid.getIsValid())
            {
                return(new RoundBetResponseModel
                {
                    Success = false,
                    ErrorCode = ErrorCode.InvalidValue,
                    DeveloperMessage = $"Requested bet string invalid \"{model.BetString}\"",
                });
            }
            var betAmount = isBetValid.getBetAmount();

            if (user.Balance < betAmount)
            {
                return(new RoundBetResponseModel
                {
                    Success = false,
                    ErrorCode = ErrorCode.BalanceNotEnough,
                    DeveloperMessage = $"Not enough balance",
                });
            }
            user.Balance -= betAmount;
            if (_dbContext.SaveChanges() > 0)
            {
                var betAmountInMilli = betAmount * 100;
                var jackToIncrease   = betAmountInMilli * jackPercFromBet / 100;
                _jackpotService.IncreaseJackpot(jackToIncrease);

                var winningResult = new Random().Next(0, 36);
                int wonAmount     = CheckBets.EstimateWin(model.BetString, winningResult);
                _dbContext.Rounds.Add(new Round
                {
                    IpAddress     = ipAddress,
                    UserId        = userId,
                    WonAmount     = wonAmount,
                    BetAmount     = betAmount,
                    BetString     = model.BetString,
                    CreateDate    = DateTime.UtcNow,
                    WinningResult = winningResult,
                });
                user.Balance += wonAmount;
                if (_dbContext.SaveChanges() > 0)
                {
                    return(new RoundBetResponseModel
                    {
                        Success = true,
                        WonAmount = wonAmount,
                    });
                }
                else
                {
                    return(new RoundBetResponseModel
                    {
                        ErrorCode = ErrorCode.ChangesNotSaved,
                        DeveloperMessage = "Something went wrong and changes could not be saved.",
                    });
                }
            }
            else
            {
                return(new RoundBetResponseModel
                {
                    Success = false,
                    ErrorCode = ErrorCode.ChangesNotSaved,
                    DeveloperMessage = $"Couldnot subtract balance from user",
                });
            }
        }
コード例 #6
0
 private decimal GetUsersWonAmount(string betString, int winningNumber)
 => CheckBets.EstimateWin(betString, winningNumber);
コード例 #7
0
        public async Task <ServiceResponse <MakeBetResponseModel> > MakeBetAsync(Guid userId, string betString)
        {
#if DEBUG
            Console.WriteLine($"New bet amount: { CheckBets.IsValid(betString).getBetAmount() } at {DateTime.Now.ToLongTimeString()}");
#endif

            // Checking if user exists for the current spacial case:
            // Imagine that I have logged in, got access token and started playing unethically.
            // I was got cought by administrators and disabled my user immediately (IsDeleted = true for now).
            // Without this check user, variable that I get below, will be null and nullreferance error will occure.

            if (_userRepository.NotExists(userId))
            {
                return(UserNotFoundResponse <MakeBetResponseModel>(userId));
            }

            var user = _userRepository.GetById(userId, nameof(User.GameHistories));

            var isBetValidResponse = CheckBets.IsValid(betString);

            if (!isBetValidResponse.getIsValid())
            {
                return(new ServiceResponse <MakeBetResponseModel>()
                       .Fail(new ServiceErrorMessage()
                             .InvalidValue("BetString")));
            }

            var betAmountInCents = isBetValidResponse.getBetAmount();

            if (user.BalanceInCents < betAmountInCents)
            {
                return(new ServiceResponse <MakeBetResponseModel>()
                       .Fail(new ServiceErrorMessage()
                             .BadRequest("Not enough balance")));
            }

            user.SubtractAmountFromBalance(betAmountInCents);

            var betAmountInMillyCents = betAmountInCents.ConvertCentsToMillyCents();
            var amountToPutInJackpot  = betAmountInMillyCents * _amountPercentgeToPutInJackpot / 100;
            var increaceJackpotResult = await _jackpotService.IncreaseJackpotAmountAsync(amountToPutInJackpot);

            if (increaceJackpotResult.Failed)
            {
                return(new ServiceResponse <MakeBetResponseModel>()
                       .Fail(new ServiceErrorMessage()
                             .ChangesNotSaved("Something went wrong, could not update jackpot amount")));
            }

            var winningNumber    = new Random().Next(0, 36);
            int wonAmountInCents = CheckBets.EstimateWin(betString, winningNumber);

            user.GameHistories.Add(new GameHistory(betString, winningNumber, betAmountInCents, wonAmountInCents));
            user.AddAmountToBalance(wonAmountInCents);

            _userRepository.Update(user);
            var rowsUpdated = await _userRepository.SaveChangesAsync();

            if (rowsUpdated == 0)
            {
                return(new ServiceResponse <MakeBetResponseModel>()
                       .Fail(new ServiceErrorMessage()
                             .ChangesNotSaved("Something went wrong, could not update user data")));
            }

            return(new ServiceResponse <MakeBetResponseModel>()
                   .Ok(new MakeBetResponseModel(wonAmountInCents)));
        }