Exemple #1
0
        private void UpdateLocation(Guid?locationGuid, PersonCacher personCacher, LocationCacher locationCacher,
                                    ref bool saveNeeded)
        {
            if (locationGuid == null)
            {
                return;
            }

            var location = locationCacher.AllForThisElection.FirstOrDefault(l => l.LocationGuid == locationGuid);

            if (location == null)
            {
                return;
            }

            var oldCount = location.BallotsCollected;
            var newCount = personCacher.AllForThisElection.Count(
                p => p.VotingLocationGuid == location.LocationGuid && !String.IsNullOrEmpty(p.VotingMethod));

            if (oldCount == newCount)
            {
                return;
            }

            Db.Location.Attach(location);

            location.BallotsCollected = newCount;

            locationCacher.UpdateItemAndSaveCache(location);
            saveNeeded = true;
        }
Exemple #2
0
        private IEnumerable <Person> PeopleInCurrentElectionQuery()
        {
            var peopleInCurrentElection = new PersonCacher(Db).AllForThisElection;

            // && p.VotingLocationGuid == UserSession.CurrentLocationGuid

            return(IncludeAbsentees
        ? peopleInCurrentElection.Where(p => !string.IsNullOrEmpty(p.VotingMethod)).ToList()
        : peopleInCurrentElection.Where(p => p.VotingMethod == VotingMethodEnum.InPerson).ToList());
        }
        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
        }
Exemple #4
0
        public object GetTies(int tieBreakGroup)
        {
            var results = new ResultCacher(Db).AllForThisElection;
            var persons = new PersonCacher(Db).AllForThisElection;

            var ties = results
                       .Where(r => r.TieBreakGroup == tieBreakGroup)
                       .Join(persons, r => r.PersonGuid, p => p.PersonGuid, (r, p) => new { r, p })
                       .Select(j => new
            {
                name       = j.p.FullNameFL,
                isResolved = j.r.IsTieResolved.AsBoolean()
            })
                       .OrderBy(x => x.name);

            return(ties);
        }
Exemple #5
0
        private void UpdateLocationCounts(Guid?newVoteLocationGuid, Guid?oldVoteLocationGuid,
                                          PersonCacher personCacher)
        {
            // would be great to throw this into a remote queue to be processed later
            var locationCacher = new LocationCacher(Db);
            var saveNeeded     = false;

            UpdateLocation(newVoteLocationGuid, personCacher, locationCacher, ref saveNeeded);

            if (oldVoteLocationGuid != null && oldVoteLocationGuid != newVoteLocationGuid)
            {
                UpdateLocation(oldVoteLocationGuid, personCacher, locationCacher, ref saveNeeded);
            }

            if (saveNeeded)
            {
                Db.SaveChanges();
            }
        }
Exemple #6
0
        private IEnumerable <Person> PeopleInCurrentElectionQuery()
        {
            var peopleInCurrentElection = new PersonCacher(Db).AllForThisElection;
            var withAbsentees           = new[]
            {
                VotingMethodEnum.InPerson,
                VotingMethodEnum.DroppedOff,
                VotingMethodEnum.MailedIn,
                //VotingMethodEnum.Registered, -- not registered (should not be used with RollCall)
                VotingMethodEnum.CalledIn,
                VotingMethodEnum.Online,
                VotingMethodEnum.Imported,
                VotingMethodEnum.Custom1,
                VotingMethodEnum.Custom2,
                VotingMethodEnum.Custom3,
            }.Select(vm => vm.Value).ToList();

            return(IncludeAbsentees
        ? peopleInCurrentElection.Where(p => withAbsentees.Contains(p.VotingMethod)).ToList()
        : peopleInCurrentElection.Where(p => p.VotingMethod == VotingMethodEnum.InPerson).ToList());
        }
Exemple #7
0
        private void UpgradeOldData()
        {
            var Db           = GetNewDbContext();
            var personCacher = new PersonCacher(Db);
            var testInfo     = personCacher.AllForThisElection.Select(p => new { p.CombinedInfo }).FirstOrDefault();

            if (testInfo == null)
            {
                return;
            }

            if (testInfo.CombinedInfo.HasContent() && !testInfo.CombinedInfo.Contains("^"))
            {
                return;
            }

            // fix all data
            var voteCacher = new VoteCacher(Db);

            var people = personCacher.AllForThisElection;
            var votes  = voteCacher.AllForThisElection;

            var peopleModel = new PeopleModel();
            var saveNeeded  = false;

            foreach (var person in people)
            {
                AutoFix(person, votes, peopleModel, ref saveNeeded);
            }

            if (saveNeeded)
            {
                Db.SaveChanges();

                new LogHelper().Add("Updated person combined infos");
            }

            personCacher.DropThisCache();
            voteCacher.DropThisCache();
        }
Exemple #8
0
        /// <summary>
        ///   Process each person record, preparing it BEFORE the election starts. Altered... too dangerous to wipe information!
        /// </summary>
        public void SetInvolvementFlagsToDefault()
        {
            var Db           = SharedDbContext;
            var personCacher = new PersonCacher(Db);

            personCacher.DropThisCache();

            var peopleInElection = personCacher.AllForThisElection;
            var reason           = new ElectionModel().GetDefaultIneligibleReason();
            var counter          = 0;

            foreach (var person in peopleInElection)
            {
                SetInvolvementFlagsToDefault(person, reason);

                if (counter++ > 500)
                {
                    Db.SaveChanges();
                    counter = 0;
                }
            }

            Db.SaveChanges();
        }
        public JsonResult GetForVoter()
        {
            var currentElection = UserSession.CurrentElection;

            if (currentElection == null)
            {
                return(new
                {
                    Error = "Election not selected"
                }.AsJsonResult());
            }

            var selectionProcess = currentElection.OnlineSelectionProcess.AsEnum(OnlineSelectionProcessEnum.Random);

            switch (selectionProcess)
            {
            case OnlineSelectionProcessEnum.List:
            case OnlineSelectionProcessEnum.Both:
                // okay
                break;

            default:
                // empty list
                return(new
                {
                    people = new List <string>()
                }.AsJsonResult());
            }

            var rnd = new Random();

            var allForThisElection = new PersonCacher(Db).AllForThisElection;

            var maxRnd = allForThisElection.Count * 100;

            return(new
            {
                people = allForThisElection
                         .Select(p =>
                {
                    var irg = p.IneligibleReasonGuid;
                    string descriptionFor = null;

                    if (irg != null)
                    {
                        if (p.CanReceiveVotes.GetValueOrDefault())
                        {
                            // if they can receive votes, ignore any other status they may have (e.g. not a delegate)
                            irg = null;
                        }

                        if (irg != null)
                        {
                            descriptionFor = IneligibleReasonEnum.DescriptionFor(irg.Value);
                        }
                    }

                    return new
                    {
                        Id = p.C_RowId,
                        Name = p.FullName,
                        IRG = descriptionFor,
                        p.OtherInfo,
                        p.Area,
                        sort = rnd.Next(maxRnd)
                    };
                })
                         .OrderBy(p => p.sort)
            }.AsJsonResult());
        }
