示例#1
0
        /// <Summary>Switch current ballot</Summary>
        public void SetAsCurrentBallot(int ballotId)
        {
            if (ballotId == SessionKey.CurrentBallotId.FromSession(0))
            {
                return;
            }

            // learn about the one wanted
            var ballot = new BallotCacher(Db).AllForThisElection.SingleOrDefault(b => b.C_RowId == ballotId);

            if (ballot == null)
            {
                // invalid request!?
                return;
            }

            //var wantedComputerCode = ballotInfo.ComputerCode;
            //if (wantedComputerCode != UserSession.CurrentComputerCode)
            //{
            //  // get our record, update it, and save it back
            //  var computer = UserSession.CurrentComputer;
            //  Db.Computer.Attach(computer);

            //  computer.ComputerCode = wantedComputerCode;
            //  computer.LastContact = DateTime.Now;
            //  Db.SaveChanges();

            //  SessionKey.CurrentComputer.SetInSession(computer);
            //}

            SessionKey.CurrentBallotId.SetInSession(ballot.C_RowId);
        }
示例#2
0
        public override object CurrentBallotsInfoList(bool refresh = false)
        {
            if (refresh)
            {
                new ElectionAnalyzerNormal().RefreshBallotStatuses(); // identical for single name elections
                Db.SaveChanges();
            }

            var votes = new VoteCacher(Db).AllForThisElection;
            //      var ballotGuidsWithVotes = votes.Select(v => v.BallotGuid).Distinct().ToList();

            var ballots = new BallotCacher(Db).AllForThisElection;

            var ballotsForLocation = ballots
                                     .Where(b => b.LocationGuid == UserSession.CurrentLocationGuid)
                                     //        .Where(b => ballotGuidsWithVotes.Contains(b.BallotGuid))
                                     .OrderBy(b => b.ComputerCode)
                                     .ThenBy(b => b.BallotNumAtComputer)
                                     .ToList();

            var ballotGuids = ballotsForLocation.Select(b => b.BallotGuid).ToList();

            var totalCount = votes
                             .Where(v => ballotGuids.Contains(v.BallotGuid))
                             .Sum(vi => vi.SingleNameElectionCount).AsInt();

            return(new
            {
                Ballots = ballotsForLocation.ToList().Select(ballot => BallotInfoForJs(ballot, votes)),
                Total = totalCount
            });
        }
示例#3
0
        public override object CurrentBallotsInfoList(bool refresh = false)
        {
            if (refresh)
            {
                new ElectionAnalyzerNormal().RefreshBallotStatuses(); // identical for single name elections
                Db.SaveChanges();
            }

            var filter = UserSession.CurrentBallotFilter;

            if (UserSession.CurrentLocationName == LocationModel.OnlineLocationName ||
                UserSession.CurrentLocationName == LocationModel.ImportedLocationName)
            {
                // ignore filter for online
                filter = null;
            }

            var ballots = new BallotCacher(Db).AllForThisElection
                          .Where(b => b.LocationGuid == UserSession.CurrentLocationGuid)
                          .ToList()
                          .Where(b => filter.HasNoContent() || filter == b.ComputerCode)
                          .OrderBy(b => b.ComputerCode)
                          .ThenBy(b => b.BallotNumAtComputer)
                          .ToList();

            var totalCount = filter.HasNoContent()
        ? ballots.Count
        : new BallotCacher(Db).AllForThisElection.Count(b => b.LocationGuid == UserSession.CurrentLocationGuid);

            return(BallotsInfoList(ballots, totalCount));
        }
