/// <summary>
        /// Map the constituant address. If the first constituent has a lat and long DONT run all constituents through the API.
        /// Otherwise run through API to establish initial lat and long.
        /// </summary>
        /// <returns>json object list of Latitudes and Longitudes</returns>
        public JsonResult MapAddresses()
        {
            Geolocation     geo          = new Geolocation();
            var             constituents = unitOfWork.Constituents.GetConstituents();
            List <string[]> locations    = new List <string[]> {
            };

            if (constituents.FirstOrDefault().Latitude != null && constituents.FirstOrDefault().Longitude != null)
            {
                foreach (var item in constituents)
                {
                    locations.Add(item.getLocation());
                }
            }

            else
            {
                foreach (var item in constituents)
                {
                    // Pass the address string to the API
                    geo.GetGeocode(item.getFullAddress());

                    // Assign resulting values to the constituents column
                    item.Latitude  = System.Convert.ToDecimal(geo.Latitude);
                    item.Longitude = System.Convert.ToDecimal(geo.Longitude);

                    // Pass the values to the jsonobject
                    locations.Add(item.getLocation());
                }
            }

            unitOfWork.Complete();

            return(Json(locations, JsonRequestBehavior.AllowGet));
        }
        public ActionResult ApproveConstituentChanges(int?id)
        {
            // Make sure the model is in a valid state before trying to do anything with it
            if (id != null)
            {
                // Find the entry for this Constituent in the master Constituent table
                Constituent original = unitOfWork.Constituents.Find(x => x.ConstituentID == id).FirstOrDefault();

                // Find the entry for this Constituent in the proposed changes table
                ProposedConstituentsChanges proposedChanges = unitOfWork.Changes.Find(x => x.ConstituentID == id).FirstOrDefault();

                // If we found an entry, update the values
                if (original != null)
                {
                    // Calculate their latitude and longitude if the primary address changed
                    if (original.PreferredAddressLine1 != proposedChanges.PreferredAddressLine1)
                    {
                        Geolocation geo = new Geolocation();
                        geo.GetGeocode(proposedChanges.getFullAddress());
                        original.Latitude  = Convert.ToDecimal(geo.Latitude);
                        original.Longitude = Convert.ToDecimal(geo.Longitude);
                    }

                    // Update the original values with the changes
                    unitOfWork.Entry(original).CurrentValues.SetValues(proposedChanges);

                    // Remove the entry associated with this Constituent from the proposed changes table
                    unitOfWork.Changes.Remove(proposedChanges);

                    // Save the changes to the database
                    unitOfWork.Complete();

                    // Success - return the view containing proposed changes
                    return(RedirectToAction("ReviewProposedConstituentChanges"));
                }
            }

            // If we get this far, something went wrong -- return the 'Error' view
            return(View("Error"));
        }
        public ActionResult New([Bind(Exclude = "ConstituentID")] Constituent constituent)
        {
            if (ModelState.IsValid)
            {
                // Determine what the current highest ID is, then increment by one
                Constituent[] allConstituents  = unitOfWork.Constituents.GetConstituents().OrderByDescending(x => x.ConstituentID).ToArray();
                int           newConstituentID = allConstituents[0].ConstituentID + 1;

                // Use that number as the ID for this Constituent
                constituent.ConstituentID = newConstituentID;

                // Calculate their latitude and longitude
                Geolocation geo = new Geolocation();
                geo.GetGeocode(constituent.getFullAddress());
                constituent.Latitude  = Convert.ToDecimal(geo.Latitude);
                constituent.Longitude = Convert.ToDecimal(geo.Longitude);

                unitOfWork.Constituents.Add(constituent);
                unitOfWork.Complete();
                return(RedirectToAction("Index"));
            }

            return(View(constituent));
        }
        public JsonResult Import(HttpPostedFileBase file)
        {
            // Only proceed if the file isn't null and has content
            if (file != null && file.ContentLength > 0)
            {
                // Restrict accepted file types to csv and CSV
                var supportedTypes = new[] { "csv", "CSV" };

                // Reject the file if it doesn't match the required type defined above
                var fileExt = Path.GetExtension(file.FileName).Substring(1);
                if (!supportedTypes.Contains(fileExt))
                {
                    ViewBag.Message = "Invalid file type. Please select a CSV file.";

                    // Redirects the user back to the Constituents index page
                    return(Json(new { Success = false, Message = "Error: Invalid file type. Please select a CSV file." }));
                }

                // Set up the requirements for reading in the CSV file
                CsvFileDescription csvFileDescription = new CsvFileDescription
                {
                    SeparatorChar           = ',',
                    FirstLineHasColumnNames = true
                };

                try
                {
                    // Read the file into a stream reader, and then convert each entry into our Constituent model
                    CsvContext   csvContext              = new CsvContext();
                    StreamReader streamReader            = new StreamReader(file.InputStream);
                    IEnumerable <Constituent> importList = csvContext.Read <Constituent>(streamReader, csvFileDescription);

                    // This loop iterates through each item in the importList object
                    // and either updates an existing record, or creates a new one
                    Geolocation geo = new Geolocation();
                    foreach (var constituent in importList)
                    {
                        // Check for an existing record with this ID
                        Constituent original = unitOfWork.Constituents.Find(x => x.ConstituentID == constituent.ConstituentID).FirstOrDefault();
                        if (original != null)
                        {
                            // If we found one, update the values //

                            // Calculate their latitude and longitude if the primary address changed
                            if (original.PreferredAddressLine1 != constituent.PreferredAddressLine1)
                            {
                                geo.GetGeocode(constituent.getFullAddress());
                                original.Latitude  = Convert.ToDecimal(geo.Latitude);
                                original.Longitude = Convert.ToDecimal(geo.Longitude);
                            }

                            // Calculate their donation status
                            original.DonationStatus = CheckStatus(constituent);

                            // Add them to the database with the updated values
                            unitOfWork.Entry(original).CurrentValues.SetValues(constituent);
                        }
                        else
                        {
                            // Otherwise, create a new entry //

                            // Grab the ID
                            constituent.ConstituentID = constituent.ConstituentID;

                            // Calculate their latitude and longitude
                            geo.GetGeocode(constituent.getFullAddress());
                            constituent.Latitude  = Convert.ToDecimal(geo.Latitude);
                            constituent.Longitude = Convert.ToDecimal(geo.Longitude);

                            // Calculate their donation status
                            constituent.DonationStatus = CheckStatus(constituent);

                            // Add them to the database
                            unitOfWork.Constituents.Add(constituent);
                        }
                    }
                    unitOfWork.Complete();
                }
                catch (DbEntityValidationException e)
                {
                    foreach (var eve in e.EntityValidationErrors)
                    {
                        Console.WriteLine("Entity of type \"{0}\" in state \"{1}\" has the following validation errors:",
                                          eve.Entry.Entity.GetType().Name, eve.Entry.State);
                        foreach (var ve in eve.ValidationErrors)
                        {
                            Console.WriteLine("- Property: \"{0}\", Error: \"{1}\"",
                                              ve.PropertyName, ve.ErrorMessage);
                        }
                    }
                    throw;
                }

                // Saves the changes to the database and additions to the Constituents table and set the success message
                //unitOfWork.Complete();
                return(Json(new { Success = true, Message = "CSV File Was Successfully Imported!" }));
            }

            // If we got this far, something went wrong -- set the error message
            return(Json(new { Success = false, Message = "Error: Import failed!" }));
        }