public async Task <ServiceResult <PostLongDto> > VoteOnPostAsync(int postId, EPostVoteType postVoteType, int userId, ERoleType userRole) { var post = await _unitOfWork.PostRepository .GetSingleAsync(p => p.Id == postId, p => p.User, p => p.Files, p => p.Votes, p => p.Group, p => p.Answers); var existingVote = await _unitOfWork.PostVoteRepository .GetSingleAsync(p => p.UserId == userId && p.PostId == postId); var validationResult = await PerformVoteRequestValidationAsync(post, userId, userRole, existingVote, postVoteType); if (!validationResult.IsSuccess) { return(validationResult); } var postVote = new PostVote() { Post = post, UserId = userId, VoteTypeId = (int)postVoteType }; post.VotesCount = CountNewVotes(postVoteType, post.VotesCount, existingVote); await _unitOfWork.PostVoteRepository.AddAsync(postVote); if (existingVote != null) { _unitOfWork.PostVoteRepository.Delete(existingVote); } post.User.CurrencyCount = CountUserCurrencyCount(postVoteType, post.User.CurrencyCount); await _unitOfWork.CommitAsync(); var postDto = _mapper.Map <Post, PostLongDto>(post); postDto.UserVoteType = postVoteType; return(ServiceResult <PostLongDto> .Ok(postDto)); }
private decimal CountUserCurrencyCount(EPostVoteType postVoteType, decimal postAuthorOldCurrencyCount, PostVote existingVoteAction = null) { decimal postAuthorCurrencyCount = postAuthorOldCurrencyCount; switch (postVoteType) { case EPostVoteType.Upvote: if (existingVoteAction?.VoteTypeId == (int)EPostVoteType.Downvote) { postAuthorCurrencyCount = postAuthorCurrencyCount - TradingConstants.DownvoteUnicoinsFee; } postAuthorCurrencyCount = TradingConstants.UpvoteUnicoinsBonus + postAuthorCurrencyCount; break; case EPostVoteType.Downvote: if (existingVoteAction?.VoteTypeId == (int)EPostVoteType.Upvote) { postAuthorCurrencyCount = postAuthorCurrencyCount - TradingConstants.UpvoteUnicoinsBonus; } postAuthorCurrencyCount = TradingConstants.DownvoteUnicoinsFee + postAuthorCurrencyCount; break; case EPostVoteType.None: if (existingVoteAction?.VoteTypeId == (int)EPostVoteType.Downvote) { postAuthorCurrencyCount = postAuthorCurrencyCount - TradingConstants.DownvoteUnicoinsFee; } else if (existingVoteAction?.VoteTypeId == (int)EPostVoteType.Upvote) { postAuthorCurrencyCount = postAuthorCurrencyCount - TradingConstants.UpvoteUnicoinsBonus; } break; default: throw new InvalidEnumArgumentException(); } return(postAuthorOldCurrencyCount); }
// TODO: refactor to different classes with BaseClass or something private int CountNewVotes(EPostVoteType postVoteType, int oldPostVotesCount, PostVote existingVoteAction = null) { int postVotesCount = oldPostVotesCount; switch (postVoteType) { case EPostVoteType.Upvote: if (existingVoteAction?.VoteTypeId == (int)EPostVoteType.Downvote) { postVotesCount = ++postVotesCount; } postVotesCount = ++postVotesCount; break; case EPostVoteType.Downvote: if (existingVoteAction?.VoteTypeId == (int)EPostVoteType.Upvote) { postVotesCount = --postVotesCount; } postVotesCount = --postVotesCount; break; case EPostVoteType.None: if (existingVoteAction?.VoteTypeId == (int)EPostVoteType.Downvote) { postVotesCount = ++postVotesCount; } else if (existingVoteAction?.VoteTypeId == (int)EPostVoteType.Upvote) { postVotesCount = --postVotesCount; } break; default: throw new InvalidEnumArgumentException(); } return(postVotesCount); }
public async Task <ActionResult <PostLongDto> > Vote([FromRoute] int postId, EPostVoteType postAction) => _viewMapper.ServiceResultToContentResult( await _postService.VoteOnPostAsync(postId, postAction, UserId, UserRole));
private async Task <ServiceResult <PostLongDto> > PerformVoteRequestValidationAsync(Post post, int userId, ERoleType userRole, PostVote existingVote, EPostVoteType newPostVoteType) { ServiceResult <PostLongDto> validationResult = null; if (post == null) { validationResult = ServiceResult <PostLongDto> .Fail(EOperationResult.EntityNotFound, "Post not found"); } var isUserUnlockedPost = await _unitOfWork.UserAvailablePostRepository.AnyAsync(up => up.UserId == userId && up.PostId == post.Id); if (!isUserUnlockedPost && userRole != ERoleType.Admin) { validationResult = ServiceResult <PostLongDto> .Fail(EOperationResult.ValidationError, "You need to unlock the post before voting"); } if (existingVote?.VoteTypeId == (int)newPostVoteType) { validationResult = ServiceResult <PostLongDto> .Fail(EOperationResult.AlreadyExist, "You already voted on this post"); } return(validationResult ?? (validationResult = ServiceResult <PostLongDto> .Ok())); }