示例#1
0
        public async Task <LiveElectionInfo> ImportLocalityResults(Ballot ballot, ElectionResultsQuery query)
        {
            using (var dbContext = _serviceProvider.CreateScope().ServiceProvider.GetService <ApplicationDbContext>())
            {
                var county = await dbContext.Counties.FirstOrDefaultAsync(c => c.CountyId == query.CountyId);

                if (county == null)
                {
                    return(LiveElectionInfo.Default);
                }
                var url    = _liveElectionUrlBuilder.GetFileUrl(ballot.BallotType, ElectionDivision.County, county.ShortName, null);
                var stream = await _fileDownloader.Download(url.Value);

                var pollingSections = await ExtractCandidateResultsFromCsv(stream, new CsvIndexes(CsvMode.National));

                var locality =
                    await dbContext.Localities.FirstOrDefaultAsync(l => l.LocalityId == query.LocalityId);

                var sectionsForLocality       = pollingSections.Where(p => p.Siruta == locality.Siruta).ToList();
                LiveElectionInfo electionInfo = new LiveElectionInfo();
                foreach (var pollingSection in sectionsForLocality)
                {
                    electionInfo.ValidVotes += pollingSection.ValidVotes;
                    electionInfo.NullVotes  += pollingSection.NullVotes;
                }
                if (locality == null)
                {
                    return(LiveElectionInfo.Default);
                }

                var candidateResults = sectionsForLocality.SelectMany(s => s.Candidates).ToList();
                GroupResults(candidateResults, electionInfo);
                return(electionInfo);
            }
        }
示例#2
0
        public async Task <Result <List <PartyList> > > GetBallotCandidates(ElectionResultsQuery query)
        {
            using (var dbContext = _serviceProvider.CreateScope().ServiceProvider.GetService <ApplicationDbContext>())
            {
                var ballot = dbContext.Ballots
                             .AsNoTracking()
                             .Include(b => b.Election)
                             .FirstOrDefault(e => e.BallotId == query.BallotId);
                var candidates = await GetCandidateResultsFromQueryAndBallot(query, ballot, dbContext);

                var minorities = await GetMinorities(ballot, dbContext);

                candidates = candidates.Concat(minorities).ToList();
                return(candidates
                       .GroupBy(c => c.PartyName)
                       .Select(p => new PartyList
                {
                    Candidates = p.OrderBy(c => c.BallotPosition).Select(c => new BasicCandidateInfo
                    {
                        Name = c.Name
                    }).ToList(),
                    Name = p.FirstOrDefault()?.PartyName
                }).ToList());
            }
        }
示例#3
0
 public async Task <List <ArticleResponse> > GetNewsFeed(ElectionResultsQuery query, int electionId)
 {
     using (var dbContext = _serviceProvider.CreateScope().ServiceProvider.GetService <ApplicationDbContext>())
     {
         return(await GetElectionNews(dbContext, query.BallotId, electionId));
     }
 }
示例#4
0
        public async Task <ActionResult <List <PartyList> > > GetCandidatesForBallot([FromQuery] ElectionResultsQuery query, int ballotId)
        {
            try
            {
                query.BallotId = ballotId;
                if (query.LocalityId == 0)
                {
                    query.LocalityId = null;
                }
                if (query.CountyId == 0)
                {
                    query.CountyId = null;
                }
                if (query.Round == 0)
                {
                    query.Round = null;
                }

                var result = await _appCache.GetOrAddAsync(
                    query.GetCacheKey(), () => _resultsAggregator.GetBallotCandidates(query),
                    DateTimeOffset.Now.AddMinutes(query.GetCacheDurationInMinutes()));

                return(result.Value);
            }
            catch (Exception e)
            {
                _appCache.Remove(query.GetCacheKey());
                Log.LogError(e, "Exception encountered while retrieving voter turnout stats");
                return(StatusCode(500, e.StackTrace));
            }
        }
示例#5
0
        private async Task <List <CandidateResult> > RetrieveAggregatedVotes(ElectionResultsQuery query, Ballot ballot)
        {
            switch (query.Division)
            {
            case ElectionDivision.County:
            {
                var result = await _winnersAggregator.GetLocalityCityHallWinnersByCounty(ballot.BallotId, query.CountyId.GetValueOrDefault());

                if (result.IsSuccess)
                {
                    var candidateResults = _winnersAggregator.RetrieveFirst10Winners(result.Value.Select(w => w.Candidate).ToList(), ballot.BallotType);

                    return(candidateResults);
                }
                throw new Exception(result.Error);
            }

            case ElectionDivision.National:
            {
                var result = await _winnersAggregator.GetAllLocalityWinners(ballot.BallotId);

                if (result.IsSuccess)
                {
                    var candidateResults = _winnersAggregator.RetrieveFirst10Winners(result.Value, ballot.BallotType);
                    return(candidateResults);
                }
                throw new Exception(result.Error);
            }

            default:
                throw new ArgumentOutOfRangeException(nameof(query));
            }
        }