示例#4
0
        protected Ballot CreateAndRegisterBallot()
        {
            var currentLocationGuid = UserSession.CurrentLocationGuid;

            if (!currentLocationGuid.HasContent())
            {
                var locationModel = new LocationModel();
                currentLocationGuid             = locationModel.GetLocations_Physical().First().LocationGuid;
                UserSession.CurrentLocationGuid = currentLocationGuid;
            }
            var computerCode = UserSession.CurrentComputerCode;

            var ballotCacher = new BallotCacher(Db);
            var firstBallot  = ballotCacher.AllForThisElection.Any();

            var ballot = new Ballot
            {
                BallotGuid          = Guid.NewGuid(),
                LocationGuid        = currentLocationGuid,
                ComputerCode        = computerCode,
                BallotNumAtComputer = NextBallotNumAtComputer(),
                StatusCode          = BallotStatusEnum.Empty,
                Teller1             = UserSession.GetCurrentTeller(1),
                Teller2             = UserSession.GetCurrentTeller(2)
            };

            Db.Ballot.Add(ballot);

            if (firstBallot)
            {
                var locationCacher = new LocationCacher(Db);
                var location       = locationCacher.AllForThisElection.FirstOrDefault(l => l.LocationGuid == currentLocationGuid);
                if (location != null && location.BallotsCollected.AsInt() == 0)
                {
                    var ballotSources = new PersonCacher(Db)
                                        .AllForThisElection
                                        .Count(p => !string.IsNullOrEmpty(p.VotingMethod) && p.VotingLocationGuid == currentLocationGuid);
                    location.BallotsCollected = ballotSources;
                    locationCacher.UpdateItemAndSaveCache(location);
                }
            }

            Db.SaveChanges();

            ballotCacher.UpdateItemAndSaveCache(ballot);

            SessionKey.CurrentBallotId.SetInSession(ballot.C_RowId);

            return(ballot); //TODO: used to be view
        }
示例#5
0
        /// <Summary>Current Ballot... could be null</Summary>
        public Ballot GetCurrentBallot(bool refresh = false)
        {
            var isSingleNameElection = UserSession.CurrentElection.IsSingleNameElection;
            var currentBallotId      = SessionKey.CurrentBallotId.FromSession(0);

            var ballotCacher = new BallotCacher(Db);

            var ballot = ballotCacher.GetById(currentBallotId);

            if (ballot == null && isSingleNameElection)
            {
                ballot = ballotCacher.GetByComputerCode();
            }

            if (ballot == null)
            {
                if (isSingleNameElection)
                {
                    // will create empty ballot for this computer... do we need it?
                    //        ballot = CreateAndRegisterBallot();
                }
            }
            else
            {
                if (refresh)
                {
                    Db.Ballot.Attach(ballot);
                    var voteCacher = new VoteCacher(Db);
                    var votes      = voteCacher.AllForThisElection;
                    var voteInfos  = VoteInfosFor(ballot, votes);

                    SortVotes(voteInfos.OrderBy(vi => vi.PositionOnBallot).Select(v => v.VoteId).ToList(), voteCacher);
                    voteInfos = VoteInfosFor(ballot, votes);

                    BallotAnalyzerLocal.UpdateBallotStatus(ballot, voteInfos, true);

                    ballotCacher.UpdateItemAndSaveCache(ballot);
                    Db.SaveChanges();
                }
            }

            if (ballot != null && ballot.C_RowId != currentBallotId)
            {
                SessionKey.CurrentBallotId.SetInSession(ballot.C_RowId);
            }

            return(ballot);
        }
示例#6
0
        //    private void ClearOutOldComputerRecords()
        //    {
        //      // backward compatible... remove all records from database
        //
        //
        //      const int maxMinutesOfNoContact = 30;
        //      var computerCacher = new ComputerCacher(Db);
        //
        //      var now = DateTime.Now;
        //      var computers = computerCacher.AllForThisElection;
        //
        //      computerCacher.RemoveItemsAndSaveCache(
        //        computers.Where(c => !c.LastContact.HasValue
        //                             || (now - c.LastContact.Value).TotalMinutes > maxMinutesOfNoContact));
        //    }

        /// <Summary>Move this computer into this location (don't change the computer code)</Summary>
        public bool MoveCurrentComputerIntoLocation(int locationId)
        {
            var location = new LocationCacher(Db).AllForThisElection.SingleOrDefault(l => l.C_RowId == locationId);

            if (location == null)
            {
                // ignore the request
                return(false);
            }

            var computer = UserSession.CurrentComputer;

            AssertAtRuntime.That(computer != null, "computer missing");
            AssertAtRuntime.That(computer.ElectionGuid == location.ElectionGuid, "can't switch elections");

            computer.LocationGuid = location.LocationGuid;
            new ComputerCacher().UpdateComputer(computer);

            SessionKey.CurrentLocationGuid.SetInSession(location.LocationGuid);

            // reset ballot #
            SessionKey.CurrentBallotId.SetInSession(0);
            if (UserSession.CurrentElection.IsSingleNameElection)
            {
                // for single name elections, only have one ballot per computer per location. (But if altered from a normal election to a single name election, may have multiple.)
                var ballotId =
                    new BallotCacher(Db).AllForThisElection.Where(b => b.LocationGuid == location.LocationGuid &&
                                                                  b.ComputerCode == computer.ComputerCode)
                    .OrderBy(b => b.BallotNumAtComputer)
                    .Select(b => b.C_RowId).FirstOrDefault();
                if (ballotId != 0)
                {
                    SessionKey.CurrentBallotId.SetInSession(ballotId);
                }
            }

            return(true);
        }
