public async Task <IActionResult> VoteForResult(ResultVoteViewModel model)
        {
            if (model.ProjectId == null)
            {
                return(RedirectToAction("Index", "Home"));
            }

            var voterId = GetAuthenticatedUser().Email;

            var vote = await _resultVoteRepository.GetAsync(model.ProjectId, model.ParticipantId, voterId);

            if (vote == null)
            {
                model.VoterUserId = voterId;

                await _resultVoteRepository.SaveAsync(model);

                var votes = await _resultVoteRepository.GetProjectResultVotesAsync(model.ProjectId);

                var totalVotes = votes.Count();
                var result     = await _resultRepository.GetAsync(model.ProjectId, model.ParticipantId);

                result.Votes += 1;

                await _resultRepository.UpdateAsync(result);
                await CalculateScores(totalVotes, model.ProjectId);
            }

            return(RedirectToAction("ProjectDetails", "Project", new { id = model.ProjectId }));
        }
        private async Task <ProjectViewModel> GetProjectViewModel(string id)
        {
            var projectCategories = _categoriesRepository.GetCategories();

            var project = await _projectRepository.GetAsync(id);

            //var resources = JsonConvert.DeserializeObject<List<ProgrammingResource>>(project.ProgrammingResources);

            project.Status = StatusHelper.GetProjectStatusFromString(project.ProjectStatus);

            var comments = await _commentsRepository.GetProjectCommentsAsync(id);

            foreach (var comment in comments)
            {
                if (!string.IsNullOrEmpty(comment.Comment))
                {
                    comment.Comment = Regex.Replace(comment.Comment, @"\r\n?|\n", "<br />");
                }
            }

            var participants = await _participantsRepository.GetProjectParticipantsAsync(id);

            var results = await _resultRepository.GetResultsAsync(id);

            var user = GetAuthenticatedUser();

            var participant = (user.Email == null) ? null : await _participantsRepository.GetAsync(id, user.Email);

            var userRole = (user.Email == null) ? null : await _userRolesRepository.GetAsync(user.Email.ToLower());

            var isAdmin  = (userRole != null) && userRole.Role == "ADMIN";
            var isAuthor = (user.Email != null) && user.Email == project.AuthorId;

            var participantId = "";
            var isParticipant = false;
            var hasResult     = false;

            if (participant != null)
            {
                participantId = user.Email;
                isParticipant = true;

                hasResult = results.Any(r => r.ParticipantId == user.Email);
            }

            var projectFollowing = (user.Email == null) ? null : await _projectFollowRepository.GetAsync(user.Email, id);

            var isFollowing = projectFollowing != null;

            comments = SortComments(comments);

            var commenterIsModerator = new Dictionary <string, bool>();

            foreach (var comment in comments)
            {
                var role = await _userRolesRepository.GetAsync(comment.UserId);

                var isModerator = role != null && role.Role == "ADMIN";
                commenterIsModerator.Add(comment.Id, isModerator);
            }

            var userVotedForResults = new Dictionary <string, bool>();
            var resultVotes         = await _resultVoteRepository.GetProjectResultVotesAsync(project.Id);

            foreach (var result in results)
            {
                var match =
                    resultVotes.FirstOrDefault(x => x.ParticipantId == result.ParticipantId && x.VoterUserId == user.Email);

                userVotedForResults.Add(result.ParticipantId, match != null && user.Email != null);
            }

            var statusBarPartial = new ProjectDetailsStatusBarViewModel
            {
                Status            = project.Status,
                ParticipantsCount = participants.Count(),
                CompetitionRegistrationDeadline = project.CompetitionRegistrationDeadline,
                ImplementationDeadline          = project.ImplementationDeadline,
                VotingDeadline          = project.VotingDeadline,
                StatusCompletionPercent = CalculateStatusCompletionPercent(project)
            };

            var commentsPartial = new ProjectCommentPartialViewModel
            {
                ProjectId            = project.Id,
                UserId               = user.Email,
                Comments             = comments,
                IsAdmin              = isAdmin,
                IsAuthor             = isAuthor,
                CommenterIsModerator = commenterIsModerator,
                ProjectAuthorId      = project.AuthorId
            };

            var participantsPartial = new ProjectParticipantsPartialViewModel
            {
                CurrentUserId = user.Email,
                Participants  = participants,
                Status        = project.Status,
                HasResult     = hasResult
            };

            var resultsPartial = new ResultsPartialViewModel
            {
                Status              = project.Status,
                Results             = results,
                IsAdmin             = isAdmin,
                SkipVoting          = project.SkipVoting,
                UserVotedForResults = userVotedForResults,
                SubmissionsDeadline = project.ImplementationDeadline
            };

            var projectViewModel = new ProjectViewModel
            {
                Id                = project.Id,
                Name              = project.Name,
                Overview          = project.Overview,
                Description       = project.Description,
                ProjectCategories = projectCategories,
                Category          = project.Category,
                Status            = project.Status,
                BudgetFirstPlace  = project.BudgetFirstPlace,
                BudgetSecondPlace = project.BudgetSecondPlace,
                VotesFor          = project.VotesFor,
                VotesAgainst      = project.VotesAgainst,
                Created           = project.Created,
                LastModified      = project.LastModified,
                CompetitionRegistrationDeadline = project.CompetitionRegistrationDeadline,
                ImplementationDeadline          = project.ImplementationDeadline,
                VotingDeadline          = project.VotingDeadline,
                StatusBarPartial        = statusBarPartial,
                CommentsPartial         = commentsPartial,
                ParticipantsPartial     = participantsPartial,
                ResultsPartial          = resultsPartial,
                AuthorId                = project.AuthorId,
                AuthorFullName          = project.AuthorFullName,
                ParticipantId           = participantId,
                IsParticipant           = isParticipant,
                IsAdmin                 = isAdmin,
                IsFollowing             = isFollowing,
                OtherProjects           = await GetOtherProjects(project.Id),
                ProgrammingResourceName = project.ProgrammingResourceName,
                ProgrammingResourceLink = project.ProgrammingResourceLink,
                SkipVoting              = project.SkipVoting,
                SkipRegistration        = project.SkipRegistration
            };

            if (!string.IsNullOrEmpty(project.Tags))
            {
                projectViewModel.TagsList = JsonConvert.DeserializeObject <List <string> >(project.Tags);

                var builder = new StringBuilder();
                foreach (var tag in projectViewModel.TagsList)
                {
                    builder.Append(tag).Append(", ");
                }
                projectViewModel.Tags = builder.ToString();
            }

            var fileInfo = await _fileInfoRepository.GetAsync(id);

            if (fileInfo != null)
            {
                var fileInfoViewModel = new ProjectFileInfoViewModel
                {
                    ContentType = fileInfo.ContentType,
                    FileName    = fileInfo.FileName
                };

                projectViewModel.FileInfo = fileInfoViewModel;
            }

            if (projectViewModel.Status == Status.Archive)
            {
                projectViewModel = await PopulateResultsViewModel(projectViewModel);
            }

            projectViewModel.ProjectUrl = project.Id;

            return(projectViewModel);
        }
        public async Task <IActionResult> VoteForResult(ResultVoteViewModel model)
        {
            if (model.ProjectId == null)
            {
                return(RedirectToAction("Index", "Home"));
            }

            var project = await _projectRepository.GetAsync(model.ProjectId);

            var voterId = GetAuthenticatedUser().Email;

            model.UserAgent = HttpContext.Request.Headers["User-Agent"].ToString();

            string voteType = null;
            var    role     = await _userRolesRepository.GetAsync(voterId);

            if (voterId == project.AuthorId)
            {
                voteType = "AUTHOR";
            }
            else if (role != null && role.Role == "ADMIN")
            {
                voteType = "ADMIN";
            }

            var vote = await _resultVoteRepository.GetAsync(model.ProjectId, model.ParticipantId, voterId);

            if (vote == null)
            {
                model.VoterUserId = voterId;
                model.Type        = voteType;

                await _resultVoteRepository.SaveAsync(model);

                var votes = await _resultVoteRepository.GetProjectResultVotesAsync(model.ProjectId);

                var totalVotes = votes.Count();
                var result     = await _resultRepository.GetAsync(model.ProjectId, model.ParticipantId);

                result.Votes += 1;

                await _resultRepository.UpdateAsync(result);
                await CalculateScores(totalVotes, model.ProjectId);

                return(RedirectToAction("ProjectDetails", "Project", new { id = model.ProjectId, resultsActive = true, votedForResult = true }));
            }
            else
            {
                await _resultVoteRepository.DeleteAsync(model.ProjectId, model.ParticipantId, voterId);

                var votes = await _resultVoteRepository.GetProjectResultVotesAsync(model.ProjectId);

                var totalVotes = votes.Count();
                var result     = await _resultRepository.GetAsync(model.ProjectId, model.ParticipantId);

                result.Votes -= 1;

                await _resultRepository.UpdateAsync(result);
                await CalculateScores(totalVotes, model.ProjectId);

                return(RedirectToAction("ProjectDetails", "Project", new { id = model.ProjectId, resultsActive = true, votedTwice = true }));
            }
        }
        // TODO: A lot of this, like the fetch methods should probably be its own ProjectModel class - it's really about the
        // Project, not just the ProjectView and anything that's related to the view only (like the projectCategories)
        // can get pushed into the separate ProjectViewModel class that has a ProjectModel property on it.
        private async Task <ProjectViewModel> GetProjectViewModel(string id)
        {
            var projectCategories = _categoriesRepository.GetCategories();

            var project = await _projectRepository.GetAsync(id);

            project.Status = StatusHelper.GetProjectStatusFromString(project.ProjectStatus);
            var projectDetailsAvatarIds = new List <string>();

            projectDetailsAvatarIds.Add(project.AuthorIdentifier);

            // TODO: And these type of additional fetch methods can be methods on the model - the more we break
            // it up, the easier it is to test and reuse.
            var comments = await _commentsRepository.GetProjectCommentsAsync(id);

            await FormatComments(id, projectDetailsAvatarIds, comments);

            var participants = await _participantsRepository.GetProjectParticipantsAsync(id);

            var results = await _resultRepository.GetResultsAsync(id);

            var user = UserModel.GetAuthenticatedUser(User.Identity);

            var participant = (user.Email == null) ? null : await _participantsRepository.GetAsync(id, user.Email);

            var userRole = (user.Email == null) ? null : await _userRolesRepository.GetAsync(user.Email.ToLower());

            var isAdmin  = (userRole != null) && userRole.Role == StreamsRoles.Admin;
            var isAuthor = (user.Email != null) && user.Email == project.AuthorId;

            var participantId = "";
            var isParticipant = false;
            var hasResult     = false;

            if (participant != null)
            {
                participantId = user.Email;
                isParticipant = true;

                hasResult = results.Any(r => r.ParticipantId == user.Email);
            }

            var projectFollowing = (user.Email == null) ? null : await _projectFollowRepository.GetAsync(user.Email, id);

            var isFollowing = projectFollowing != null;

            // TODO: As I go through this, wondering if we need a CommentsList model, especially since
            // comments are probably going to be important to the platform going forwards
            comments = SortComments(comments);

            var commenterIsModerator = new Dictionary <string, bool>();

            foreach (var comment in comments)
            {
                var role = await _userRolesRepository.GetAsync(comment.UserId);

                var isModerator = role != null && role.Role == StreamsRoles.Admin;
                commenterIsModerator.Add(comment.Id, isModerator);
            }

            // TODO: The votes might also need to be broken out, especially if we want to do
            // 5-star or numeric scoring
            var userVotedForResults = new Dictionary <string, bool>();
            var resultVotes         = await _resultVoteRepository.GetProjectResultVotesAsync(project.Id);

            foreach (var part in participants)
            {
                if (string.IsNullOrEmpty(part.UserIdentifier))
                {
                    var profile = await _personalDataService.FindClientsByEmail(part.UserId);

                    if (profile != null)
                    {
                        part.UserIdentifier = profile.Id;
                        await _participantsRepository.UpdateAsync(part);
                    }
                }

                projectDetailsAvatarIds.Add(part.UserIdentifier);
                var participantStreamsId = await _streamsIdRepository.GetOrCreateAsync(part.UserIdentifier);

                part.StreamsId = participantStreamsId.StreamsId;
            }

            foreach (var result in results)
            {
                if (string.IsNullOrEmpty(result.ParticipantIdentifier))
                {
                    var profile = await _personalDataService.FindClientsByEmail(result.ParticipantId);

                    result.ParticipantIdentifier = profile.Id;
                    await _resultRepository.UpdateAsync(result);
                }

                var match =
                    resultVotes.FirstOrDefault(x => x.ParticipantId == result.ParticipantId && x.VoterUserId == user.Email);

                userVotedForResults.Add(result.ParticipantId, match != null && user.Email != null);
                var resultStreamsId = await _streamsIdRepository.GetOrCreateAsync(result.ParticipantIdentifier);

                result.StreamsId = resultStreamsId.StreamsId;
            }

            var statusBarPartial = ProjectDetailsStatusBarViewModel.Create(project, participants.Count());

            var commentsPartial = new ProjectCommentPartialViewModel
            {
                ProjectId            = project.Id,
                UserId               = user.Email,
                Comments             = comments,
                IsAdmin              = isAdmin,
                IsAuthor             = isAuthor,
                CommenterIsModerator = commenterIsModerator,
                ProjectAuthorId      = project.AuthorId
            };

            var participantsPartial = new ProjectParticipantsPartialViewModel
            {
                CurrentUserId = user.Email,
                Participants  = participants,
                Status        = project.Status,
                HasResult     = hasResult
            };

            var resultsPartial = new ResultsPartialViewModel
            {
                Status              = project.Status,
                Results             = results,
                IsAdmin             = isAdmin,
                SkipVoting          = project.SkipVoting,
                UserVotedForResults = userVotedForResults,
                SubmissionsDeadline = project.ImplementationDeadline
            };

            var allExperts = await _projectExpertsRepository.GetAllUniqueAsync();

            var projectExperts = await _projectExpertsRepository.GetProjectExpertsAsync(id);

            foreach (var expert in projectExperts)
            {
                if (string.IsNullOrEmpty(expert.UserIdentifier) && !string.IsNullOrEmpty(expert.UserId))
                {
                    var profile = await _personalDataService.FindClientsByEmail(expert.UserId);

                    if (profile != null)
                    {
                        expert.UserIdentifier = profile.Id;
                        await _projectExpertsRepository.UpdateAsync(expert);
                    }
                }
                if (!string.IsNullOrEmpty(expert.UserIdentifier))
                {
                    projectDetailsAvatarIds.Add(expert.UserIdentifier);
                    expert.StreamsId = (await _streamsIdRepository.GetOrCreateAsync(expert.UserIdentifier)).StreamsId;
                }
            }

            var avatarsDictionary = await _personalDataService.GetClientAvatarsAsync(projectDetailsAvatarIds);

            participantsPartial.Avatars = avatarsDictionary.ToDictionary(kvp => kvp.Key, kvp => kvp.Value);
            commentsPartial.Avatars     = avatarsDictionary.ToDictionary(kvp => kvp.Key, kvp => kvp.Value);
            resultsPartial.Avatars      = avatarsDictionary.ToDictionary(kvp => kvp.Key, kvp => kvp.Value);

            projectExperts = projectExperts.OrderBy(x => x.Priority == 0).ThenBy(x => x.Priority);
            var authorStreamsId = await _streamsIdRepository.GetOrCreateAsync(project.AuthorIdentifier);

            var projectViewModel = new ProjectViewModel
            {
                Id                = project.Id,
                Name              = project.Name,
                Overview          = project.Overview,
                Description       = project.Description,
                ProjectCategories = projectCategories,
                Category          = project.Category,
                Status            = project.Status,
                BudgetFirstPlace  = project.BudgetFirstPlace,
                BudgetSecondPlace = project.BudgetSecondPlace,
                VotesFor          = project.VotesFor,
                VotesAgainst      = project.VotesAgainst,
                Created           = project.Created,
                LastModified      = project.LastModified,
                CompetitionRegistrationDeadline = project.CompetitionRegistrationDeadline,
                ImplementationDeadline          = project.ImplementationDeadline,
                VotingDeadline          = project.VotingDeadline,
                StatusBarPartial        = statusBarPartial,
                CommentsPartial         = commentsPartial,
                ParticipantsPartial     = participantsPartial,
                ResultsPartial          = resultsPartial,
                AuthorId                = project.AuthorId,
                AuthorFullName          = project.AuthorFullName,
                AuthorIdentifier        = project.AuthorIdentifier,
                ParticipantId           = participantId,
                IsParticipant           = isParticipant,
                IsAdmin                 = isAdmin,
                IsFollowing             = isFollowing,
                OtherProjects           = await GetOtherProjects(project.Id),
                ProgrammingResourceName = project.ProgrammingResourceName,
                ProgrammingResourceLink = project.ProgrammingResourceLink,
                SkipVoting              = project.SkipVoting,
                SkipRegistration        = project.SkipRegistration,
                ProjectExperts          = !projectExperts.Any() ? null : projectExperts,
                PrizeDescription        = project.PrizeDescription,
                StreamId                = project.StreamId,
                AllStreamProjects       = await GetStreamProjects(),
                CompactStreams          = await GetCompactStreams(),
                NameTag                 = project.NameTag,
                AuthorAvatarUrl         = avatarsDictionary[project.AuthorIdentifier],
                AuthorStreamsId         = authorStreamsId.StreamsId,
                Experts                 = allExperts.Select(ExpertViewModel.Create).ToList(),
                InfoForKycUsers         = project.InfoForKycUsers,
                DescriptionFooter       = project.DescriptionFooter
            };

            if (!string.IsNullOrEmpty(project.Tags))
            {
                projectViewModel.TagsList = JsonConvert.DeserializeObject <List <string> >(project.Tags);

                var builder = new StringBuilder();
                foreach (var tag in projectViewModel.TagsList)
                {
                    builder.Append(tag).Append(", ");
                }
                projectViewModel.Tags = builder.ToString();
            }

            projectViewModel.EditStreamProjects = new EditStreamProjects {
                ProjectsList = new List <StreamProject>()
            };
            if (!string.IsNullOrEmpty(project.StreamId))
            {
                var stream = await _streamRepository.GetAsync(project.StreamId);

                projectViewModel.StreamProjects = JsonConvert.DeserializeObject <List <StreamProject> >(stream.Stream);
            }

            var fileInfo = await _fileInfoRepository.GetAsync(id);

            if (fileInfo != null)
            {
                var fileInfoViewModel = new ProjectFileInfoViewModel
                {
                    ContentType = fileInfo.ContentType,
                    FileName    = fileInfo.FileName
                };

                projectViewModel.FileInfo = fileInfoViewModel;
            }

            if (projectViewModel.Status == Status.Archive)
            {
                projectViewModel = await PopulateResultsViewModel(projectViewModel);

                var winners = await _winnersRepository.GetWinnersAsync(project.Id);

                projectViewModel.Winners = winners.Select(x => WinnerViewModel.Create(x)).ToList();
            }

            projectViewModel.ProjectUrl = project.Id;

            return(projectViewModel);
        }