示例#6
0
        public async Task <ActionResult <ElectionResponse> > GetBallot([FromQuery] ElectionResultsQuery query)
        {
            try
            {
                if (query.LocalityId == 0)
                {
                    query.LocalityId = null;
                }
                if (query.CountyId == 0)
                {
                    query.CountyId = null;
                }
                if (query.Round == 0)
                {
                    query.Round = null;
                }

                var expiration = GetExpirationDate(query);
                var result     = await _appCache.GetOrAddAsync(
                    query.GetCacheKey(), () => _resultsAggregator.GetBallotResults(query),
                    expiration);

                var newsFeed = await _resultsAggregator.GetNewsFeed(query, result.Value.Meta.ElectionId);

                result.Value.ElectionNews = newsFeed;
                return(result.Value);
            }
            catch (Exception e)
            {
                _appCache.Remove(query.GetCacheKey());
                Log.LogError(e, "Exception encountered while retrieving voter turnout stats");
                return(StatusCode(500, e.StackTrace));
            }
        }
示例#7
0
        private static async Task <Turnout> RetrieveAggregatedTurnoutForCityHalls(ElectionResultsQuery query,
                                                                                  Ballot ballot, ApplicationDbContext dbContext)
        {
            IQueryable <Turnout> queryable = dbContext.Turnouts
                                             .Where(t =>
                                                    t.BallotId == ballot.BallotId);

            if (ballot.BallotType == BallotType.CountyCouncilPresident || ballot.BallotType == BallotType.CountyCouncil)
            {
                queryable = queryable
                            .Where(t =>
                                   t.Division == ElectionDivision.County);
            }
            else
            {
                queryable = queryable
                            .Where(t =>
                                   t.Division == ElectionDivision.Locality);
            }


            if (query.CountyId != null)
            {
                queryable = queryable.Where(c => c.CountyId == query.CountyId);
            }

            var turnoutsForCounty = await queryable.ToListAsync();

            var turnout = AggregateTurnouts(turnoutsForCounty);

            turnout.BallotId = ballot.BallotId;
            return(turnout);
        }
示例#8
0
        public async Task <ActionResult <ElectionResponse> > GetBallot([FromQuery] ElectionResultsQuery query)
        {
            try
            {
                if (query.LocalityId == 0)
                {
                    query.LocalityId = null;
                }
                if (query.CountyId == 0)
                {
                    query.CountyId = null;
                }
                if (query.Round == 0)
                {
                    query.Round = null;
                }
                var result = await _resultsAggregator.GetBallotResults(query);

                return(result.Value);
            }
            catch (Exception e)
            {
                Log.LogError(e, "Exception encountered while retrieving voter turnout stats");
                return(StatusCode(500, e.Message));
            }
        }
示例#9
0
 private DateTimeOffset GetExpirationDate(ElectionResultsQuery electionResultsQuery)
 {
     if (electionResultsQuery.BallotId < 110) // ballot older than parliament elections in 2020
     {
         return(DateTimeOffset.Now.AddDays(1));
     }
     return(DateTimeOffset.Now.AddMinutes(_settings.ResultsCacheInMinutes));
 }
示例#10
0
 private static async Task <Turnout> GetDivisionTurnout(ElectionResultsQuery query, ApplicationDbContext dbContext, Ballot ballot)
 {
     return(await dbContext.Turnouts
            .FirstOrDefaultAsync(t =>
                                 t.BallotId == ballot.BallotId &&
                                 t.CountyId == query.CountyId &&
                                 t.CountryId == query.CountryId &&
                                 t.LocalityId == query.LocalityId));
 }
示例#11
0
        private async Task <List <CandidateResult> > GetMinorities(Ballot ballot, ApplicationDbContext dbContext)
        {
            var query = new ElectionResultsQuery();

            query.CountyId = null;
            query.Division = ElectionDivision.County;
            var minorities = await GetCandidateResultsFromQueryAndBallot(query, ballot, dbContext);

            return(minorities);
        }
示例#12
0
        private async Task <List <CandidateResult> > GetCandidates(ElectionResultsQuery query, Ballot ballot,
                                                                   ApplicationDbContext dbContext)
        {
            var resultsQuery = dbContext.CandidateResults
                               .Include(c => c.Party)
                               .Where(er =>
                                      er.BallotId == ballot.BallotId &&
                                      er.Division == query.Division &&
                                      er.CountyId == query.CountyId &&
                                      er.CountryId == query.CountryId &&
                                      er.LocalityId == query.LocalityId);

            return(await resultsQuery.ToListAsync());
        }