Exemple #10
0
        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());
        }
Exemple #11
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);
        }
Exemple #12
0
        private object GetVoteUpdates(int lastVoteId, VoteCacher voteCacher, bool isSingleName, PersonCacher personCacher)
        {
            if (lastVoteId == 0)
            {
                // single name elections
                return(null);
            }

            // ignores vote and ballot status - count how many times the name has been written on ballots

            var peopleInRecentVotes = voteCacher
                                      .AllForThisElection
                                      .Where(v => v.C_RowId > lastVoteId && v.PersonGuid != null)
                                      .Select(v => v.PersonGuid)
                                      .Distinct();

            var counts = voteCacher
                         .AllForThisElection
                         .Where(v => peopleInRecentVotes.Contains(v.PersonGuid))
                         .GroupBy(v => v.PersonGuid)
                         .Join(personCacher.AllForThisElection, votes => votes.Key, p => p.PersonGuid, (votes, p) => new { votes, p })
                         .Select(g => new
            {
                Id    = g.p.C_RowId,
                Count = g.votes.Sum(v => isSingleName ? v.SingleNameElectionCount : 1)
            })
                         .ToList();

            return(counts);
        }
Exemple #13
0
        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());
        }
Exemple #14
0
        public object GetCurrentResults()
        {
            try
            {
                var resultSummaryFinal =
                    _analyzer.ResultSummaryFinal; // resultSummaries.SingleOrDefault(rs => rs.ResultType == ResultType.Final);

                //TODO build online checks into base analysis

                // don't show any details if review is needed or online ballots need to be processed
                var issues = new List <string>();
                if (_election.OnlineCurrentlyOpen)
                {
                    issues.Add("Online voting is still open. It must be Closed before analyzing ballots.");
                }

                var unprocessedOnlineBallots = _election.OnlineWhenOpen.HasValue
          ? Db.OnlineVotingInfo
                                               .Join(Db.Person.Where(p => p.VotingMethod == VotingMethodEnum.Online.Value), ovi => ovi.PersonGuid, p => p.PersonGuid, (ovi, p) => ovi)
                                               .Count(ovi => ovi.ElectionGuid == UserSession.CurrentElectionGuid && ovi.Status == OnlineBallotStatusEnum.Submitted)
          : 0;
                if (unprocessedOnlineBallots > 0)
                {
                    issues.Add($"Online ballots waiting to be accepted: {unprocessedOnlineBallots}");
                }

                if (resultSummaryFinal.BallotsNeedingReview != 0 || issues.Any())
                {
                    var locations         = new LocationCacher(Db).AllForThisElection;
                    var multipleLocations = locations.Count() > 1;

                    var needReview = _analyzer.VoteInfos.Where(VoteAnalyzer.VoteNeedReview)
                                     .Join(locations, vi => vi.LocationId, l => l.C_RowId,
                                           (vi, location) => new { vi, location })
                                     .Select(x => new
                    {
                        x.vi.LocationId,
                        x.vi.BallotId,
                        Status = BallotStatusEnum.TextFor(x.vi.BallotStatusCode),
                        Ballot = multipleLocations ? $"{x.vi.C_BallotCode} ({x.location.Name})" : x.vi.C_BallotCode,
                    })
                                     .Distinct()
                                     .OrderBy(x => x.Ballot);

                    var needReview2 = _analyzer.Ballots.Where(BallotAnalyzer.BallotNeedsReview)
                                      .Join(locations, b => b.LocationGuid, l => l.LocationGuid,
                                            (b, location) => new { b, location })
                                      .OrderBy(x => x.b.ComputerCode)
                                      .ThenBy(x => x.b.BallotNumAtComputer)
                                      .Select(x => new
                    {
                        LocationId = x.location.C_RowId,
                        BallotId   = x.b.C_RowId,
                        Status     = BallotStatusEnum.TextFor(x.b.StatusCode),
                        Ballot     = multipleLocations ? $"{x.b.C_BallotCode} ({x.location.Name})" : x.b.C_BallotCode
                    });

                    return(new
                    {
                        NeedReview = needReview.Concat(needReview2).Distinct(),
                        _election.VotingMethods,
                        ResultsFinal = _analyzer.ResultSummaryFinal
                                       .GetPropertiesExcept(null, new[] { "ElectionGuid" }),
                        ResultsCalc =
                            _analyzer.ResultSummaries.First(rs => rs.ResultType == ResultType.Calculated)
                            .GetPropertiesExcept(null, new[] { "ElectionGuid" }),
                        ResultsManual = (_analyzer.ResultSummaries.FirstOrDefault(rs => rs.ResultType == ResultType.Manual) ??
                                         new ResultSummary()).GetPropertiesExcept(null, new[] { "ElectionGuid" }),
                        OnlineIssues = issues,
                        _election.OnlineCurrentlyOpen
                        //ResultsFinal =
                        //  resultSummaries.First(rs => rs.ResultType == ResultType.Final)
                        //    .GetPropertiesExcept(null, new[] { "ElectionGuid" }),
                    });
                }

                // show vote totals

                var persons = new PersonCacher(Db).AllForThisElection;

                var vResultInfos =
                    // TODO 2012-01-21 Glen Little: Could return fewer columns for non-tied results
                    _analyzer.Results // new ResultCacher(Db).AllForThisElection
                    .OrderBy(r => r.Rank)
                    .ToList()
                    .Select(r => new
                {
                    rid = r.C_RowId,
                    r.CloseToNext,
                    r.CloseToPrev,
                    r.ForceShowInOther,
                    r.IsTied,
                    r.IsTieResolved,
                    PersonName = PersonNameFor(persons, r),
                    r.Rank,
                    //ri.RankInExtra,
                    r.Section,
                    r.TieBreakCount,
                    r.TieBreakGroup,
                    r.TieBreakRequired,
                    r.VoteCount
                }).ToList();

                var ties = _analyzer.ResultTies //  new ResultTieCacher(Db).AllForThisElection
                           .OrderBy(rt => rt.TieBreakGroup)
                           .Select(rt => new
                {
                    rt.TieBreakGroup,
                    rt.NumInTie,
                    rt.NumToElect,
                    rt.TieBreakRequired,
                    rt.IsResolved
                }).ToList();

                //var spoiledVotesSummary = Db.vVoteInfoes.where
                return(new
                {
                    Votes = vResultInfos,
                    UserSession.CurrentElectionStatus,
                    Ties = ties,
                    NumToElect = _election.NumberToElect,
                    NumExtra = _election.NumberExtra,
                    // ShowCalledIn = _election.UseCallInButton,
                    // _election.CustomMethods,
                    _election.VotingMethods,
                    ShowOnline = _election.OnlineWhenOpen.HasValue,
                    ResultsManual =
                        (_analyzer.ResultSummaries.FirstOrDefault(rs => rs.ResultType == ResultType.Manual) ?? new ResultSummary())
                        .GetPropertiesExcept(null, new[] { "ElectionGuid" }),
                    ResultsCalc =
                        _analyzer.ResultSummaries.First(rs => rs.ResultType == ResultType.Calculated)
                        .GetPropertiesExcept(null, new[] { "ElectionGuid" }),
                    ResultsFinal =
                        _analyzer.ResultSummaries.First(rs => rs.ResultType == ResultType.Final)
                        .GetPropertiesExcept(null, new[] { "ElectionGuid" }),
                });
            }
            catch (Exception ex)
            {
                return(new
                {
                    Interrupted = true,
                    Msg = ex.GetAllMsgs("; ") + "\n" + ex.StackTrace
                });
            }
        }
