public async Task <RewardHistory> CreateRewardAsync(CreateRewardRequest rewardRequest) { // validate target user exists var existUser = await _uow.UserRepository.GetAsync(rewardRequest.UserId); if (existUser == null) { throw new NotFoundException(ExceptionConstants.NOT_FOUND, "User"); } // get/validate-exist reward type var rewardCategory = await _rewardCategoryService.GetRewardCategoryByCategoryAsync(rewardRequest.RewardCategoryEnum); var rewardAcomulate = await GetOrCreateRewardAcomulate(existUser, rewardCategory); var allowedPoints = 0; if (rewardCategory.Category == RewardCategoryEnum.SOLO_QUESTION_ANSWERED) { var data = JsonConvert.DeserializeObject <RewardHistoryData>(rewardRequest.Data); var userAnswer = JsonConvert.DeserializeObject <UserSoloAnswerResponse>(data.Entity1); allowedPoints = userAnswer.Points; } else { allowedPoints = await AllowedPointsAsync(rewardCategory, rewardAcomulate, rewardRequest.IsPlus); } if (allowedPoints == 0) { return(null); } var rewardPoints = rewardRequest.IsPlus ? rewardCategory.PointsToIncrement : rewardCategory.PointsToDecrement; if (rewardCategory.Category == RewardCategoryEnum.SOLO_QUESTION_ANSWERED) { rewardPoints = allowedPoints; } var dbReward = new RewardHistory(); dbReward.User = existUser; dbReward.RewardCategory = rewardCategory; dbReward.IsPlus = rewardRequest.IsPlus; dbReward.Points = allowedPoints; dbReward.RewardPoints = rewardPoints; dbReward.Data = rewardRequest.Data; dbReward.CreatedAt = DateTime.UtcNow; await _uow.RewardHistoryRepository.AddAsync(dbReward); allowedPoints = rewardRequest.IsPlus ? allowedPoints : allowedPoints * -1; rewardAcomulate.Points = rewardAcomulate.Points + allowedPoints; rewardAcomulate.ModifiedAt = DateTime.UtcNow; await _uow.RewardAcumulateRepository.UpdateAsync(rewardAcomulate, rewardAcomulate.Id); await _userStatisticsService.UpdateTotalPoints(existUser, allowedPoints); await _userStatisticsService.UpdateTotalCoinsAsync(existUser, allowedPoints); await _uow.CommitAsync(); return(dbReward); }
/// <summary> /// Handle the creation of a reward /// </summary> /// <param name="category">Which type of reward will be</param> /// <param name="targetUser">user who will receive the reward</param> /// <param name="isPlus">Sum or rest points this reward</param> /// <param name="entity1">Info to store in the history</param> /// <param name="entity2">Other info to store in the history</param> /// <param name="notificationType">How will be the user notified</param> /// <param name="devices">Firebase notification targets</param> /// <returns>void - notify client that a reward was created via websocket</returns> public async Task <RewardResponse> HandleRewardAsync(RewardCategoryEnum category, int targetUser, bool isPlus, object entity1, object entity2, NotificationTypeEnum notificationType = NotificationTypeEnum.SIGNAL_R, IEnumerable <Device> devices = null) { var userStatics = await _userStatisticsService.GetOrCreateUserStatisticsByUserAsync(targetUser); var currentPoints = userStatics.Points; var cutPoints = await _cutPointService.GetNextCutPointsAsync(currentPoints, 5); var data = new RewardHistoryData { // Make sure that this is an important info to store in the history Entity1 = JsonConvert.SerializeObject(entity1), Entity2 = JsonConvert.SerializeObject(entity2) }; var reward = new CreateRewardRequest { UserId = targetUser, RewardCategoryEnum = (int)category, IsPlus = isPlus, Data = JsonConvert.SerializeObject(data), }; var dbReward = await _rewardService.CreateRewardAsync(reward); RewardResponse mapped = null; // assign only if the reward was created after validations if (dbReward != null) { mapped = new RewardResponse { Id = dbReward.Id, CategoryId = (int)dbReward.RewardCategory.Category, Category = dbReward.RewardCategory.Category.ToString(), IsPlus = dbReward.IsPlus, Points = dbReward.Points, RewardPoints = dbReward.RewardPoints, RewardCategoryId = dbReward.RewardCategoryId, UserId = dbReward.UserId, CreatedAt = dbReward.CreatedAt }; switch (notificationType) { case NotificationTypeEnum.SIGNAL_R: await SendSignalRNotificationAsync(HubConstants.REWARD_CREATED, mapped); break; case NotificationTypeEnum.FIREBASE: var lang = await _userService.GetUserLanguageFromUserIdAsync(mapped.UserId); var title = (lang == "EN") ? "You have receipt a new reward" : "Has recibido una nueva recompensa"; var body = ""; if (category == RewardCategoryEnum.EAT_BALANCED_CREATED_STREAK || category == RewardCategoryEnum.EAT_CREATED_STREAK) { body = GetFirebaseMessageForStreakReward(category, (int)entity1, mapped, lang); } if (category == RewardCategoryEnum.DISH_BUILT) { body = GetFirebaseMessageForDishBuildReward(mapped, lang); } if (category == RewardCategoryEnum.NEW_REFERAL) { body = GetFirebaseMessageForNewReferralReward(mapped, lang); } if (category == RewardCategoryEnum.EAT_BALANCED_CREATED || category == RewardCategoryEnum.EAT_CREATED) { body = GetFirebaseMessageForCreateEatReward(mapped, lang, category); } if (category == RewardCategoryEnum.CUT_POINT_REACHED) { body = GetFirebaseMessageForCutPointReachedReward(mapped, lang); } if (devices != null) { await _notificationService.SendFirebaseNotificationAsync(title, body, devices); } break; default: break; } await HandleCutPointRewardsAsync(cutPoints, targetUser); } return(mapped); }