示例#13
0
        private async Task <Turnout> GetDivisionTurnout(ElectionResultsQuery query, ApplicationDbContext dbContext, Ballot ballot)
        {
            if (ballot.Election.Category == ElectionCategory.Local && !ballot.AllowsDivision(query.Division, query.LocalityId.GetValueOrDefault()) && !ballot.Election.Live)
            {
                return(await RetrieveAggregatedTurnoutForCityHalls(query, ballot, dbContext));
            }

            return(await dbContext.Turnouts
                   .FirstOrDefaultAsync(t =>
                                        t.BallotId == ballot.BallotId &&
                                        t.CountyId == query.CountyId &&
                                        t.CountryId == query.CountryId &&
                                        t.LocalityId == query.LocalityId));
        }
示例#14
0
        private async Task <List <CandidateResult> > RetrieveAggregatedVotes(ApplicationDbContext dbContext,
                                                                             ElectionResultsQuery query, Ballot ballot)
        {
            switch (query.Division)
            {
            case ElectionDivision.County:
            {
                var takeOnlyWinner = ballot.BallotType != BallotType.LocalCouncil;
                var result         = await _winnersAggregator.GetLocalityCityHallWinnersByCounty(ballot.BallotId, query.CountyId.GetValueOrDefault(), takeOnlyWinner);

                if (result.IsSuccess)
                {
                    var candidateResults = _winnersAggregator.RetrieveWinners(result.Value.Select(w => w.Candidate).ToList(), ballot.BallotType);

                    return(candidateResults);
                }
                throw new Exception(result.Error);
            }

            case ElectionDivision.National:
            {
                Result <List <CandidateResult> > result;
                if (ballot.BallotType == BallotType.CountyCouncil ||
                    ballot.BallotType == BallotType.CountyCouncilPresident)
                {
                    result = await _winnersAggregator.GetWinningCandidatesByCounty(ballot.BallotId);

                    if (result.IsSuccess)
                    {
                        return(_winnersAggregator.RetrieveWinners(result.Value, ballot.BallotType));
                    }
                }
                else
                {
                    var resultsForElection = await dbContext.CandidateResults
                                             .Include(c => c.Party)
                                             .Where(c => c.BallotId == query.BallotId && c.Division == ElectionDivision.Locality)
                                             .ToListAsync();

                    return(_winnersAggregator.RetrieveWinners(resultsForElection, ballot.BallotType));
                }
                throw new Exception(result.Error);
            }

            default:
                throw new ArgumentOutOfRangeException(nameof(query));
            }
        }
        public async Task <LiveElectionInfo> AggregateNationalResults(ElectionResultsQuery query, Ballot ballot)
        {
            var electionInfo = new LiveElectionInfo();

            using (var dbContext = _serviceProvider.CreateScope().ServiceProvider.GetService <ApplicationDbContext>())
            {
                var dbCounties = await dbContext.Counties.ToListAsync();

                var turnouts = await dbContext.Turnouts.Where(t => t.BallotId == ballot.BallotId).ToListAsync();

                var results            = new List <CandidateResult>();
                var capitalCityResults = await ImportCapitalCityResults(ballot);

                results.AddRange(capitalCityResults.Candidates);

                electionInfo.ValidVotes += capitalCityResults.ValidVotes;
                electionInfo.NullVotes  += capitalCityResults.NullVotes;

                foreach (var countyTurnout in turnouts.Where(t => t.Division == ElectionDivision.County && t.CountyId != Consts.CapitalCity))
                {
                    var county = dbCounties.First(c => c.CountyId == countyTurnout.CountyId);
                    if (county == null)
                    {
                        continue;
                    }
                    var url = _liveElectionUrlBuilder.GetFileUrl(ballot.BallotType, ElectionDivision.County, county.ShortName, null);

                    var countyResults = await Import(url.Value, new CsvIndexes(CsvMode.National));

                    if (countyResults.IsSuccess)
                    {
                        results.AddRange(countyResults.Value.Candidates);
                        electionInfo.ValidVotes += countyResults.Value.ValidVotes;
                        electionInfo.NullVotes  += countyResults.Value.NullVotes;
                    }
                }

                var diasporaResults = await AggregateDiasporaResults(query, ballot);

                electionInfo.ValidVotes += diasporaResults.ValidVotes;
                electionInfo.NullVotes  += diasporaResults.NullVotes;
                GroupResults(results.Concat(diasporaResults.Candidates).ToList(), electionInfo);
                //PrepareCandidates(electionInfo.Candidates, query, ballot);
                //await UpdateResults(dbContext, electionInfo.Candidates);
            }

            return(electionInfo);
        }
