Esempio n. 1
0
        public ElectionResult CalculateElectionResult(int positionId)
        {
            Position position = _repository.GetPosition(positionId);

            // Set up the Nominees for the one and only round of voting
            List <ElectionRoundNomineeResult> nomineeResults = new List <ElectionRoundNomineeResult>();

            foreach (Nominee nominee in position.Nominees)
            {
                nomineeResults.Add(new ElectionRoundNomineeResult()
                {
                    NomineeId = nominee.Id,
                    Votes     = position.Votes.Count(v => v.NomineeId == nominee.Id &&
                                                     !v.HasAbstained &&
                                                     v.PreferenceOrder == 1)
                });
            }

            // Create the one and only round result
            ElectionRoundResult roundResult = new ElectionRoundResult()
            {
                NomineeResults = nomineeResults,
                Round          = 1,
                TotalVotes     = nomineeResults.Sum(n => n.Votes),
            };

            // ... and the generic result object
            ElectionResult result = new ElectionResult()
            {
                PositionId          = positionId,
                SuccessfulNomineeId = nomineeResults.Aggregate((n1, n2) => n1.Votes > n2.Votes ? n1 : n2).NomineeId,
                RoundResults        = new List <ElectionRoundResult>()
            };

            result.RoundResults.Add(roundResult);

            return(result);
        }
        public ElectionResult CalculateElectionResult(int positionId)
        {
            Position position = _repository.GetPosition(positionId);
            int      round    = 1;

            // Create the generic result object
            ElectionResult result = new ElectionResult()
            {
                PositionId   = positionId,
                RoundResults = new List <ElectionRoundResult>()
            };

            // Set up the first round of voting
            ElectionRoundResult roundResult = new ElectionRoundResult()
            {
                NomineeResults = new List <ElectionRoundNomineeResult>(),
                Round          = round
            };

            foreach (Nominee nominee in position.Nominees.Where(n => !position.Election.IsNominationConfirmationRequired || n.HasConfirmedNomination))
            {
                roundResult.NomineeResults.Add(new ElectionRoundNomineeResult()
                {
                    NomineeId = nominee.Id,
                    Votes     = 0
                });
            }

            // Repeat until we have a winner with majority
            while (result.SuccessfulNomineeId != 0)
            {
                // Record the votes for this round
                foreach (int userId in position.Votes.Select(v => v.UserId).Distinct())
                {
                    List <Vote> userVotes    = position.Votes.Where(v => v.UserId == userId).OrderBy(v => v.PreferenceOrder).ToList();
                    bool        voteRecorded = false;
                    for (int i = 0; i < userVotes.Count() && !voteRecorded; i++)
                    {
                        if (!userVotes[i].HasAbstained &&
                            //position.RoleTypeId == userVotes[i].User.MembershipType.R
                            roundResult.NomineeResults.Any(nr => nr.NomineeId == userVotes[i].NomineeId))
                        {
                            roundResult.NomineeResults.Single(nr => nr.NomineeId == userVotes[i].NomineeId).Votes++;
                            voteRecorded = true;
                        }
                    }

                    if (voteRecorded)
                    {
                        roundResult.TotalVotes++;
                    }
                    else
                    {
                        roundResult.InvalidVotes++;
                    }
                }

                result.RoundResults.Add(roundResult);

                // Do we have a majority winner?
                if (roundResult.NomineeResults.Any(nr => nr.Votes > (roundResult.TotalVotes / 2)))
                {
                    result.SuccessfulNomineeId = roundResult.NomineeResults.Single(nr => nr.Votes > (roundResult.TotalVotes / 2)).NomineeId;
                }
                else
                {
                    // Set up the next round of voting
                    round++;
                    int minimumVotes = roundResult.NomineeResults.Select(nr => nr.Votes).Min();

                    roundResult = new ElectionRoundResult()
                    {
                        NomineeResults = new List <ElectionRoundNomineeResult>(),
                        Round          = round
                    };

                    foreach (ElectionRoundNomineeResult nomineeResult in result.RoundResults.Single(rr => rr.Round == (round - 1)).NomineeResults.Where(nr => nr.Votes > minimumVotes))
                    {
                        roundResult.NomineeResults.Add(new ElectionRoundNomineeResult()
                        {
                            NomineeId = nomineeResult.NomineeId,
                            Votes     = 0
                        });
                    }
                }
            }

            result.RoundResults.Add(roundResult);

            return(result);
        }