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 }); }
/// <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); } }
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", }); } }
private decimal GetUsersWonAmount(string betString, int winningNumber) => CheckBets.EstimateWin(betString, winningNumber);
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))); }