/// <Summary>Update the Ballot status of this ballot, based on these Votes.</Summary> /// <param name="ballot">The Ballot or vBallotInfo to check and update.</param> /// <param name="currentVotes">The list of Votes in this Ballot</param> /// <param name="refreshVoteStatus"></param> /// <returns>Returns the updated status code</returns> public BallotStatusWithSpoilCount UpdateBallotStatus(Ballot ballot, List <VoteInfo> currentVotes, bool refreshVoteStatus, bool forceSave = false) { //double check: currentVotes.ForEach(vi => AssertAtRuntime.That(vi.BallotGuid == ballot.BallotGuid)); if (refreshVoteStatus) { VoteAnalyzer.UpdateAllStatuses(currentVotes, new VoteCacher(Db).AllForThisElection, new Savers(Db).VoteSaver); } if (DetermineStatusFromVotesList(ballot.StatusCode, currentVotes, out var newStatus, out var spoiledCount) || forceSave) { BallotSaver(DbAction.Attach, ballot); ballot.StatusCode = newStatus; // BallotSaver(DbAction.Save, ballot); new BallotCacher(Db).UpdateItemAndSaveCache(ballot); Db.SaveChanges(); } Db.SaveChanges(); return(new BallotStatusWithSpoilCount { Status = BallotStatusEnum.Parse(newStatus), SpoiledCount = spoiledCount }); }
/// <Summary>Update the Ballot status of this ballot, based on these Votes.</Summary> /// <param name="ballot">The Ballot or vBallotInfo to check and update.</param> /// <param name="currentVotes">The list of Votes in this Ballot</param> /// <param name="refreshVoteStatus"></param> /// <returns>Returns the updated status code</returns> public BallotStatusWithSpoilCount UpdateBallotStatus(Ballot ballot, List <VoteInfo> currentVotes, bool refreshVoteStatus) { //double check: currentVotes.ForEach(vi => AssertAtRuntime.That(vi.BallotGuid == ballot.BallotGuid)); if (refreshVoteStatus) { VoteAnalyzer.UpdateAllStatuses(currentVotes, new VoteCacher(Db).AllForThisElection, new Savers(Db).VoteSaver); } string newStatus; int spoiledCount; //if (IsSingleNameElection) //{ // if (ballot.StatusCode != BallotStatusEnum.Ok) // { // BallotSaver(DbAction.Attach, ballot); // ballot.StatusCode = BallotStatusEnum.Ok; // BallotSaver(DbAction.Save, ballot); // } // return new BallotStatusWithSpoilCount // { // Status = BallotStatusEnum.Ok, // SpoiledCount = 0 // }; //} if (DetermineStatusFromVotesList(ballot.StatusCode, currentVotes, out newStatus, out spoiledCount)) { BallotSaver(DbAction.Attach, ballot); ballot.StatusCode = newStatus; BallotSaver(DbAction.Save, ballot); } return(new BallotStatusWithSpoilCount { Status = BallotStatusEnum.Parse(newStatus), SpoiledCount = spoiledCount }); }
public void RefreshBallotStatuses() { new BallotCacher(Db).DropThisCache(); new VoteCacher(Db).DropThisCache(); // first refresh person vote statuses new PeopleModel().EnsureFlagsAreRight(People, _hub, Savers.PersonSaver); // then refresh all votes _hub.StatusUpdate("Reviewing votes"); VoteAnalyzer.UpdateAllStatuses(VoteInfos, Votes, Savers.VoteSaver); // then refresh all ballots _hub.StatusUpdate("Reviewing ballots"); var ballotAnalyzer = new BallotAnalyzer(TargetElection, Savers.BallotSaver); ballotAnalyzer.UpdateAllBallotStatuses(Ballots, VoteInfos); Db.SaveChanges(); }
public JsonResult SaveVote(int personId, int voteId, Guid?invalidReason, int lastVid, int count, bool verifying) { if (UserSession.CurrentElectionStatus == ElectionTallyStatusEnum.Finalized) { return(new { Message = UserSession.FinalizedNoChangesMessage }.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 isSingleName = UserSession.CurrentElection.IsSingleNameElection; var ballot = GetCurrentBallot(); if (ballot == null) { // don't have an active Ballot! return(new { Updated = false, Error = "Invalid ballot" }.AsJsonResult()); } Db.Ballot.Attach(ballot); var voteCacher = new VoteCacher(Db); var personCacher = new PersonCacher(Db); if (voteId != 0) { // update existing record // find info about the existing Vote var vote = voteCacher.AllForThisElection.SingleOrDefault(v => v.C_RowId == voteId); if (vote == null) { // problem... client has a vote number, but we didn't find... return(new { Updated = false, Error = "Invalid vote id" }.AsJsonResult()); } if (vote.BallotGuid != ballot.BallotGuid) { // problem... client is focused on a different ballot! return(new { Updated = false, Error = "Invalid vote/ballot id" }.AsJsonResult()); } Db.Vote.Attach(vote); vote.SingleNameElectionCount = count; var person1 = personCacher.AllForThisElection.SingleOrDefault(p => p.C_RowId == personId); vote.PersonCombinedInfo = person1?.CombinedInfo; if (UserSession.CurrentLocation.IsVirtual) { // changing person on an online ballot if (person1 == null) { vote.PersonGuid = null; } else { vote.PersonGuid = person1.PersonGuid; invalidReason = person1.IneligibleReasonGuid; } vote.StatusCode = invalidReason == null ? VoteStatusCode.Ok : VoteStatusCode.Spoiled; } DetermineInvalidReasonGuid(invalidReason, vote); vote.StatusCode = VoteAnalyzer.DetermineStatus(new VoteInfo(vote, UserSession.CurrentElection, ballot, UserSession.CurrentLocation, person1)); Db.SaveChanges(); var votes = voteCacher.UpdateItemAndSaveCache(vote).AllForThisElection; var ballotStatusInfo = BallotAnalyzerLocal.UpdateBallotStatus(ballot, VoteInfosFor(ballot, votes), true); var sum = _helper.BallotCount(ballot.LocationGuid, isSingleName, null, votes); ballot.Teller1 = UserSession.GetCurrentTeller(1); ballot.Teller2 = UserSession.GetCurrentTeller(2); new BallotCacher(Db).UpdateItemAndSaveCache(ballot); Db.SaveChanges(); var ballotCounts = isSingleName ? new VoteCacher().AllForThisElection .Where(v => v.BallotGuid == ballot.BallotGuid) .Sum(v => v.SingleNameElectionCount) : 0; var ballotCountNames = isSingleName ? new VoteCacher().AllForThisElection .Count(v => v.BallotGuid == ballot.BallotGuid) : 0; return(new { Updated = true, BallotStatus = ballotStatusInfo.Status.Value, BallotStatusText = ballotStatusInfo.Status.DisplayText, ballotStatusInfo.SpoiledCount, LocationBallotsEntered = sum, BallotId = ballot.C_RowId, SingleBallotCount = ballotCounts, SingleBallotNames = ballotCountNames, VoteUpdates = GetVoteUpdates(lastVid, voteCacher, isSingleName, personCacher), LastVid = vote.C_RowId, vote.InvalidReasonGuid, Name = person1?.C_FullName, person1?.Area, vote = CurrentVotesForJs(GetCurrentBallot(), new List <Vote> { vote }).First() }.AsJsonResult()); } // make a new Vote record var location = new LocationCacher(Db).AllForThisElection.Single(l => l.LocationGuid == ballot.LocationGuid); if (location.IsVirtual) { return(new { Updated = false, Error = "Cannot add votes to an online ballot" }.AsJsonResult()); } var invalidReasonGuid = DetermineInvalidReasonGuid(invalidReason); var person = personCacher.AllForThisElection.SingleOrDefault(p => p.C_RowId == personId); var ok = person != null || (invalidReason != null && invalidReasonGuid != Guid.Empty); if (ok) { var nextVoteNum = 1 + voteCacher.AllForThisElection.Where(v => v.BallotGuid == ballot.BallotGuid) .OrderByDescending(v => v.PositionOnBallot) .Take(1) .Select(b => b.PositionOnBallot) .SingleOrDefault(); var vote = new Vote { BallotGuid = ballot.BallotGuid, PositionOnBallot = nextVoteNum, StatusCode = VoteStatusCode.Ok, SingleNameElectionCount = count }; if (person != null) { vote.PersonGuid = person.PersonGuid; vote.PersonCombinedInfo = person.CombinedInfo; vote.InvalidReasonGuid = person.CanReceiveVotes.AsBoolean(true) ? null : person.IneligibleReasonGuid; // VoteHelperLocal.IneligibleToReceiveVotes(person.IneligibleReasonGuid, // person.CanReceiveVotes); } vote.InvalidReasonGuid = invalidReasonGuid; Db.Vote.Add(vote); Db.SaveChanges(); var votes = voteCacher.UpdateItemAndSaveCache(vote).AllForThisElection; var rawBallot = CurrentRawBallot(); var ballotStatusInfo = BallotAnalyzerLocal.UpdateBallotStatus(rawBallot, VoteInfosFor(rawBallot, votes), true); var sum = _helper.BallotCount(ballot.LocationGuid, isSingleName, null, votes); new BallotCacher(Db).UpdateItemAndSaveCache(rawBallot); Db.SaveChanges(); var ballotCounts = isSingleName ? new VoteCacher().AllForThisElection .Where(v => v.BallotGuid == ballot.BallotGuid) .Sum(v => v.SingleNameElectionCount) : 0; var ballotCountNames = isSingleName ? new VoteCacher().AllForThisElection .Count(v => v.BallotGuid == ballot.BallotGuid) : 0; return(new { Updated = true, VoteId = vote.C_RowId, pos = vote.PositionOnBallot, BallotStatus = ballotStatusInfo.Status.Value, BallotStatusText = ballotStatusInfo.Status.DisplayText, ballotStatusInfo.SpoiledCount, BallotId = ballot.C_RowId, LocationBallotsEntered = sum, SingleBallotCount = ballotCounts, SingleBallotNames = ballotCountNames, VoteUpdates = GetVoteUpdates(lastVid, voteCacher, isSingleName, personCacher), LastVid = vote.C_RowId }.AsJsonResult()); } // don't recognize person id return(new { Updated = false, Error = "Invalid person. Please try again." }.AsJsonResult()); }