示例#16
0
        private static async Task <Turnout> RetrieveAggregatedTurnoutForCityHalls(ElectionResultsQuery query,
                                                                                  Ballot ballot, ApplicationDbContext dbContext)
        {
            if (ballot.Election.Live && query.Division == ElectionDivision.National)
            {
                var nationalTurnout = await dbContext.Turnouts
                                      .FirstOrDefaultAsync(t =>
                                                           t.BallotId == ballot.BallotId && t.Division == ElectionDivision.National);

                return(nationalTurnout);
            }
            var turnout   = new Turnout();
            var queryable = dbContext.Turnouts
                            .Where(t =>
                                   t.BallotId == ballot.BallotId &&
                                   t.CountyId == query.CountyId &&
                                   t.Division == ElectionDivision.Locality);

            if (ballot.Election.Live)
            {
                if (query.Division == ElectionDivision.County)
                {
                    if (ballot.BallotType != BallotType.Mayor && ballot.BallotType != BallotType.LocalCouncil)
                    {
                        queryable = dbContext.Turnouts
                                    .Where(t =>
                                           t.BallotId == ballot.BallotId &&
                                           t.Division == ElectionDivision.County);
                    }
                }
            }

            var turnoutsForCounty = await queryable.ToListAsync();

            turnout.BallotId       = ballot.BallotId;
            turnout.EligibleVoters = turnoutsForCounty.Sum(c => c.EligibleVoters);
            turnout.TotalVotes     = turnoutsForCounty.Sum(c => c.TotalVotes);
            turnout.ValidVotes     = turnoutsForCounty.Sum(c => c.ValidVotes);
            turnout.NullVotes      = turnoutsForCounty.Sum(c => c.NullVotes);
            return(turnout);
        }
示例#17
0
        public async Task <LiveElectionInfo> ImportCountryResults(ElectionResultsQuery query, Ballot ballot)
        {
            using (var dbContext = _serviceProvider.CreateScope().ServiceProvider.GetService <ApplicationDbContext>())
            {
                var country = await dbContext.Countries.FirstOrDefaultAsync(c => c.Id == query.CountryId);

                if (country == null)
                {
                    return(LiveElectionInfo.Default);
                }
                LiveElectionInfo electionInfo = new LiveElectionInfo();
                var url             = _liveElectionUrlBuilder.GetFileUrl(ballot.BallotType, ElectionDivision.Diaspora, null, null);
                var diasporaResults = await GetDiasporaResults(url, country, electionInfo, new CsvIndexes(CsvMode.Diaspora));

                var correspondenceUrl     = _liveElectionUrlBuilder.GetCorrespondenceUrl(ballot.BallotType, ElectionDivision.Diaspora);
                var correspondenceResults = await GetDiasporaResults(correspondenceUrl, country, electionInfo, new CsvIndexes(CsvMode.Correspondence));

                GroupResults(diasporaResults.Concat(correspondenceResults).ToList(), electionInfo);
                return(electionInfo);
            }
        }
示例#18
0
        private async Task <LiveElectionInfo> GetCandidatesFromDb(ElectionResultsQuery query, Ballot ballot,
                                                                  ApplicationDbContext dbContext)
        {
            LiveElectionInfo liveElectionInfo = new LiveElectionInfo();

            if (ballot.Election.Category == ElectionCategory.Local && query.CountyId.GetValueOrDefault().IsCapitalCity() == false)
            {
                if (!ballot.AllowsDivision(query.Division, query.LocalityId.GetValueOrDefault()) && !ballot.Election.Live)
                {
                    var aggregatedVotes = await RetrieveAggregatedVotes(dbContext, query, ballot);

                    liveElectionInfo.Candidates = aggregatedVotes;
                    liveElectionInfo.Aggregated = true;
                    return(liveElectionInfo);
                }
            }

            var results = await GetCandidateResultsFromQueryAndBallot(query, ballot, dbContext);

            liveElectionInfo.Candidates = results;
            return(liveElectionInfo);
        }
示例#19
0
        public async Task <LiveElectionInfo> AggregateDiasporaResults(ElectionResultsQuery query, Ballot ballot)
        {
            var electionInfo = new LiveElectionInfo();

            var diasporaUrl     = _liveElectionUrlBuilder.GetFileUrl(ballot.BallotType, ElectionDivision.Diaspora, null, null);
            var diasporaResults = await _appCache.GetOrAddAsync(
                $"{diasporaUrl}", () => Import(diasporaUrl.Value, new CsvIndexes(CsvMode.Diaspora)),
                DateTimeOffset.Now.AddMinutes(_liveElectionSettings.CsvCacheInMinutes));

            electionInfo.ValidVotes += diasporaResults.Value.ValidVotes;
            electionInfo.NullVotes  += diasporaResults.Value.NullVotes;
            var url = _liveElectionUrlBuilder.GetCorrespondenceUrl(ballot.BallotType, ElectionDivision.Diaspora);
            var correspondenceResults = await _appCache.GetOrAddAsync(
                $"{url}", () => Import(url.Value, new CsvIndexes(CsvMode.Correspondence)),
                DateTimeOffset.Now.AddMinutes(_liveElectionSettings.CsvCacheInMinutes));

            electionInfo.ValidVotes += correspondenceResults.Value.ValidVotes;
            electionInfo.NullVotes  += correspondenceResults.Value.NullVotes;
            GroupResults(diasporaResults.Value.Candidates.Concat(correspondenceResults.Value.Candidates).ToList(), electionInfo);

            return(electionInfo);
        }