Exemple #15
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());
        }
Exemple #16
0
        public JsonResult Import(int rowId)
        {
            var file =
                Db.ImportFile.SingleOrDefault(
                    fi => fi.ElectionGuid == UserSession.CurrentElectionGuid && fi.C_RowId == rowId);

            if (file == null)
            {
                return(new
                {
                    failed = true,
                    result = new[] { "File not found" }
                }.AsJsonResult());
            }

            var columnsToRead = file.ColumnsToRead;

            if (columnsToRead == null)
            {
                return(new
                {
                    failed = true,
                    result = new[] { "Mapping not defined" }
                }.AsJsonResult());
            }

            var start      = DateTime.Now;
            var textReader = new StringReader(file.Contents.AsString(file.CodePage));
            var csv        = new CsvReader(textReader, true)
            {
                SkipEmptyLines = true
            };

            //mapping:   csv->db,csv->db
            var currentMappings =
                columnsToRead.DefaultTo("").SplitWithString(",").Select(s => s.SplitWithString("->")).ToList();
            var dbFields      = DbFieldsList.ToList();
            var validMappings = currentMappings.Where(mapping => dbFields.Contains(mapping[1])).ToList();

            if (validMappings.Count == 0)
            {
                return(new
                {
                    failed = true,
                    result = new[] { "Mapping not defined" }
                }.AsJsonResult());
            }

            var mappedFields = dbFields.Where(f => validMappings.Select(m => m[1]).Contains(f)).ToList();

            if (!mappedFields.Contains("LastName"))
            {
                return(new
                {
                    failed = true,
                    result = new[] { "Last Name must be mapped" }
                }.AsJsonResult());
            }

            var currentPeople = new PersonCacher(Db).AllForThisElection.ToList();
            var personModel   = new PeopleModel();
            var defaultReason = new ElectionModel().GetDefaultIneligibleReason();

            var rowsProcessed          = 0;
            var rowsSkipped            = 0;
            var peopleAdded            = 0;
            var peopleSkipped          = 0;
            var peopleSkipWarningGiven = false;

            var hub          = new ImportHub();
            var peopleToLoad = new List <Person>();
            var result       = new List <string>();

            var unexpectedReasons = new Dictionary <string, int>();
            var validReasons      = 0;

            csv.ReadNextRecord();
            while (!csv.EndOfStream)
            {
                rowsProcessed++;

                var valuesSet       = false;
                var namesFoundInRow = false;

                var query = currentPeople.AsQueryable();

                var person = new Person();
                var reason = defaultReason;

                foreach (var currentMapping in validMappings)
                {
                    var dbFieldName = currentMapping[1];
                    var value       = csv[currentMapping[0]];

                    switch (dbFieldName)
                    {
                    case "IneligibleReasonGuid":
                        // match value to the list of Enums
                        value = value.Trim();
                        if (value.HasContent())
                        {
                            var match = IneligibleReasonEnum.GetFor(value);
                            if (match != null)
                            {
                                reason        = match;
                                validReasons += 1;
                            }
                            else
                            {
                                // tried but didn't match a valid reason!
                                reason = defaultReason;
                                value  = HttpUtility.HtmlEncode(value);
                                result.Add("Invalid Eligibility Status reason on line {0}: {1}".FilledWith(rowsProcessed + 1, value));

                                if (unexpectedReasons.ContainsKey(value))
                                {
                                    unexpectedReasons[value] += 1;
                                }
                                else
                                {
                                    unexpectedReasons.Add(value, 1);
                                }
                            }
                        }
                        break;

                    default:
                        person.SetPropertyValue(dbFieldName, value);
                        break;
                    }
                    ;
                    valuesSet = true;

                    switch (dbFieldName)
                    {
                    case "LastName":
                        query           = query.Where(p => p.LastName == value);
                        namesFoundInRow = namesFoundInRow || value.HasContent();
                        break;

                    case "FirstName":
                        query           = query.Where(p => p.FirstName == value);
                        namesFoundInRow = namesFoundInRow || value.HasContent();
                        break;

                    case "OtherLastNames":
                        query = query.Where(p => p.OtherLastNames == value);
                        break;

                    case "OtherNames":
                        query = query.Where(p => p.OtherNames == value);
                        break;

                    case "OtherInfo":
                        query = query.Where(p => p.OtherInfo == value);
                        break;

                    case "Area":
                        query = query.Where(p => p.Area == value);
                        break;

                    case "BahaiId":
                        query = query.Where(p => p.BahaiId == value);
                        break;

                    case "IneligibleReasonGuid":
                        //if (reason != defaultReason)
                        //{
                        //  query = query.Where(p => p.IneligibleReasonGuid == reason.Value);
                        //}
                        break;

                    default:
                        throw new ApplicationException("Unexpected: " + dbFieldName);
                    }
                }

                if (!valuesSet || !namesFoundInRow)
                {
                    rowsSkipped++;
                    result.Add("Skipping line " + rowsProcessed);
                }
                else if (query.Any())
                {
                    peopleSkipped++;
                    if (peopleSkipped < 10)
                    {
                        result.Add("Duplicate on line " + (rowsProcessed + 1));
                    }
                    else
                    {
                        if (!peopleSkipWarningGiven)
                        {
                            result.Add("More duplicates... (Only the first 10 are noted.)");
                            peopleSkipWarningGiven = true;
                        }
                    }
                }
                else
                {
                    //get ready for DB
                    person.ElectionGuid = UserSession.CurrentElectionGuid;
                    person.PersonGuid   = Guid.NewGuid();

                    personModel.SetCombinedInfoAtStart(person);
                    personModel.SetInvolvementFlagsToDefault(person, reason);

                    //Db.Person.Add(person);
                    currentPeople.Add(person);
                    peopleToLoad.Add(person);

                    peopleAdded++;

                    if (peopleToLoad.Count >= 500)
                    {
                        //Db.SaveChanges();

                        Db.BulkInsert(peopleToLoad);
                        peopleToLoad.Clear();
                    }
                }

                if (rowsProcessed % 100 == 0)
                {
                    hub.ImportInfo(rowsProcessed, peopleAdded);
                }

                csv.ReadNextRecord();
            }

            if (peopleToLoad.Count != 0)
            {
                Db.BulkInsert(peopleToLoad);
            }

            file.ProcessingStatus = "Imported";

            Db.SaveChanges();

            new PersonCacher().DropThisCache();

            result.AddRange(new[]
            {
                "Processed {0} data line{1}".FilledWith(rowsProcessed, rowsProcessed.Plural()),
                "Added {0} {1}.".FilledWith(peopleAdded, peopleAdded.Plural("people", "person"))
            });
            if (peopleSkipped > 0)
            {
                result.Add("{0} duplicate{1} ignored.".FilledWith(peopleSkipped, peopleSkipped.Plural()));
            }
            if (rowsSkipped > 0)
            {
                result.Add("{0} line{1} skipped or blank.".FilledWith(rowsSkipped, rowsSkipped.Plural()));
            }
            if (validReasons > 0)
            {
                result.Add("{0} {1} with recognized Eligibility Status Reasons.".FilledWith(validReasons, validReasons.Plural("people", "person")));
            }
            if (unexpectedReasons.Count > 0)
            {
                result.Add("{0} Eligibility Status Reason{1} not recognized: ".FilledWith(unexpectedReasons.Count, unexpectedReasons.Count.Plural()));
                foreach (var r in unexpectedReasons)
                {
                    result.Add("&nbsp; &nbsp; \"{0}\"{1}".FilledWith(r.Key, r.Value == 1 ? "" : " x" + r.Value));
                }
            }

            result.Add("Import completed in " + (DateTime.Now - start).TotalSeconds.ToString("0.0") + " s.");

            new LogHelper().Add("Imported file #" + rowId + ": " + result.JoinedAsString(" "), true);

            return(new
            {
                result,
                count = NumberOfPeople
            }.AsJsonResult());
        }
