Exemplo n.º 1
0
        /// <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());
        }