示例#20
0
        public async Task <Turnout> GetDivisionTurnout(ElectionResultsQuery query, ApplicationDbContext dbContext, Ballot ballot)
        {
            if (ballot.Election.Category == ElectionCategory.Local && !ballot.AllowsDivision(query.Division, query.LocalityId.GetValueOrDefault()) && !ballot.Election.Live)
            {
                return(await RetrieveAggregatedTurnoutForCityHalls(query, ballot, dbContext));
            }

            var turnouts = await dbContext.Turnouts
                           .Where(t =>
                                  t.BallotId == ballot.BallotId &&
                                  t.CountyId == query.CountyId &&
                                  t.CountryId == query.CountryId &&
                                  t.Division == query.Division &&
                                  t.LocalityId == query.LocalityId).ToListAsync();

            if (turnouts.Count > 0 && query.Division == ElectionDivision.Diaspora_Country)
            {
                var turnout = AggregateTurnouts(turnouts);
                turnout.BallotId = ballot.BallotId;
                return(turnout);
            }
            if (turnouts.Count == 0 && query.Division == ElectionDivision.Diaspora)
            {
                turnouts = await dbContext.Turnouts
                           .Where(t =>
                                  t.BallotId == ballot.BallotId &&
                                  t.CountyId == null &&
                                  t.Division == ElectionDivision.Diaspora_Country &&
                                  t.LocalityId == null).ToListAsync();

                var turnout = AggregateTurnouts(turnouts);
                turnout.BallotId = ballot.BallotId;
                return(turnout);
            }
            return(turnouts.FirstOrDefault());
        }
示例#21
0
        private async Task <ElectionScope> CreateElectionScope(ApplicationDbContext dbContext, ElectionResultsQuery query)
        {
            var electionScope = new ElectionScope
            {
                Type = query.Division
            };
            County county;

            if (query.Division == ElectionDivision.County)
            {
                county = await dbContext.Counties.FirstOrDefaultAsync(c => c.CountyId == query.CountyId);

                electionScope.CountyId   = query.CountyId;
                electionScope.CountyName = county?.Name;
            }
            else
            {
                var locality = await dbContext.Localities.FirstOrDefaultAsync(c => c.LocalityId == query.LocalityId);

                if (query.Division == ElectionDivision.Locality)
                {
                    electionScope.LocalityId   = query.LocalityId;
                    electionScope.LocalityName = locality?.Name;
                    electionScope.CountyId     = locality?.CountyId;
                    county = await dbContext.Counties.FirstOrDefaultAsync(c => c.CountyId == query.CountyId);

                    electionScope.CountyName = county?.Name;
                }
                else if (query.Division == ElectionDivision.Diaspora_Country)
                {
                    var country = await dbContext.Countries.FirstOrDefaultAsync(c => c.Id == query.CountryId);

                    electionScope.CountryId   = query.CountryId;
                    electionScope.CountryName = country?.Name;
                }
            }

            return(electionScope);
        }
示例#22
0
        private async Task <LiveElectionInfo> GetCandidatesFromDb(ElectionResultsQuery query, Ballot ballot,
                                                                  ApplicationDbContext dbContext)
        {
            LiveElectionInfo liveElectionInfo = new LiveElectionInfo();

            if (ballot.Election.Live && ballot.AllowsDivision(query.Division, query.LocalityId.GetValueOrDefault()))
            {
                try
                {
                    int?siruta;
                    var county = await _territoryRepository.GetCountyById(query.CountyId);

                    if (query.LocalityId.GetValueOrDefault().IsCapitalCity() && query.Division == ElectionDivision.County)
                    {
                        siruta = null;
                    }
                    else
                    {
                        var locality = await _territoryRepository.GetLocalityById(query.LocalityId);

                        if (locality.IsFailure)
                        {
                            return(LiveElectionInfo.Default);
                        }
                        siruta = locality.IsSuccess ? locality.Value?.Siruta : null;
                    }
                    if (county.IsFailure)
                    {
                        return(LiveElectionInfo.Default);
                    }

                    var countyShortName = county.IsSuccess ? county.Value.ShortName : null;
                    var url             = _liveElectionUrlBuilder.GetFileUrl(ballot.BallotType, query.Division, countyShortName, siruta);
                    if (url.IsFailure)
                    {
                        return(LiveElectionInfo.Default);
                    }
                    liveElectionInfo = await _csvDownloaderJob.GetCandidatesFromUrl(url.Value);

                    var candidates = liveElectionInfo.Candidates;
                    var parties    = await dbContext.Parties.ToListAsync();

                    var candidatesForThisElection = await GetCandidateResultsFromQueryAndBallot(query, ballot, dbContext);

                    var dbCandidates = new List <CandidateResult>();
                    if (candidates == null)
                    {
                        liveElectionInfo.Candidates = dbCandidates;
                        return(liveElectionInfo);
                    }
                    foreach (var candidate in candidates)
                    {
                        dbCandidates.Add(PopulateCandidateData(candidatesForThisElection, candidate, parties, ballot));
                    }

                    liveElectionInfo.Candidates = dbCandidates;
                    return(liveElectionInfo);
                }
                catch (Exception e)
                {
                    Console.WriteLine("Probably there are no votes ");
                    Console.WriteLine(e);
                    return(new LiveElectionInfo());
                }
            }
            if (ballot.Election.Category == ElectionCategory.Local && query.CountyId.GetValueOrDefault().IsCapitalCity() == false)
            {
                if (!ballot.AllowsDivision(query.Division, query.LocalityId.GetValueOrDefault()) && !ballot.Election.Live)
                {
                    var aggregatedVotes = await RetrieveAggregatedVotes(query, ballot);

                    liveElectionInfo.Candidates = aggregatedVotes;
                    return(liveElectionInfo);
                }
            }

            var results = await GetCandidateResultsFromQueryAndBallot(query, ballot, dbContext);

            liveElectionInfo.Candidates = results;
            return(liveElectionInfo);
        }