Exemple #5
0
        public async Task SaveWinners(string projectId)
        {
            var project = await _projectRepository.GetAsync(projectId);

            var results = await _resultRepository.GetResultsAsync(projectId);

            var votes = await _resultVoteRepository.GetProjectResultVotesAsync(projectId);

            var projectResultVoteDatas = votes as IList <IProjectResultVoteData> ?? votes.ToList();

            var adminVotes  = projectResultVoteDatas.Where(x => x.Type == "ADMIN");
            var authorVotes = projectResultVoteDatas.Where(x => x.Type == "AUTHOR");

            var totalVotesCount = projectResultVoteDatas.Count;
            var resultVoteDatas = adminVotes as IList <IProjectResultVoteData> ?? adminVotes.ToList();

            var adminVotesCount = resultVoteDatas.Count;
            var voteDatas       = authorVotes as IList <IProjectResultVoteData> ?? authorVotes.ToList();

            var authorVotesCount = voteDatas.Count;

            var userVotes = totalVotesCount - adminVotesCount - authorVotesCount;

            var resultScores = new Dictionary <string, double>();

            var projectResultDatas = results as IList <IProjectResultData> ?? results.ToList();

            foreach (var result in projectResultDatas)
            {
                double resultScore     = 0;
                double adminVotesScore = 0;
                double userVotesScore  = 0;

                var resultAdminVotes = resultVoteDatas.Where(x => x.ParticipantId == result.ParticipantId);
                var resultVotes      = projectResultVoteDatas.Where(x => x.ParticipantId == result.ParticipantId && x.Type != "ADMIN" && x.Type != "AUTHOR");
                var authorVote       = voteDatas.FirstOrDefault(x => x.ParticipantId == result.ParticipantId);

                var resultAdminVotesCount = Convert.ToDouble(resultAdminVotes.Count());
                var resultVotesCount      = Convert.ToDouble(resultVotes.Count());

                if (adminVotesCount != 0)
                {
                    adminVotesScore = (resultAdminVotesCount / Convert.ToDouble(adminVotesCount)) * AdminsVoteValue;
                }

                if (userVotes != 0)
                {
                    userVotesScore = (resultVotesCount / Convert.ToDouble(userVotes)) * CitizensVoteValue;
                }

                resultScore = adminVotesScore + userVotesScore;

                if (authorVote != null)
                {
                    resultScore += AuthorVoteValue;
                }

                resultScores.Add(result.ParticipantId, resultScore);
            }

            var firstPlaceWinner = resultScores.OrderByDescending(pair => pair.Value).Take(1).FirstOrDefault();

            var secondPlaceWinners = resultScores.OrderByDescending(pair => pair.Value).Skip(1).Take(3);

            var firstPlaceResult = projectResultDatas.FirstOrDefault(x => x.ParticipantId == firstPlaceWinner.Key);

            if (firstPlaceResult != null)
            {
                var firstWinner = new WinnerViewModel
                {
                    ProjectId    = firstPlaceResult.ProjectId,
                    WinnerId     = firstPlaceResult.ParticipantId,
                    FullName     = firstPlaceResult.ParticipantFullName,
                    Result       = firstPlaceResult.Link,
                    Votes        = firstPlaceResult.Votes,
                    Score        = firstPlaceResult.Score,
                    Place        = 1,
                    Budget       = project.BudgetFirstPlace,
                    WinningScore = firstPlaceWinner.Value
                };

                if (await WinnerIsEligible(firstWinner.ProjectId, firstWinner.WinnerId))
                {
                    await _winnersRepository.SaveAsync(firstWinner);
                }
            }

            if (project.BudgetSecondPlace != null)
            {
                foreach (var winner in secondPlaceWinners)
                {
                    var secondPlaceResult = projectResultDatas.FirstOrDefault(x => x.ParticipantId == winner.Key);

                    var secondWinner = new WinnerViewModel
                    {
                        ProjectId    = secondPlaceResult.ProjectId,
                        WinnerId     = secondPlaceResult.ParticipantId,
                        FullName     = secondPlaceResult.ParticipantFullName,
                        Result       = secondPlaceResult.Link,
                        Votes        = secondPlaceResult.Votes,
                        Score        = secondPlaceResult.Score,
                        Place        = 2,
                        Budget       = project.BudgetSecondPlace,
                        WinningScore = winner.Value
                    };

                    if (await WinnerIsEligible(secondWinner.ProjectId, secondWinner.WinnerId))
                    {
                        await _winnersRepository.SaveAsync(secondWinner);
                    }
                }
            }
        }