Exemple #17
0
        public JsonResult Import(int rowId)
        {
            var file =
                Db.ImportFile.SingleOrDefault(
                    fi => fi.ElectionGuid == UserSession.CurrentElectionGuid && fi.C_RowId == rowId);

            if (file == null)
            {
                return(new
                {
                    failed = true,
                    result = new[] { "File not found" }
                }.AsJsonResult());
            }

            var columnsToRead = file.ColumnsToRead;

            if (columnsToRead == null)
            {
                return(new
                {
                    failed = true,
                    result = new[] { "Mapping not defined" }
                }.AsJsonResult());
            }

            var start      = DateTime.Now;
            var fileString = file.Contents.AsString(file.CodePage);

            var firstDataRow       = file.FirstDataRow.AsInt();
            var numFirstRowsToSkip = firstDataRow - 2;

            if (numFirstRowsToSkip > 0)
            {
                // 1 based... headers on line 1, data on line 2. If 2 or less, ignore it.
                fileString = fileString.GetLinesAfterSkipping(numFirstRowsToSkip);
            }
            else
            {
                numFirstRowsToSkip = 0;
            }

            var textReader = new StringReader(fileString);
            var csv        = new CsvReader(textReader, true, ',', '"', '"', '#', ValueTrimmingOptions.All, 4096, null)
            {
                // had to provide all parameters in order to set ValueTrimmingOption.All
                SkipEmptyLines     = false,
                MissingFieldAction = MissingFieldAction.ReplaceByEmpty,
                SupportsMultiline  = false,
            };

            //mapping:   csv->db,csv->db
            var currentMappings =
                columnsToRead.DefaultTo("").SplitWithString(",").Select(s => s.SplitWithString(MappingSymbol)).ToList();
            var dbFields      = DbFieldsList.ToList();
            var validMappings = currentMappings.Where(mapping => dbFields.Contains(mapping[1])).ToList();

            if (validMappings.Count == 0)
            {
                return(new
                {
                    failed = true,
                    result = new[] { "Mapping not defined" }
                }.AsJsonResult());
            }

            var mappedFields = dbFields.Where(f => validMappings.Select(m => m[1]).Contains(f)).ToList();

            if (!mappedFields.Contains("LastName"))
            {
                return(new
                {
                    failed = true,
                    result = new[] { "Last Name must be mapped" }
                }.AsJsonResult());
            }
            if (!mappedFields.Contains("FirstName"))
            {
                return(new
                {
                    failed = true,
                    result = new[] { "First Name must be mapped" }
                }.AsJsonResult());
            }

            var phoneNumberChecker = new Regex(@"\+[0-9]{4,15}");
            var phoneNumberCleaner = new Regex(@"[^\+0-9]");
            var emailChecker       = new Regex(@".*@.*\..*");

            var currentPeople = new PersonCacher(Db).AllForThisElection.ToList();

            currentPeople.ForEach(p => p.TempImportLineNum = -1);

            var knownEmails = currentPeople.Where(p => p.Email != null).Select(p => p.Email.ToLower()).ToList();
            var knownPhones = currentPeople.Where(p => p.Phone != null).Select(p => p.Phone).ToList();

            var personModel = new PeopleModel();
            // var defaultReason = new ElectionModel().GetDefaultIneligibleReason();

            var currentLineNum = numFirstRowsToSkip > 0 ? numFirstRowsToSkip : 1; // including header row
            var rowsWithErrors = 0;
            var peopleAdded    = 0;
            var peopleSkipped  = 0;
            // var peopleSkipWarningGiven = false;

            var hub          = new ImportHub();
            var peopleToLoad = new List <Person>();
            var result       = new List <string>();

            var unexpectedReasons = new Dictionary <string, int>();
            // var validReasons = 0;
            var continueReading = true;

            hub.StatusUpdate("Processing", true);

            while (csv.ReadNextRecord() && continueReading)
            {
                if (csv.GetCurrentRawData() == null)
                {
                    continue;
                }

                // currentLineNum++;
                currentLineNum = numFirstRowsToSkip + (int)csv.CurrentRecordIndex + 1;

                var valuesSet       = false;
                var namesFoundInRow = 0;
                var errorInRow      = false;

                var duplicateInFileSearch = currentPeople.AsQueryable();
                var doDupQuery            = false;

                var person = new Person
                {
                    TempImportLineNum = currentLineNum
                };

                foreach (var currentMapping in validMappings)
                {
                    var csvColumnName = currentMapping[0];
                    var dbFieldName   = currentMapping[1];

                    string value;
                    try
                    {
                        value = csv[csvColumnName] ?? "";
                    }
                    catch (Exception e)
                    {
                        result.Add($"~E Line {currentLineNum} - {e.Message.Split('\r')[0]}. Are there \"\" marks missing?");
                        errorInRow      = true;
                        continueReading = false;
                        break;
                    }
                    var rawValue      = HttpUtility.HtmlEncode(value);
                    var originalValue = value;


                    switch (dbFieldName)
                    {
                    case "IneligibleReasonGuid":
                        // match value to the list of Enums
                        value = value.Trim();
                        if (value.HasContent())
                        {
                            if (value == "Eligible")
                            {
                                // leave as null
                            }
                            else
                            {
                                var match = IneligibleReasonEnum.GetFor(value);
                                if (match != null)
                                {
                                    person.IneligibleReasonGuid = match.Value;
                                }
                                else
                                {
                                    // tried but didn't match a valid reason!
                                    errorInRow = true;

                                    result.Add($"~E Line {currentLineNum} - Invalid Eligibility Status reason: {rawValue}");

                                    if (unexpectedReasons.ContainsKey(value))
                                    {
                                        unexpectedReasons[value] += 1;
                                    }
                                    else
                                    {
                                        unexpectedReasons.Add(value, 1);
                                    }
                                }
                            }
                        }
                        break;

                    case "FirstName":
                    case "LastName":
                        if (value.Trim() == "")
                        {
                            result.Add($"~E Line {currentLineNum} - {dbFieldName} must not be blank");
                        }
                        else
                        {
                            person.SetPropertyValue(dbFieldName, value);
                        }
                        break;

                    default:
                        person.SetPropertyValue(dbFieldName, value);
                        break;
                    }
                    ;

                    valuesSet = valuesSet || value.HasContent();

                    if (value.HasContent())
                    {
                        doDupQuery = true;
                        switch (dbFieldName)
                        {
                        case "LastName":
                            duplicateInFileSearch = duplicateInFileSearch.Where(p => p.LastName == value);
                            namesFoundInRow++;
                            break;

                        case "FirstName":
                            duplicateInFileSearch = duplicateInFileSearch.Where(p => p.FirstName == value);
                            namesFoundInRow++;
                            break;

                        case "OtherLastNames":
                            duplicateInFileSearch = duplicateInFileSearch.Where(p => p.OtherLastNames == value);
                            break;

                        case "OtherNames":
                            duplicateInFileSearch = duplicateInFileSearch.Where(p => p.OtherNames == value);
                            break;

                        case "OtherInfo":
                            duplicateInFileSearch = duplicateInFileSearch.Where(p => p.OtherInfo == value);
                            break;

                        case "Area":
                            duplicateInFileSearch = duplicateInFileSearch.Where(p => p.Area == value);
                            break;

                        case "BahaiId":
                            duplicateInFileSearch = duplicateInFileSearch.Where(p => p.BahaiId == value);
                            break;

                        case "Email":
                            if (value.HasContent())
                            {
                                value = value.ToLower();
                                if (!emailChecker.IsMatch(value))
                                {
                                    result.Add($"~E Line {currentLineNum} - Invalid email: {rawValue}");
                                    errorInRow = true;
                                }
                                else if (knownEmails.Contains(value))
                                {
                                    result.Add($"~E Line {currentLineNum} - Duplicate email: {rawValue}");
                                    errorInRow = true;
                                }

                                if (!errorInRow)
                                {
                                    knownEmails.Add(value);
                                }
                            }
                            break;

                        case "Phone":
                            if (value.HasContent())
                            {
                                value = phoneNumberCleaner.Replace(value, "");

                                if (!value.StartsWith("+") && value.Length == 10)
                                {
                                    // assume north american
                                    value = "+1" + value;
                                }

                                if (!phoneNumberChecker.IsMatch(value))
                                {
                                    result.Add($"~E Line {currentLineNum} - Invalid phone number: {rawValue}");
                                    errorInRow = true;
                                }
                                else if (originalValue != value)
                                {
                                    result.Add($"~W Line {currentLineNum} - Phone number adjusted from {rawValue} to {value} ");
                                }

                                if (value.HasContent())
                                {
                                    if (knownPhones.Contains(value))
                                    {
                                        result.Add($"~E Line {currentLineNum} - Duplicate phone number: {value}");
                                        errorInRow = true;
                                    }

                                    knownPhones.Add(value);
                                }

                                // update with the cleaned phone number
                                person.SetPropertyValue(dbFieldName, value.HasContent() ? value : null);
                            }

                            break;

                        case "IneligibleReasonGuid":
                            break;

                        default:
                            throw new ApplicationException("Unexpected: " + dbFieldName);
                        }
                    }
                }

                var addRow = true;

                if (!valuesSet)
                {
                    // don't count it as an error
                    result.Add($"~I Line {currentLineNum} - Ignoring blank line");
                    addRow = false;
                }
                else if (namesFoundInRow != 2 || errorInRow)
                {
                    addRow = false;
                    rowsWithErrors++;

                    if (namesFoundInRow != 2)
                    {
                        result.Add($"~E Line {currentLineNum} - First or last name missing");
                    }
                }

                if (doDupQuery)
                {
                    var duplicates = duplicateInFileSearch.Select(p => p.TempImportLineNum).Distinct().ToList();
                    if (duplicates.Any())
                    {
                        addRow = false;

                        if (duplicates.All(n => n == -1))
                        {
                            result.Add($"~I Line {currentLineNum} - {person.FirstName} {person.LastName} - skipped - Matching person found in existing records");
                        }
                        else
                        {
                            peopleSkipped++;
                            foreach (var n in duplicates.Where(n => n > 0))
                            {
                                result.Add($"~E Line {currentLineNum} - {person.FirstName} {person.LastName} - Duplicate person found on line {n}");
                            }
                        }
                    }
                }



                if (addRow)
                { //get ready for DB
                    person.ElectionGuid = UserSession.CurrentElectionGuid;
                    person.PersonGuid   = Guid.NewGuid();

                    personModel.SetCombinedInfoAtStart(person);
                    personModel.ApplyVoteReasonFlags(person);

                    peopleToLoad.Add(person);

                    // result.Add($"~I Line {currentLineNum} - {person.FirstName} {person.LastName}");  -- not good for large lists!

                    peopleAdded++;
                }

                currentPeople.Add(person);

                if (currentLineNum % 100 == 0)
                {
                    hub.ImportInfo(currentLineNum, peopleAdded);
                }

                if (result.Count(s => s.StartsWith("~E")) == 10)
                {
                    result.Add("~E Import aborted after 10 errors");
                    break;
                }
            }

            var abort = rowsWithErrors > 0 || peopleSkipped > 0;

            if (!abort && peopleToLoad.Count != 0)
            {
                hub.StatusUpdate("Saving");

                var error = BulkInsert_CheckErrors(peopleToLoad);
                if (error != null)
                {
                    abort = true;
                    result.Add(error);
                }
                else
                {
                    result.Add("Saved to database");
                }
            }

            file.ProcessingStatus = abort ? "Import aborted" : "Imported";

            Db.SaveChanges();

            new PersonCacher().DropThisCache();

            result.AddRange(new[]
            {
                "---------",
                $"Processed {currentLineNum:N0} data line{currentLineNum.Plural()}",
            });
            // if (peopleSkipped > 0)
            // {
            //   result.Add($"{peopleSkipped:N0} duplicate{peopleSkipped.Plural()} ignored.");
            // }
            if (rowsWithErrors > 0)
            {
                result.Add($"{rowsWithErrors:N0} line{rowsWithErrors.Plural("s had errors or were", " had errors or was")} blank.");
            }
            // if (validReasons > 0)
            // {
            //   result.Add($"{validReasons:N0} {validReasons.Plural("people", "person")} with recognized Eligibility Status Reason{validReasons.Plural()}.");
            // }
            if (unexpectedReasons.Count > 0)
            {
                result.Add($"{unexpectedReasons.Count:N0} Eligibility Status Reason{unexpectedReasons.Count.Plural()} not recognized: ");
                foreach (var r in unexpectedReasons)
                {
                    result.Add("&nbsp; &nbsp; \"{0}\"{1}".FilledWith(r.Key, r.Value == 1 ? "" : " x" + r.Value));
                }
            }

            result.Add("---------");

            if (abort)
            {
                result.Add($"Import aborted due to errors in file. Please correct and try again.");
            }
            else
            {
                result.Add($"Added {peopleAdded:N0} {peopleAdded.Plural("people", "person")}.");
                result.Add($"Import completed in {(DateTime.Now - start).TotalSeconds:N1} s.");
            }

            var resultsForLog = result.Where(s => !s.StartsWith("~"));

            new LogHelper().Add("Imported file #" + rowId + ":\r" + resultsForLog.JoinedAsString("\r"), true);

            return(new
            {
                result,
                count = NumberOfPeople
            }.AsJsonResult());
        }