示例#7
0
        public override JsonResult StartNewBallotJson()
        {
            if (UserSession.CurrentElectionStatus == ElectionTallyStatusEnum.Finalized)
            {
                return(new { Message = UserSession.FinalizedNoChangesMessage }.AsJsonResult());
            }

            // for single name, only one ballot per computer
            var ballots = new BallotCacher(Db).AllForThisElection;

            if (ballots.Any(b => b.ComputerCode == UserSession.CurrentComputerCode))
            {
                return(new { Message = "Only one 'ballot' per computer in single-name elections." }.AsJsonResult());
            }

            var locationModel = new LocationModel();

            if (locationModel.HasMultiplePhysicalLocations && UserSession.CurrentLocation == null)
            {
                return(new { Message = "Must select your location first!" }.AsJsonResult());
            }
            if (UserSession.GetCurrentTeller(1).HasNoContent())
            {
                return(new { Message = "Must select \"Teller at Keyboard\" first!" }.AsJsonResult());
            }

            var ballotInfo = CreateAndRegisterBallot();

            var allVotes = new VoteCacher(Db).AllForThisElection;

            return(new
            {
                BallotInfo = BallotInfoForJs(ballotInfo, allVotes),
                Ballots = CurrentBallotsInfoList()
            }.AsJsonResult());
        }
示例#8
0
        public bool CreateBallotForOnlineVoter(List <OnlineRawVote> poolList, out string errorMessage)
        {
            //{Id: 0, First:"", Last:"", OtherInfo:""}

            // double check
            var numberToElect = UserSession.CurrentElection.NumberToElect;

            if (poolList.Count != numberToElect)
            {
                errorMessage = $"Invalid number of votes ({poolList.Count}). Need {numberToElect}.";
                return(false);
            }

            var ballotCacher   = new BallotCacher(Db);
            var voteCacher     = new VoteCacher(Db);
            var locationHelper = new LocationModel(Db);
            var location       = locationHelper.GetOnlineLocation();

            // create ballot
            var ballot = new Ballot
            {
                BallotGuid          = Guid.NewGuid(),
                LocationGuid        = location.LocationGuid,
                ComputerCode        = ComputerModel.ComputerCodeForOnline,
                BallotNumAtComputer = 0, // maxNum + 1, // will reset later
                StatusCode          = BallotStatusEnum.Empty,
            };

            Db.Ballot.Add(ballot);
            Db.SaveChanges();

            ballotCacher.UpdateItemAndSaveCache(ballot);

            // add Votes
            var nextVoteNum = 0;

            foreach (var rawVote in poolList)
            {
                Vote vote;
                if (rawVote.Id > 0)
                {
                    var person = new PersonCacher(Db).AllForThisElection.FirstOrDefault(b => b.C_RowId == rawVote.Id);
                    if (person == null)
                    {
                        errorMessage = $"Error converting pool id {rawVote.Id} to person.";
                        return(false);
                    }

                    vote = new Vote
                    {
                        BallotGuid              = ballot.BallotGuid,
                        PositionOnBallot        = ++nextVoteNum,
                        StatusCode              = VoteStatusCode.Ok,
                        PersonGuid              = person.PersonGuid,
                        PersonCombinedInfo      = person.CombinedInfo,
                        SingleNameElectionCount = 1, // okay if set for normal election too
                        InvalidReasonGuid       = person.CanReceiveVotes.AsBoolean(true) ? null : person.IneligibleReasonGuid
                    };
                }
                else
                {
                    // "random" vote
                    vote = new Vote
                    {
                        BallotGuid              = ballot.BallotGuid,
                        PositionOnBallot        = ++nextVoteNum,
                        StatusCode              = VoteStatusCode.OnlineRaw,
                        SingleNameElectionCount = 1,
                        OnlineVoteRaw           = JsonConvert.SerializeObject(rawVote),
                    };

                    // attempt to match if it is exact...
                    var matched = new PersonCacher(Db).AllForThisElection
                                  // match on first and last name only
                                  .Where(p => p.FirstName.ToLower() == rawVote.First.ToLower() && p.LastName.ToLower() == rawVote.Last.ToLower())
                                  // don't match if our list has "otherInfo" for this person - there might be some special considerations
                                  .Where(p => p.OtherInfo.HasNoContent())
                                  .ToList();

                    if (matched.Count == 1)
                    {
                        // found one exact match
                        var person = matched[0];
                        vote.StatusCode         = VoteStatusCode.Ok;
                        vote.PersonGuid         = person.PersonGuid;
                        vote.PersonCombinedInfo = person.CombinedInfo;
                        vote.InvalidReasonGuid  = person.CanReceiveVotes.AsBoolean(true) ? null : person.IneligibleReasonGuid;
                    }
                }

                Db.Vote.Add(vote);

                Db.SaveChanges();

                voteCacher.UpdateItemAndSaveCache(vote);
            }

            var votes = voteCacher.AllForThisElection;

            BallotAnalyzerLocal.UpdateBallotStatus(ballot, VoteInfosFor(ballot, votes), true);

            ballotCacher.UpdateItemAndSaveCache(ballot);
            Db.SaveChanges();

            errorMessage = "";
            return(true);
        }
