public async Task <PrizeWinner> AddPrizeWinnerAsync(PrizeWinner prizeWinner, bool userIdIsCurrentUser = false) { if (prizeWinner.DrawingId == null && prizeWinner.TriggerId == null) { throw new Exception("Prizes must be awarded through a drawing or a trigger."); } prizeWinner.SiteId = GetCurrentSiteId(); prizeWinner.CreatedAt = _dateTimeProvider.Now; prizeWinner.CreatedBy = prizeWinner.UserId; int currentUserId = userIdIsCurrentUser ? prizeWinner.UserId : GetClaimId(ClaimType.UserId); return(await _prizeWinnerRepository.AddSaveAsync(currentUserId, prizeWinner)); }
private async Task AwardPrizeAsync(int userId, Trigger trigger, int?mailId, bool userIdIsCurrentUser = false) { if (!string.IsNullOrEmpty(trigger.AwardPrizeName)) { var prize = new PrizeWinner { CreatedBy = userId, CreatedAt = DateTime.Now, TriggerId = trigger.Id, PrizeName = trigger.AwardPrizeName, PrizeRedemptionInstructions = trigger.AwardPrizeRedemptionInstructions, UserId = userId }; if (mailId != null) { prize.MailId = mailId; } await _prizeWinnerService.AddPrizeWinnerAsync(prize, userIdIsCurrentUser); } }
public async Task <Drawing> PerformDrawingAsync(Drawing drawing) { // todo validate site int siteId = GetCurrentSiteId(); int authUserId = GetClaimId(ClaimType.UserId); if (HasPermission(Permission.PerformDrawing)) { // insert drawing drawing.DrawingCriterion = default(DrawingCriterion); drawing.Id = default(int); drawing = await _drawingRepository.AddSaveAsync(authUserId, drawing); // pull list of eligible users var eligibleUserIds = await _drawingCriterionRepository.GetEligibleUserIdsAsync(drawing.DrawingCriterionId); // ensure there are enough eligible users to do the drawing if (drawing.WinnerCount > eligibleUserIds.Count()) { throw new GraException($"Cannot draw {drawing.WinnerCount} from an eligible pool of {eligibleUserIds.Count()} participants."); } // prepare and perform the drawing var remainingUsers = new List <int>(eligibleUserIds); var rng = System.Security.Cryptography.RandomNumberGenerator.Create(); var randomBytes = new byte[sizeof(int)]; for (int count = 1; count <= drawing.WinnerCount; count++) { rng.GetBytes(randomBytes); int random = System.Math.Abs(System.BitConverter.ToInt32(randomBytes, 0)); int randomUserId = remainingUsers.ElementAt(random % remainingUsers.Count()); var winner = new PrizeWinner { SiteId = siteId, DrawingId = drawing.Id, UserId = randomUserId }; // if there's an associated notification, send it now if (!string.IsNullOrEmpty(drawing.NotificationSubject) && !string.IsNullOrEmpty(drawing.NotificationMessage)) { var mail = new Mail { SiteId = siteId, Subject = drawing.NotificationSubject, Body = drawing.NotificationMessage, ToUserId = winner.UserId, DrawingId = drawing.Id }; mail = await _mailRepository.AddSaveAsync(authUserId, mail); winner.MailId = mail.Id; } // add the winner - does not perform a save await _prizeWinnerRepository.AddAsync(authUserId, winner); // remove them so they aren't drawn twice remainingUsers.Remove(randomUserId); } await _drawingRepository.SaveAsync(); // return the fully-populated drawing return(await _drawingRepository.GetByIdAsync(drawing.Id)); } else { _logger.LogError($"User {authUserId} doesn't have permission to perform drawings."); throw new GraException("Permission denied."); } }