Exemple #18
0
        public JsonResult SavePerson(Person personFromInput)
        {
            if (UserSession.CurrentElectionStatus == ElectionTallyStatusEnum.Finalized)
            {
                return(new { Message = UserSession.FinalizedNoChangesMessage }.AsJsonResult());
            }

            var Db = SharedDbContext;

            var personInDatastore = PeopleInElection.SingleOrDefault(p => p.Id == personFromInput.Id);
            var changed           = false;

            if (personInDatastore == null)
            {
                if (personFromInput.Id != -1)
                {
                    return(new
                    {
                        Message = "Unknown ID"
                    }.AsJsonResult());
                }

                // create new
                personInDatastore = new Person
                {
                    PersonGuid   = Guid.NewGuid(),
                    ElectionGuid = CurrentElectionGuid
                };

                var reason = new ElectionModel().GetDefaultIneligibleReason();
                SetInvolvementFlagsToDefault(personInDatastore, reason);
                Db.Person.Add(personInDatastore);

                PeopleInElection.Add(personInDatastore);

                changed = true;
            }
            else
            {
                Db.Person.Attach(personInDatastore);
            }

            if (personFromInput.IneligibleReasonGuid == Guid.Empty)
            {
                personFromInput.IneligibleReasonGuid = null;
            }

            var editableFields = new
            {
                // personFromInput.AgeGroup,
                personFromInput.BahaiId,
                personFromInput.FirstName,
                personFromInput.IneligibleReasonGuid,
                personFromInput.LastName,
                personFromInput.OtherInfo,
                personFromInput.OtherLastNames,
                personFromInput.OtherNames,
                personFromInput.Area,
            }.GetAllPropertyInfos().Select(pi => pi.Name).ToArray();


            changed = personFromInput.CopyPropertyValuesTo(personInDatastore, editableFields) || changed;

            // these two may not be present, depending on the election type
            const string all             = ElectionModel.CanVoteOrReceive.All;
            var          canReceiveVotes = personFromInput.CanReceiveVotes.GetValueOrDefault(CurrentElection.CanReceive == all);

            if (personInDatastore.CanReceiveVotes != canReceiveVotes)
            {
                personInDatastore.CanReceiveVotes = canReceiveVotes;
                changed = true;
            }

            var canVote = personFromInput.CanVote.GetValueOrDefault(CurrentElection.CanVote == all);

            if (personInDatastore.CanVote != canVote)
            {
                personInDatastore.CanVote = canVote;
                changed = true;
            }

            if (changed)
            {
                SetCombinedInfos(personInDatastore);

                Db.SaveChanges();

                new PersonCacher(Db).ReplaceEntireCache(PeopleInElection);

                UpdateFrontDeskListing(personInDatastore);
            }

            var persons = new PersonCacher(Db).AllForThisElection;

            return(new
            {
                Status = "Saved",
                Person = PersonForEdit(personInDatastore),
                OnFile = persons.Count(),
                Eligible = persons.Count(p => p.IneligibleReasonGuid == null),
            }.AsJsonResult());
        }
