public JsonResult JoinElection(Guid electionGuid) { var voterId = UserSession.VoterId; if (voterId.HasNoContent()) { return(new { Error = "Invalid request" }.AsJsonResult()); } // confirm that this person is in the election var personQuery = Db.Person.Where(p => p.ElectionGuid == electionGuid); if (UserSession.VoterIdType == VoterIdTypeEnum.Email) { personQuery = personQuery.Where(p => p.Email == voterId); } else if (UserSession.VoterIdType == VoterIdTypeEnum.Phone) { personQuery = personQuery.Where(p => p.Phone == voterId); } else { return(new { Error = "Invalid request" }.AsJsonResult()); } var electionInfo = personQuery .Join(Db.Election, p => p.ElectionGuid, e => e.ElectionGuid, (p, e) => new { e, p }) .SingleOrDefault(); if (electionInfo == null) { return(new { Error = "Invalid election" }.AsJsonResult()); } var now = DateTime.Now; // get voting info var votingInfo = Db.OnlineVotingInfo .SingleOrDefault(ovi => ovi.ElectionGuid == electionGuid && ovi.PersonGuid == electionInfo.p.PersonGuid); // if (votingInfo == null) // { // var existingByEmail = Db.OnlineVotingInfo // .SingleOrDefault(ovi => ovi.ElectionGuid == electionGuid && ovi.PersonGuid == electionInfo.p.Email); // // if (existingByEmail != null) // { // return new // { // Error = "This email address was used for another person." // }.AsJsonResult(); // } // // var existingByPhone = Db.OnlineVotingInfo // .SingleOrDefault(ovi => ovi.ElectionGuid == electionGuid && ovi.Phone == electionInfo.p.Phone); // // if (existingByPhone != null) // { // return new // { // Error = "This phone number was used for another person." // }.AsJsonResult(); // } // } if (electionInfo.e.OnlineWhenOpen <= now && electionInfo.e.OnlineWhenClose > now) { // put election in session UserSession.CurrentElectionGuid = electionInfo.e.ElectionGuid; UserSession.VoterInElectionPersonGuid = electionInfo.p.PersonGuid; // UserSession.VoterInElectionPersonName = electionInfo.p.C_FullNameFL; string poolDecryptError = null; if (votingInfo == null) { votingInfo = new OnlineVotingInfo { ElectionGuid = electionInfo.e.ElectionGuid, PersonGuid = electionInfo.p.PersonGuid, Status = OnlineBallotStatusEnum.New, WhenStatus = now, HistoryStatus = "New|{0}".FilledWith(now.ToJSON()) }; Db.OnlineVotingInfo.Add(votingInfo); Db.SaveChanges(); } else { if (EncryptionHelper.IsEncrypted(votingInfo.ListPool)) { votingInfo.ListPool = new OnlineVoteHelper().GetDecryptedListPool(votingInfo, out poolDecryptError); } } // okay return(new { open = true, voterName = electionInfo.p.C_FullName, electionInfo.e.NumberToElect, OnlineSelectionProcess = electionInfo.e.OnlineSelectionProcess.DefaultTo(OnlineSelectionProcessEnum.Random.ToString().Substring(0, 1)), registration = VotingMethodEnum.TextFor(electionInfo.p.VotingMethod), votingInfo, poolDecryptError }.AsJsonResult()); } return(new { closed = true, votingInfo }.AsJsonResult()); }
/// <summary> /// Mark online ballot as "submitted" or locked. /// </summary> /// <param name="locked"></param> /// <returns></returns> public JsonResult LockPool(bool locked) { var currentElection = UserSession.CurrentElection; var personGuid = UserSession.VoterInElectionPersonGuid; var onlineVotingInfo = Db.OnlineVotingInfo .SingleOrDefault(ovi => ovi.ElectionGuid == currentElection.ElectionGuid && ovi.PersonGuid == personGuid); if (onlineVotingInfo == null) { return(new { Error = "Invalid request" }.AsJsonResult()); } if (onlineVotingInfo.Status == OnlineBallotStatusEnum.Processed) { // already processed... don't do anything return(new { Error = "Ballot already processed" }.AsJsonResult()); } var now = DateTime.Now; if (currentElection.OnlineWhenOpen <= now && currentElection.OnlineWhenClose > now) { var onlineVoteHelper = new OnlineVoteHelper(); var logHelper = new LogHelper(); if (!EncryptionHelper.IsEncrypted(onlineVotingInfo.ListPool)) { // upgrade previous record onlineVoteHelper.SetListPoolEncrypted(onlineVotingInfo); } if (locked) { // ensure we have enough votes var rawPool = onlineVoteHelper.GetDecryptedListPool(onlineVotingInfo, out var errorMessage); if (rawPool == null) { logHelper.Add("LockPool but pool is empty. " + errorMessage, true); return(new { Error = "Pool is empty" }.AsJsonResult()); } if (errorMessage.HasContent()) { logHelper.Add(errorMessage, true); return(new { Error = errorMessage }.AsJsonResult()); } List <OnlineRawVote> completePool; try { completePool = JsonConvert.DeserializeObject <List <OnlineRawVote> >(rawPool); } catch (Exception e) { logHelper.Add("LockPool but pool has invalid JSON. " + e.GetBaseException().Message + "... Start of pool: " + rawPool.Left(30), true); return(new { Error = "Technical error in pool. Please edit and try again." }.AsJsonResult()); } var numVotes = completePool.Count; if (numVotes < currentElection.NumberToElect) { var msg = $"Too few votes ({numVotes})"; logHelper.Add(msg + $" Required ({currentElection.NumberToElect})", true); return(new { Error = msg }.AsJsonResult()); } } onlineVotingInfo.PoolLocked = locked; onlineVotingInfo.Status = locked ? OnlineBallotStatusEnum.Submitted : OnlineBallotStatusEnum.Draft; onlineVotingInfo.HistoryStatus += $";{onlineVotingInfo.Status} ({UserSession.VoterLoginSource})|{now.ToJSON()}".FilledWith(onlineVotingInfo.Status, now.ToJSON()); onlineVotingInfo.WhenStatus = now; var personCacher = new PersonCacher(Db); var person = personCacher.AllForThisElection.SingleOrDefault(p => p.PersonGuid == onlineVotingInfo.PersonGuid); if (person == null) { return(new { Error = "Invalid request (2)" }.AsJsonResult()); } if (!person.CanVote.AsBoolean()) { return(new { Error = "Cannot vote" }.AsJsonResult()); } Db.Person.Attach(person); var peopleModel = new PeopleModel(); var votingMethodRemoved = false; string notificationType = null; person.HasOnlineBallot = locked; if (person.VotingMethod.HasContent() && person.VotingMethod != VotingMethodEnum.Online) { // teller has set. Voter can't change it... } else { if (locked) { person.VotingMethod = VotingMethodEnum.Online; person.RegistrationTime = now; person.VotingLocationGuid = new LocationModel().GetOnlineLocation().LocationGuid; person.EnvNum = null; var log = person.RegistrationLog; log.Add(new[] { peopleModel.ShowRegistrationTime(person, true), UserSession.VoterLoginSource, VotingMethodEnum.TextFor(person.VotingMethod), }.JoinedAsString("; ", true)); person.RegistrationLog = log; // logHelper.Add("Locked ballot"); logHelper.Add("Submitted Ballot", false, UserSession.VoterId); var notificationHelper = new NotificationHelper(); var notificationSent = notificationHelper.SendWhenBallotSubmitted(person, currentElection, out notificationType, out var error); if (!notificationSent) { notificationType = null; } } else { // not online or anywhere person.VotingMethod = null; person.VotingLocationGuid = null; person.EnvNum = null; votingMethodRemoved = true; var log = person.RegistrationLog; person.RegistrationTime = now; // set time so that the log will have it log.Add(new[] { peopleModel.ShowRegistrationTime(person, true), "Cancel Online", }.JoinedAsString("; ", true)); person.RegistrationTime = null; // don't keep it visible person.RegistrationLog = log; // logHelper.Add("Unlocked ballot"); logHelper.Add("Recalled Ballot", false, UserSession.VoterId); } } Db.SaveChanges(); personCacher.UpdateItemAndSaveCache(person); peopleModel.UpdateFrontDeskListing(person, votingMethodRemoved); // okay return(new { success = true, notificationType, person.VotingMethod, ElectionGuid = UserSession.CurrentElectionGuid, person.RegistrationTime, onlineVotingInfo.WhenStatus, onlineVotingInfo.PoolLocked }.AsJsonResult()); } return(new { Error = "Closed" }.AsJsonResult()); }
public JsonResult RegisterVotingMethod(int personId, string voteType, bool forceDeselect, int locationId) { if (UserSession.CurrentElectionStatus == ElectionTallyStatusEnum.Finalized) { return(new { Message = UserSession.FinalizedNoChangesMessage }.AsJsonResult()); } var locationModel = new LocationModel(); var hasMultiplePhysicalLocations = locationModel.HasMultiplePhysicalLocations; if (hasMultiplePhysicalLocations && UserSession.CurrentLocation == null) { return(new { Message = "Must select your location first!" }.AsJsonResult()); } if (UserSession.CurrentLocation.C_RowId != locationId) { new ComputerModel().MoveCurrentComputerIntoLocation(locationId); } if (UserSession.GetCurrentTeller(1).HasNoContent()) { return(new { Message = "Must select \"Teller at Keyboard\" first!" }.AsJsonResult()); } if (!VotingMethodEnum.Exists(voteType)) { return(new { Message = "Invalid type" }.AsJsonResult()); } var personCacher = new PersonCacher(Db); var person = personCacher.AllForThisElection.SingleOrDefault(p => p.C_RowId == personId); if (person == null) { return(new { Message = "Unknown person" }.AsJsonResult()); } if (person.VotingMethod == VotingMethodEnum.Online) { var onlineVoter = Db.OnlineVotingInfo.SingleOrDefault(ovi => ovi.PersonGuid == person.PersonGuid && ovi.ElectionGuid == person.ElectionGuid); if (onlineVoter != null) { if (onlineVoter.Status == OnlineBallotStatusEnum.Processed) { return(new { Message = "This online ballot has been processed. Registration cannot be changed." }.AsJsonResult()); } } } Db.Person.Attach(person); person.Teller1 = UserSession.GetCurrentTeller(1); person.Teller2 = UserSession.GetCurrentTeller(2); var votingMethodRemoved = false; Guid?oldVoteLocationGuid = null; Guid?newVoteLocationGuid = null; if (person.VotingMethod == voteType || forceDeselect || !person.CanVote.AsBoolean()) { oldVoteLocationGuid = person.VotingLocationGuid; // it is already set this way...turn if off person.VotingMethod = null; person.VotingLocationGuid = null; person.RegistrationTime = DateTime.Now; votingMethodRemoved = true; var log = person.RegistrationLog; log.Add(new[] { ShowRegistrationTime(person), "De-selected", ShowTellers(person), hasMultiplePhysicalLocations ? LocationName(UserSession.CurrentLocationGuid) : null, }.JoinedAsString("; ", true)); person.RegistrationLog = log; } else { person.VotingMethod = voteType; oldVoteLocationGuid = person.VotingLocationGuid; person.VotingLocationGuid = UserSession.CurrentLocationGuid; person.RegistrationTime = DateTime.Now; newVoteLocationGuid = person.VotingLocationGuid; var log = person.RegistrationLog; log.Add(new[] { ShowRegistrationTime(person), VotingMethodEnum.TextFor(person.VotingMethod), ShowTellers(person), hasMultiplePhysicalLocations ? LocationName(UserSession.CurrentLocationGuid) : null, }.JoinedAsString("; ", true)); person.RegistrationLog = log; // make number for every method except Registered var needEnvNum = person.EnvNum == null && voteType != VotingMethodEnum.Registered; if (needEnvNum) { person.EnvNum = new ElectionModel().GetNextEnvelopeNumber(); } } personCacher.UpdateItemAndSaveCache(person); UpdateFrontDeskListing(person, votingMethodRemoved); // if (lastRowVersion == 0) // { // lastRowVersion = person.C_RowVersionInt.AsLong() - 1; // } UpdateLocationCounts(newVoteLocationGuid, oldVoteLocationGuid, personCacher); Db.SaveChanges(); return(true.AsJsonResult()); }
public bool VotingMethodsContains(VotingMethodEnum method) { return(VotingMethods.DefaultTo("").Contains(method.Value)); }
public JsonResult RegisterVotingMethod(int personId, string voteType, long lastRowVersion, bool forceDeselect) { var Db = GetNewDbContext(); if (UserSession.CurrentElectionStatus == ElectionTallyStatusEnum.Finalized) { return(new { Message = UserSession.FinalizedNoChangesMessage }.AsJsonResult()); } var locationModel = new LocationModel(); if (locationModel.HasLocations && 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()); } if (!VotingMethodEnum.Exists(voteType)) { return(new { Message = "Invalid type" }.AsJsonResult()); } var personCacher = new PersonCacher(Db); var person = personCacher.AllForThisElection.SingleOrDefault(p => p.Id == personId); if (person == null) { return(new { Message = "Unknown person" }.AsJsonResult()); } var timeOffset = UserSession.TimeOffsetServerAhead; Db.Person.Attach(person); person.Teller1 = UserSession.GetCurrentTeller(1); person.Teller2 = UserSession.GetCurrentTeller(2); var votingMethodRemoved = false; Guid?oldVoteLocationGuid = null; Guid?newVoteLocationGuid = null; if (person.VotingMethod == voteType || forceDeselect) { oldVoteLocationGuid = person.VotingLocationGuid; // it is already set this way...turn if off person.VotingMethod = null; person.VotingLocationGuid = null; person.RegistrationTime = DateTime.Now; votingMethodRemoved = true; var log = person.RegistrationLogAsList; log.Add(new[] { ShowRegistrationTime(timeOffset, person), "De-selected", ShowTellers(person), LocationName(UserSession.CurrentLocationGuid), }.JoinedAsString("; ", true)); person.RegistrationLogAsList = log; } else { person.VotingMethod = voteType; oldVoteLocationGuid = person.VotingLocationGuid; person.VotingLocationGuid = UserSession.CurrentLocationGuid; person.RegistrationTime = DateTime.Now; newVoteLocationGuid = person.VotingLocationGuid; var log = person.RegistrationLogAsList; log.Add(new[] { ShowRegistrationTime(timeOffset, person), VotingMethodEnum.TextFor(person.VotingMethod), ShowTellers(person), LocationName(person.VotingLocationGuid), }.JoinedAsString("; ", true)); person.RegistrationLogAsList = log; // make number for every method except Registered var needEnvNum = person.EnvNum == null && voteType != VotingMethodEnum.Registered; if (needEnvNum) { person.EnvNum = new ElectionModel().GetNextEnvelopeNumber(); } } personCacher.UpdateItemAndSaveCache(person); UpdateFrontDeskListing(person, votingMethodRemoved); if (lastRowVersion == 0) { lastRowVersion = person.C_RowVersionInt.AsLong() - 1; } UpdateLocationCounts(newVoteLocationGuid, oldVoteLocationGuid, personCacher); Db.SaveChanges(); return(true.AsJsonResult()); }