示例#23
0
        public async Task <Result <ElectionResponse> > GetBallotResults(ElectionResultsQuery query)
        {
            using (var dbContext = _serviceProvider.CreateScope().ServiceProvider.GetService <ApplicationDbContext>())
            {
                var ballot = dbContext.Ballots
                             .AsNoTracking()
                             .Include(b => b.Election)
                             .FirstOrDefault(e => e.BallotId == query.BallotId);
                if (ballot == null)
                {
                    throw new Exception($"No results found for ballot id {query.BallotId}");
                }
                var electionResponse = new ElectionResponse();

                var divisionTurnout =
                    await GetDivisionTurnout(query, dbContext, ballot);

                var electionInfo = await GetCandidatesFromDb(query, ballot, dbContext);

                if (electionInfo.TotalVotes > 0)
                {
                    divisionTurnout = new Turnout
                    {
                        EligibleVoters = electionInfo.EligibleVoters,
                        CountedVotes   = electionInfo.TotalVotes,
                        TotalVotes     = divisionTurnout?.TotalVotes ?? electionInfo.TotalVotes,
                        ValidVotes     = electionInfo.ValidVotes,
                        NullVotes      = electionInfo.NullVotes
                    };
                }
                ElectionResultsResponse results;
                if (divisionTurnout == null)
                {
                    results = null;
                }
                else
                {
                    var parties = await _partiesRepository.GetAllParties();

                    results = ResultsProcessor.PopulateElectionResults(divisionTurnout, ballot, electionInfo.Candidates, parties.ToList());
                }

                electionResponse.Results     = results;
                electionResponse.Observation = await dbContext.Observations.FirstOrDefaultAsync(o => o.BallotId == ballot.BallotId);

                if (divisionTurnout != null)
                {
                    electionResponse.Turnout = new ElectionTurnout
                    {
                        TotalVotes     = divisionTurnout.TotalVotes,
                        EligibleVoters = divisionTurnout.EligibleVoters,
                    };
                }

                electionResponse.Scope = await CreateElectionScope(dbContext, query);

                electionResponse.Meta         = CreateElectionMeta(ballot);
                electionResponse.ElectionNews = await GetElectionNews(dbContext, ballot.BallotId, ballot.ElectionId);

                return(electionResponse);
            }
        }