Exemple #19
0
        public object GetCurrentResults()
        {
            //var ready = _analyzer.IsResultAvailable;
            var dbContext = GetNewDbContext();

            try
            {
                var resultSummaryFinal = _analyzer.ResultSummaryFinal; // resultSummaries.SingleOrDefault(rs => rs.ResultType == ResultType.Final);


                // don't show any details if review is needed
                if (resultSummaryFinal.BallotsNeedingReview != 0)
                {
                    var locations         = new LocationCacher(dbContext).AllForThisElection;
                    var multipleLocations = locations.Count() > 1;

                    //TODO
                    var needReview = _analyzer.VoteInfos // .Where(VoteAnalyzer.VoteNeedReview)
                                     .Join(locations, vi => vi.LocationId, l => l.Id,
                                           (vi, location) => new { vi, location })
                                     .Select(x => new
                    {
                        x.vi.LocationId,
                        x.vi.BallotId,
                        Status =
                            x.vi.BallotStatusCode == "Review"
                            ? BallotStatusEnum.Review.DisplayText
                            : "Verification Needed",
                        Ballot = multipleLocations ?
                                 string.Format("{0} ({1})", x.vi.C_BallotCode, x.location.Name) : x.vi.C_BallotCode
                    })
                                     .Distinct()
                                     .OrderBy(x => x.Ballot);

                    var needReview2 = _analyzer.Ballots.Where(b => b.StatusCode == BallotStatusEnum.Review)
                                      .Join(locations, b => b.LocationGuid, l => l.LocationGuid,
                                            (b, location) => new { b, location })
                                      .Select(x => new
                    {
                        LocationId = x.location.Id,
                        BallotId   = x.b.Id,
                        Status     =
                            x.b.StatusCode == "Review"
                            ? BallotStatusEnum.Review.DisplayText
                            : "Verification Needed",
                        Ballot = multipleLocations ?
                                 string.Format("{0} ({1})", x.b.C_BallotCode, x.location.Name) : x.b.C_BallotCode
                    });

                    return(new
                    {
                        NeedReview = needReview.Concat(needReview2).Distinct(),
                        ResultsFinal = _analyzer.ResultSummaryFinal
                                       .GetPropertiesExcept(null, new[] { "ElectionGuid" }),
                        ResultsCalc =
                            _analyzer.ResultSummaries.First(rs => rs.ResultType == ResultType.Calculated)
                            .GetPropertiesExcept(null, new[] { "ElectionGuid" }),
                        ResultsManual = (_analyzer.ResultSummaries.FirstOrDefault(rs => rs.ResultType == ResultType.Manual) ??
                                         new ResultSummary()).GetPropertiesExcept(null, new[] { "ElectionGuid" }),

                        //ResultsFinal =
                        //  resultSummaries.First(rs => rs.ResultType == ResultType.Final)
                        //    .GetPropertiesExcept(null, new[] { "ElectionGuid" }),
                    });
                }

                // show vote totals

                var persons = new PersonCacher(dbContext).AllForThisElection;

                var vResultInfos =
                    // TODO 2012-01-21 Glen Little: Could return fewer columns for non-tied results
                    _analyzer.Results // new ResultCacher(Db).AllForThisElection
                    .OrderBy(r => r.Rank)
                    .ToList()
                    .Select(r => new
                {
                    rid = r.Id,
                    r.CloseToNext,
                    r.CloseToPrev,
                    r.ForceShowInOther,
                    r.IsTied,
                    r.IsTieResolved,
                    PersonName = PersonNameFor(persons, r),
                    r.Rank,
                    //ri.RankInExtra,
                    r.Section,
                    r.TieBreakCount,
                    r.TieBreakGroup,
                    r.TieBreakRequired,
                    r.VoteCount
                }).ToList();

                var ties = _analyzer.ResultTies //  new ResultTieCacher(Db).AllForThisElection
                           .OrderBy(rt => rt.TieBreakGroup)
                           .Select(rt => new
                {
                    rt.TieBreakGroup,
                    rt.NumInTie,
                    rt.NumToElect,
                    rt.TieBreakRequired,
                    rt.IsResolved
                }).ToList();

                //var spoiledVotesSummary = Db.vVoteInfoes.where



                return(new
                {
                    Votes = vResultInfos,
                    UserSession.CurrentElectionStatus,
                    Ties = ties,
                    NumToElect = _election.NumberToElect,
                    NumExtra = _election.NumberExtra,
                    ShowCalledIn = _election.UseCallInButton,
                    ResultsManual =
                        (_analyzer.ResultSummaries.FirstOrDefault(rs => rs.ResultType == ResultType.Manual) ?? new ResultSummary())
                        .GetPropertiesExcept(null, new[] { "ElectionGuid" }),
                    ResultsCalc =
                        _analyzer.ResultSummaries.First(rs => rs.ResultType == ResultType.Calculated)
                        .GetPropertiesExcept(null, new[] { "ElectionGuid" }),
                    ResultsFinal =
                        _analyzer.ResultSummaries.First(rs => rs.ResultType == ResultType.Final)
                        .GetPropertiesExcept(null, new[] { "ElectionGuid" }),
                });
            }
            catch (Exception ex)
            {
                return(new
                {
                    Interrupted = true,
                    Msg = ex.GetAllMsgs("; ") + "\n" + ex.StackTrace
                });
            }
        }