Exemple #6
0
        public async Task SaveWinners(string projectId, IEnumerable <WinnerViewModel> winners = null)
        {
            var project = await _projectRepository.GetAsync(projectId);

            var results = await _resultRepository.GetResultsAsync(projectId);

            var projectResultDatas = results as IList <IProjectResultData> ?? results.ToList();

            var votes = await _resultVoteRepository.GetProjectResultVotesAsync(projectId);

            var projectResultVoteDatas = votes as IList <IProjectResultVoteData> ?? votes.ToList();

            var resultScores = CalculateScores(projectResultDatas, projectResultVoteDatas);

            if (winners != null && winners.Any(x => !string.IsNullOrEmpty(x.WinnerId)))
            {
                //await SaveCustomWinners(projectId, winners);
                foreach (var winner in winners.Where(x => !string.IsNullOrEmpty(x.WinnerId)))
                {
                    var winnerResult = projectResultDatas.FirstOrDefault(x => x.ParticipantId == winner.WinnerId);
                    var winnerScore  = resultScores.First(x => x.Key == winner.WinnerId);
                    var budget       = winner.Budget;
                    if (budget == null)
                    {
                        budget = winner.Place == 1 ? project.BudgetFirstPlace : project.BudgetSecondPlace;
                    }

                    var winnerModel = WinnerViewModel.Create(winnerResult, winner.Place, winnerScore.Value, budget);
                    await _winnersRepository.SaveAsync(winnerModel);
                }

                return;
            }

            var firstPlaceWinner = resultScores.OrderByDescending(pair => pair.Value).Take(1).FirstOrDefault();
            var firstPlaceResult = projectResultDatas.FirstOrDefault(x => x.ParticipantId == firstPlaceWinner.Key);

            if (firstPlaceResult != null)
            {
                var firstWinner = WinnerViewModel.Create(firstPlaceResult, 1, firstPlaceWinner.Value, project.BudgetFirstPlace);

                if (await WinnerIsEligible(firstWinner.ProjectId, firstWinner.WinnerId))
                {
                    await _winnersRepository.SaveAsync(firstWinner);
                }
            }

            var secondPlaceWinners = resultScores.OrderByDescending(pair => pair.Value).Skip(1).Take(3);

            if (project.BudgetSecondPlace != null)
            {
                foreach (var winner in secondPlaceWinners)
                {
                    var secondPlaceResult = projectResultDatas.FirstOrDefault(x => x.ParticipantId == winner.Key);
                    var secondWinner      = WinnerViewModel.Create(secondPlaceResult, 2, winner.Value, project.BudgetSecondPlace);

                    if (await WinnerIsEligible(secondWinner.ProjectId, secondWinner.WinnerId))
                    {
                        await _winnersRepository.SaveAsync(secondWinner);
                    }
                }
            }
        }
        public async Task <IActionResult> VoteForResult(ResultVoteViewModel model)
        {
            if (model.ProjectId == null)
            {
                return(RedirectToAction("Index", "Home"));
            }

            var project = await _projectRepository.GetAsync(model.ProjectId);

            var voterId = UserModel.GetAuthenticatedUser(User.Identity).Email;

            model.UserAgent = HttpContext.Request.Headers["User-Agent"].ToString();

            string voteType = null;
            var    role     = await _userRolesRepository.GetAsync(voterId);

            if (voterId == project.AuthorId)
            {
                voteType = ResultVoteTypes.Author;
            }
            else if (role != null && role.Role == StreamsRoles.Admin)
            {
                voteType = ResultVoteTypes.Admin;
            }

            var vote = await _resultVoteRepository.GetAsync(model.ProjectId, model.ParticipantId, voterId);

            if (vote == null)
            {
                model.VoterUserId = voterId;
                model.Type        = voteType;

                await _resultVoteRepository.SaveAsync(model);

                var votes = await _resultVoteRepository.GetProjectResultVotesAsync(model.ProjectId);

                var totalVotes = votes.Count();
                var result     = await _resultRepository.GetAsync(model.ProjectId, model.ParticipantId);

                result.Votes += 1;

                await _resultRepository.UpdateAsync(result);
                await CalculateScores(totalVotes, model.ProjectId);

                TempData["ShowVotedForResultModal"] = true;

                return(RedirectToAction("ProjectDetails", "Project", new { id = model.ProjectId }, "tab_Results"));
            }
            else
            {
                await _resultVoteRepository.DeleteAsync(model.ProjectId, model.ParticipantId, voterId);

                var votes = await _resultVoteRepository.GetProjectResultVotesAsync(model.ProjectId);

                var totalVotes = votes.Count();
                var result     = await _resultRepository.GetAsync(model.ProjectId, model.ParticipantId);

                result.Votes -= 1;

                await _resultRepository.UpdateAsync(result);
                await CalculateScores(totalVotes, model.ProjectId);

                TempData["ShowVotedTwiceModal"] = true;

                return(RedirectToAction("ProjectDetails", "Project", new { id = model.ProjectId }, "tab_Results"));
            }
        }