示例#24
0
        public async Task <Result <ElectionResponse> > GetBallotResults(ElectionResultsQuery query)
        {
            using (var dbContext = _serviceProvider.CreateScope().ServiceProvider.GetService <ApplicationDbContext>())
            {
                var ballot = dbContext.Ballots
                             .AsNoTracking()
                             .Include(b => b.Election)
                             .FirstOrDefault(e => e.BallotId == query.BallotId);
                if (query.CountyId != null &&
                    query.CountyId.Value.IsCapitalCity() &&
                    query.Division == ElectionDivision.County &&
                    ballot.Date.Year == 2020)
                {
                    BallotType ballotType = ballot.BallotType;
                    if (ballot.BallotType == BallotType.Mayor)
                    {
                        ballotType = BallotType.CountyCouncilPresident;
                    }
                    if (ballot.BallotType == BallotType.LocalCouncil)
                    {
                        ballotType = BallotType.CountyCouncil;
                    }
                    ballot = dbContext.Ballots
                             .AsNoTracking()
                             .Include(b => b.Election)
                             .FirstOrDefault(e => e.ElectionId == ballot.ElectionId && e.BallotType == ballotType);
                }
                if (ballot == null)
                {
                    throw new Exception($"No results found for ballot id {query.BallotId}");
                }
                var electionResponse = new ElectionResponse();

                var divisionTurnout =
                    await GetDivisionTurnout(query, dbContext, ballot);

                var electionInfo = await GetCandidatesFromDb(query, ballot, dbContext);

                if (electionInfo.TotalVotes > 0)
                {
                    divisionTurnout = new Turnout
                    {
                        EligibleVoters = divisionTurnout.EligibleVoters,
                        CountedVotes   = electionInfo.TotalVotes,
                        TotalVotes     = divisionTurnout.TotalVotes,
                        ValidVotes     = electionInfo.ValidVotes,
                        NullVotes      = electionInfo.NullVotes
                    };
                }
                ElectionResultsResponse results;
                if (divisionTurnout == null)
                {
                    results = new ElectionResultsResponse
                    {
                        TotalVotes     = 0,
                        EligibleVoters = 0,
                        NullVotes      = 0,
                        ValidVotes     = 0,
                        Candidates     = new List <CandidateResponse>()
                    };
                }
                else
                {
                    var parties = await _partiesRepository.GetAllParties();

                    results = ResultsProcessor.PopulateElectionResults(divisionTurnout, ballot, electionInfo.Candidates, parties.ToList());
                }

                electionResponse.Aggregated  = electionInfo.Aggregated;
                electionResponse.Results     = results;
                electionResponse.Observation = await dbContext.Observations.FirstOrDefaultAsync(o => o.BallotId == ballot.BallotId);

                if (divisionTurnout != null)
                {
                    electionResponse.Turnout = new ElectionTurnout
                    {
                        TotalVotes     = divisionTurnout.TotalVotes,
                        EligibleVoters = divisionTurnout.EligibleVoters,
                    };
                    if (query.Division == ElectionDivision.Diaspora ||
                        query.Division == ElectionDivision.Diaspora_Country)
                    {
                        electionResponse.Turnout.EligibleVoters = electionResponse.Turnout.TotalVotes;
                    }
                }

                electionResponse.Scope = await CreateElectionScope(dbContext, query);

                electionResponse.Meta         = CreateElectionMeta(ballot);
                electionResponse.ElectionNews = await GetElectionNews(dbContext, ballot.BallotId, ballot.ElectionId);

                return(electionResponse);
            }
        }
示例#25
0
        public async Task <Result <ElectionResponse> > GetBallotResults(ElectionResultsQuery query)
        {
            using (var dbContext = _serviceProvider.CreateScope().ServiceProvider.GetService <ApplicationDbContext>())
            {
                var ballot = dbContext.Ballots
                             .AsNoTracking()
                             .Include(b => b.Election)
                             .FirstOrDefault(e => e.BallotId == query.BallotId);
                if (ballot == null)
                {
                    throw new Exception($"No results found for ballot id {query.BallotId}");
                }
                var electionResponse = new ElectionResponse();

                var candidates = await GetCandidates(query, ballot, dbContext);

                var divisionTurnout = await GetDivisionTurnout(query, dbContext, ballot);

                var electionTurnout = await GetElectionTurnout(dbContext, ballot);

                ElectionResultsResponse results;
                if (divisionTurnout == null)
                {
                    results = null;
                }
                else
                {
                    results = GetResults(divisionTurnout, ballot, candidates);
                    if (ballot.BallotType != BallotType.Referendum)
                    {
                        var parties = await dbContext.Parties.ToListAsync();

                        foreach (var candidate in results.Candidates)
                        {
                            if (candidate.PartyColor.IsEmpty())
                            {
                                var matchingParty = parties.FirstOrDefault(p =>
                                                                           candidate.ShortName.ContainsString(p.ShortName + "-") ||
                                                                           candidate.ShortName.ContainsString(p.ShortName + "+") ||
                                                                           candidate.ShortName.ContainsString(p.ShortName + " +") ||
                                                                           candidate.ShortName.ContainsString("+" + p.ShortName) ||
                                                                           candidate.ShortName.ContainsString("+ " + p.ShortName) ||
                                                                           candidate.ShortName.ContainsString(" " + p.ShortName) ||
                                                                           candidate.ShortName.ContainsString(p.ShortName + " "));
                                if (matchingParty != null)
                                {
                                    candidate.PartyColor = matchingParty.Color;
                                }
                            }
                        }
                    }
                }

                electionResponse.Results     = results;
                electionResponse.Observation = await dbContext.Observations.FirstOrDefaultAsync(o => o.BallotId == ballot.BallotId);

                if (electionTurnout != null)
                {
                    electionResponse.Turnout = new ElectionTurnout
                    {
                        TotalVotes     = electionTurnout.TotalVotes,
                        EligibleVoters = electionTurnout.EligibleVoters,

                        /*Breakdown = new ElectionTurnoutBreakdown
                         * {
                         *  Categories = new List<TurnoutCategory>
                         *  {
                         *      new TurnoutCategory
                         *      {
                         *          Type = VoteType.PermanentLists
                         *      }
                         *  }
                         * }*/
                    };
                }

                electionResponse.Scope = await CreateElectionScope(dbContext, query);

                electionResponse.Meta         = CreateElectionMeta(ballot);
                electionResponse.ElectionNews = await GetElectionNews(dbContext, ballot);

                return(electionResponse);
            }
        }