示例#9
0
        public JsonResult EditLocation(int id, string text)
        {
            var locationCacher = new LocationCacher(SharedDbContext);

            var location = locationCacher.AllForThisElection.SingleOrDefault(l => l.Id == id);
            var changed  = false;

            if (location == null)
            {
                location = new Location
                {
                    ElectionGuid = UserSession.CurrentElectionGuid,
                    LocationGuid = Guid.NewGuid()
                };
                SharedDbContext.Location.Add(location);
                changed = true;
            }
            else
            {
                SharedDbContext.Location.Attach(location);
            }

            int    locationId;
            string locationText;
            string status;
            var    success = false;

            if (text.HasNoContent() && location.Id > 0)
            {
                // don't delete last location
                if (AllLocations.Count() > 1)
                {
                    // delete existing if we can
                    var used = new BallotCacher(SharedDbContext).AllForThisElection.Any(b => b.LocationGuid == location.LocationGuid);
                    if (!used)
                    {
                        SharedDbContext.Location.Remove(location);
                        SharedDbContext.SaveChanges();
                        locationCacher.RemoveItemAndSaveCache(location);

                        status       = "Deleted";
                        success      = true;
                        locationId   = 0;
                        locationText = "";
                    }
                    else
                    {
                        status       = "Cannot deleted this location because it has Ballots recorded in it";
                        locationId   = location.Id;
                        locationText = location.Name;
                    }
                }
                else
                {
                    // only one
                    status       = "At least one location is required";
                    locationId   = location.Id;
                    locationText = location.Name;
                }
            }
            else if (text.HasContent())
            {
                locationText = location.Name = text;
                locationId   = location.Id; // may be 0 if new

                changed = true;
                status  = "Saved";
            }
            else
            {
                status       = "Nothing to save";
                locationId   = 0;
                locationText = "";
                success      = true;
                changed      = false;
            }

            if (changed)
            {
                SharedDbContext.SaveChanges();

                locationId = location.Id;
                locationCacher.UpdateItemAndSaveCache(location);
                success = true;
            }

            return(new
            {
                // returns 0 if deleted or not created
                Id = locationId,
                Text = locationText,
                Success = success,
                Status = status
            }.AsJsonResult());
        }