Exemple #20
0
        public JsonResult SavePerson(Person personFromInput)
        {
            if (UserSession.CurrentElectionStatus == ElectionTallyStatusEnum.Finalized)
            {
                return(new { Message = UserSession.FinalizedNoChangesMessage }.AsJsonResult());
            }

            var personInDatastore = PeopleInElection.SingleOrDefault(p => p.C_RowId == personFromInput.C_RowId);
            var changed           = false;

            if (personInDatastore == null)
            {
                if (personFromInput.C_RowId != -1)
                {
                    return(new
                    {
                        Message = "Unknown ID"
                    }.AsJsonResult());
                }

                // create new
                personInDatastore = new Person
                {
                    PersonGuid   = Guid.NewGuid(),
                    ElectionGuid = CurrentElectionGuid
                };

                Db.Person.Add(personInDatastore);

                PeopleInElection.Add(personInDatastore);

                changed = true;
            }
            else
            {
                Db.Person.Attach(personInDatastore);
            }

            var beforeChanges = personInDatastore.GetAllProperties();

            if (personFromInput.IneligibleReasonGuid == Guid.Empty)
            {
                personFromInput.IneligibleReasonGuid = null;
            }

            if (personFromInput.Phone != null)
            {
                //check via Twilio to ensure real number?
                if (!new Regex(@"\+[0-9]{4,15}").IsMatch(personFromInput.Phone))
                {
                    return(new
                    {
                        Message = "Invalid phone number. Must start with + and only contain digits."
                    }.AsJsonResult());
                }
            }

            var editableFields = new
            {
                // personFromInput.AgeGroup,
                personFromInput.BahaiId,
                personFromInput.FirstName,
                personFromInput.IneligibleReasonGuid,
                personFromInput.LastName,
                personFromInput.OtherInfo,
                personFromInput.OtherLastNames,
                personFromInput.OtherNames,
                personFromInput.Area,
                personFromInput.Email,
                personFromInput.Phone,
            }.GetAllPropertyInfos().Select(pi => pi.Name).ToArray();


            changed = personFromInput.CopyPropertyValuesTo(personInDatastore, editableFields) || changed;

            // var defaultReason = new ElectionModel().GetDefaultIneligibleReason();
            if (ApplyVoteReasonFlags(personInDatastore))
            {
                changed = true;
            }

            // const string all = ElectionModel.CanVoteOrReceive.All;
            // var canReceiveVotes = personFromInput.CanReceiveVotes.AsBoolean(CurrentElection.CanReceive == all);
            // if (personInDatastore.CanReceiveVotes != canReceiveVotes)
            // {
            //   personInDatastore.CanReceiveVotes = canReceiveVotes;
            //   changed = true;
            // }
            //
            // var canVote = personFromInput.CanVote.AsBoolean(CurrentElection.CanVote == all);
            // if (personInDatastore.CanVote != canVote)
            // {
            //   personInDatastore.CanVote = canVote;
            //   changed = true;
            // }

            if (changed)
            {
                SetCombinedInfos(personInDatastore);

                try
                {
                    Db.SaveChanges();
                }
                catch (Exception e)
                {
                    // revert person object back to what it was
                    beforeChanges.CopyPropertyValuesTo(personInDatastore);

                    if (e.GetAllMsgs(";").Contains("IX_PersonEmail"))
                    {
                        return(new
                        {
                            Message = "That email is registered with another person.",
                            Person = PersonForEdit(personInDatastore),
                        }.AsJsonResult());
                    }

                    if (e.GetAllMsgs(";").Contains("IX_PersonPhone"))
                    {
                        return(new
                        {
                            Message = "That phone number is registered with another person.",
                            Person = PersonForEdit(personInDatastore),
                        }.AsJsonResult());
                    }

                    return(new
                    {
                        e.LastException().Message
                    }.AsJsonResult());
                }

                new PersonCacher(Db).ReplaceEntireCache(PeopleInElection);

                UpdateFrontDeskListing(personInDatastore);
            }

            var persons = new PersonCacher(Db).AllForThisElection;

            return(new
            {
                Status = "Saved",
                Person = PersonForEdit(personInDatastore),
                OnFile = persons.Count(),
                Eligible = persons.Count(p => p.IneligibleReasonGuid == null), //TODO? split to: can vote, can receive votes
            }.AsJsonResult());
        }
Exemple #21
0
        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());
        }