public ActionResult Filter(SearchVenueViewModel model) { model.Venues = (List <VenueViewModel>)TempData["Venues"]; // Create new model to send to view SearchVenueViewModel viewModel = new SearchVenueViewModel(); viewModel.Venues = new List <VenueViewModel>(); if (model.Venues.Count == 0) { ViewBag.Error = "No results to filter. Please click \"Reset all filters\""; return(View("Index", viewModel)); } // User entered a search string if (!string.IsNullOrEmpty(model.Search)) { // Search venue names and cities viewModel.Venues.AddRange(model.Venues.Where(x => x.Name.CaseInsensitiveContains(model.Search)).ToList()); viewModel.Venues.AddRange(model.Venues.Where(x => x.City.CaseInsensitiveContains(model.Search))); // Get first venue on list and assign coordinates to map center var firstVenue = viewModel.Venues.FirstOrDefault(); if (firstVenue != null) { viewModel.CurrentLatitude = firstVenue.LatitudeCoord; viewModel.CurrentLongitude = firstVenue.LongitudeCoord; } } if (!string.IsNullOrEmpty(model.Filter)) { // User chose to sort by rating if (model.Filter.Equals("Rating")) { viewModel.Venues = model.Venues.OrderByDescending(x => x.AverageRating).ToList(); if (viewModel.Venues.Count == 0) { ViewBag.Error = "No search results matching given filters"; } // Get first venue on list and assign coordinates to map center var firstVenue = viewModel.Venues.FirstOrDefault(); if (firstVenue != null) { viewModel.CurrentLatitude = firstVenue.LatitudeCoord; viewModel.CurrentLongitude = firstVenue.LongitudeCoord; } } // User chose to filter by time if (model.Filter.Equals("Time")) { //get all the buiness hours for all the venues List <BusinessHours> hours = _venueService.GetAllBusinessHours(); //lets wait till time is NOT null if (model.Time != null) { //convert user input string to a TimeSpan TimeSpan hs = TimeSpan.Parse(model.Time); var dayOfWeek = Enum.Parse(typeof(DayOfWeek), model.Day); //First filter out using the days List <BusinessHours> day_available = hours.Where(x => x.DayOfWeek == (int)dayOfWeek).ToList(); //Then use that list and filter the closed times List <BusinessHours> closed_from = day_available.Where(x => x.CloseTime >= hs).ToList(); //Finally filter the list above and you have the remaning few which maches the days and the closing time List <BusinessHours> open_from = closed_from.Where(x => x.OpenTime <= hs).ToList(); //If there are some in the list that matches the user input - else it didnt match if (open_from.Count > 0) { foreach (var businessHour in open_from) { // Only keep venues that are in open_from var venue = model.Venues.FirstOrDefault(x => x.VenueId == businessHour.VenueId); if (venue != null && !viewModel.Venues.Contains(venue)) { viewModel.Venues.Add(venue); } } } } // Get first venue on list and assign coordinates to map center var firstVenue = viewModel.Venues.FirstOrDefault(); if (firstVenue != null) { viewModel.CurrentLatitude = firstVenue.LatitudeCoord; viewModel.CurrentLongitude = firstVenue.LongitudeCoord; } } // User chose to filter by distance if (model.Filter.Equals("Distance")) { foreach (var venue in model.Venues) { //get location of venue Location location = _venueService.GetVenueLocation(venue.VenueId); //converted coordinates from strings to doubles double userLat = Convert.ToDouble(model.CurrentLatitude); double userLong = Convert.ToDouble(model.CurrentLongitude); double venLat = Convert.ToDouble(location.Latitude); double venLong = Convert.ToDouble(location.Longitude); //Calculate the distance from user to venue. Method at the bottom venue.Distance = _venueService.CalculateVenueDistance(userLat, userLong, venLat, venLong); viewModel.Venues.Add(venue); } viewModel.Venues = viewModel.Venues.OrderBy(x => x.Distance).ToList(); // Get closest venue to user and assign coordinates to map center var closest = viewModel.Venues.First(); viewModel.CurrentLatitude = closest.LatitudeCoord; viewModel.CurrentLongitude = closest.LongitudeCoord; } } if (viewModel.Venues.Count == 0) { ViewBag.Error = "No search results matching given filters"; } // Preserve search/filter values viewModel.Day = model.Day; viewModel.Time = model.Time; viewModel.Search = model.Search; if (string.IsNullOrEmpty(viewModel.CurrentLatitude)) { viewModel.CurrentLatitude = model.CurrentLatitude; viewModel.CurrentLongitude = model.CurrentLongitude; } model.Venues.Clear(); return(View("Index", viewModel)); }