示例#26
0
        private static async Task <List <CandidateResult> > GetCandidateResultsFromQueryAndBallot(ElectionResultsQuery query, Ballot ballot,
                                                                                                  ApplicationDbContext dbContext)
        {
            var resultsQuery = dbContext.CandidateResults
                               .Include(c => c.Party)
                               .Where(er =>
                                      er.BallotId == ballot.BallotId &&
                                      er.Division == query.Division &&
                                      er.CountyId == query.CountyId &&
                                      er.CountryId == query.CountryId &&
                                      er.LocalityId == query.LocalityId);
            var results = await resultsQuery.ToListAsync();

            if (query.Division == ElectionDivision.Diaspora_Country)
            {
                results = results.GroupBy(r => r.Name).Select(r =>
                {
                    var candidate   = r.FirstOrDefault();
                    candidate.Votes = r.Sum(c => c.Votes);
                    return(candidate);
                }).ToList();
            }
            return(results);
        }
示例#27
0
        private async Task <LiveElectionInfo> GetCandidatesFromDb(ElectionResultsQuery query, Ballot ballot,
                                                                  ApplicationDbContext dbContext)
        {
            LiveElectionInfo liveElectionInfo = new LiveElectionInfo();

            if (ballot.Election.Live)
            {
                if (query.Division == ElectionDivision.National)
                {
                    return(await _appCache.GetOrAddAsync(
                               $"{ballot.BallotType}-national", () => _resultsCrawler.AggregateNationalResults(query, ballot),
                               DateTimeOffset.Now.AddMinutes(_settings.CsvCacheInMinutes)));
                }
                if (query.Division == ElectionDivision.Diaspora)
                {
                    return(await _appCache.GetOrAddAsync(
                               $"{ballot.BallotType}-diaspora", () => _resultsCrawler.AggregateDiasporaResults(query, ballot),
                               DateTimeOffset.Now.AddMinutes(_settings.CsvCacheInMinutes)));
                }
                if (query.Division == ElectionDivision.Diaspora_Country)
                {
                    return(await _appCache.GetOrAddAsync(
                               $"{ballot.BallotType}-diaspora_country-{query.CountryId}", () => _resultsCrawler.ImportCountryResults(query, ballot),
                               DateTimeOffset.Now.AddMinutes(_settings.CsvCacheInMinutes)));
                }
                var county = await dbContext.Counties.FirstOrDefaultAsync(c => c.CountyId == query.CountyId);

                if (county.CountyId.IsCapitalCity())
                {
                    int?index = null;
                    if (query.Division == ElectionDivision.Locality)
                    {
                        var sector = await dbContext.Localities.FirstOrDefaultAsync(l => l.LocalityId == query.LocalityId);

                        index = int.Parse(sector.Name.Split(" ").Last());
                    }
                    return(await _resultsCrawler.ImportCapitalCityResults(ballot, index));
                }

                if (query.Division == ElectionDivision.Locality)
                {
                    return(await _resultsCrawler.ImportLocalityResults(ballot, query));
                }
                var url = _urlBuilder.GetFileUrl(ballot.BallotType, query.Division, county?.ShortName,
                                                 query.LocalityId);
                if (url.IsFailure)
                {
                    return(LiveElectionInfo.Default);
                }
                var result = await _appCache.GetOrAddAsync(
                    $"{url}", () => _resultsCrawler.Import(url.Value),
                    DateTimeOffset.Now.AddMinutes(_settings.CsvCacheInMinutes));

                if (result.IsSuccess)
                {
                    return(result.Value);
                }
                return(LiveElectionInfo.Default);
            }
            if (ballot.Election.Category == ElectionCategory.Local && query.CountyId.GetValueOrDefault().IsCapitalCity() == false)
            {
                if (!ballot.AllowsDivision(query.Division, query.LocalityId.GetValueOrDefault()) && !ballot.Election.Live)
                {
                    var aggregatedVotes = await RetrieveAggregatedVotes(dbContext, query, ballot);

                    liveElectionInfo.Candidates = aggregatedVotes;
                    liveElectionInfo.Aggregated = true;
                    return(liveElectionInfo);
                }
            }

            var results = await GetCandidateResultsFromQueryAndBallot(query, ballot, dbContext);

            liveElectionInfo.Candidates = results;
            return(liveElectionInfo);
        }