public ActionResult Index(SearchParameters parameters)
        {

            Logger.Info("New search started: " + parameters.FreeSearch);
            ViewBag.Title = String.Format("Searching by '{0}'", parameters.FreeSearch);

            var criteria = new CatalogItemSearchCriteria
            {
                SearchPhrase = parameters.FreeSearch,
                IsFuzzySearch = true,
                Catalog = UserHelper.CustomerSession.CatalogId
            };

            RestoreSearchPreferences(parameters);
            var results = SearchResults(criteria, parameters);
            return View(results);
        }
        /// <summary>
        /// Gets the model from criteria.
        /// </summary>
        /// <param name="criteria">The criteria.</param>
        /// <param name="parameters">The parameters.</param>
        /// <returns>CatalogItemSearchModel.</returns>
        private CatalogItemSearchModel GetModelFromCriteria(CatalogItemSearchCriteria criteria,
                                                            SearchParameters parameters)
        {
            criteria.Currency = UserHelper.CustomerSession.Currency;

            var dataSource = CreateDataModel(criteria, parameters, true);
            return dataSource;
        }
        /// <summary>
        /// Creates the data model.
        /// </summary>
        /// <param name="criteria">The criteria.</param>
        /// <param name="parameters">The parameters.</param>
        /// <param name="cacheResults">if set to <c>true</c> [cache results].</param>
        /// <returns>CatalogItemSearchModel.</returns>
        private CatalogItemSearchModel CreateDataModel(CatalogItemSearchCriteria criteria, SearchParameters parameters,
                                                       bool cacheResults)
        {
            var session = UserHelper.CustomerSession;

            // Create a model
            var dataSource = new CatalogItemSearchModel();

            // Now fill in filters
            var filters = _searchFilter.Filters;

            // Add all filters
            foreach (var filter in filters)
            {
                criteria.Add(filter);
            }

            // Get selected filters
            var facets = parameters.Facets;
            dataSource.SelectedFilters = new List<SelectedFilterModel>();
            if (facets.Count != 0)
            {
                foreach (var key in facets.Keys)
                {
                    var filter = filters.SingleOrDefault(x => x.Key.Equals(key, StringComparison.OrdinalIgnoreCase)
                        && (!(x is PriceRangeFilter) || ((PriceRangeFilter)x).Currency.Equals(StoreHelper.CustomerSession.Currency, StringComparison.OrdinalIgnoreCase)));

                    var appliedFilter = _searchFilter.Convert(filter, facets[key]);

                    foreach (var val in appliedFilter.GetValues())
                    {
                        criteria.Apply(appliedFilter);
                        dataSource.SelectedFilters.Add(
                            new SelectedFilterModel(_searchFilter.Convert(filter), _searchFilter.Convert(val)));
                    }
                }
            }

            // Perform search
            var sort = string.IsNullOrEmpty(parameters.Sort) ? "position" : parameters.Sort;
            var sortOrder = parameters.SortOrder;

            var isDescending = "desc".Equals(sortOrder, StringComparison.OrdinalIgnoreCase);

            SearchSort sortObject = null;

            switch (sort.ToLowerInvariant())
            {
                case "price":
                    if (session.Pricelists != null)
                    {
                        sortObject = new SearchSort(session.Pricelists.Select(priceList =>
                            new SearchSortField(
                                String.Format("price_{0}_{1}",
                                    criteria.Currency.ToLower(),
                                    priceList.ToLower()))
                            {
                                IgnoredUnmapped = true,
                                IsDescending = isDescending,
                                DataType = SearchSortField.DOUBLE
                            })
                            .ToArray());
                    }
                    break;
                case "position":
                    sortObject = new SearchSort(new SearchSortField(string.Format("sort{0}{1}",session.CatalogId,session.CategoryId).ToLower())
                    {
                        IgnoredUnmapped = true,
                        IsDescending = isDescending
                    });
                    break;
                case "name":
                    sortObject = new SearchSort("name", isDescending);
                    break;
                case "rating":
                    sortObject = new SearchSort(criteria.ReviewsAverageField, isDescending);
                    break;
                case "reviews":
                    sortObject = new SearchSort(criteria.ReviewsTotalField, isDescending);
                    break;
                default:
                    sortObject = CatalogItemSearchCriteria.DefaultSortOrder;
                    break;

            }

            criteria.Sort = sortObject;
            CatalogItemSearchResults results;
            // Search using criteria, it will only return IDs of the items
            var items = Search(criteria, cacheResults, out results).ToArray();
            var itemsIdsArray = items.Select(i => i.ItemId).ToArray();

            // Now load items with appropriate 
            var itemModelList = new List<CatalogItemWithPriceModel>();
            if (items.Any())
            {
                // Now convert it to the model
                var prices = _priceListClient.GetLowestPrices(session.Pricelists, itemsIdsArray, 1);
                var availabilities = _catalogClient.GetItemAvailability(itemsIdsArray,
                                                   UserHelper.StoreClient.GetCurrentStore().FulfillmentCenterId);

                foreach (var item in items)
                {
                    PriceModel priceModel = null;
                    ItemAvailabilityModel availabilityModel = null;
                    var searchTags = results.Items[item.ItemId.ToLower()];

                    var currentOutline = this.GetItemOutlineUsingContext(searchTags[criteria.OutlineField].ToString());

                    //Cache outline
                    HttpContext.Items["browsingoutline_" + item.ItemId.ToLower()] = StripCatalogFromOutline(currentOutline);

                    if (prices != null && prices.Any())
                    {
                        var lowestPrice = (prices.Where(p => p.ItemId.Equals(item.ItemId, StringComparison.OrdinalIgnoreCase))).SingleOrDefault();
                        if (lowestPrice != null)
                        {
                            var tags = new Hashtable
							{
								{
									"Outline",
									currentOutline
								}
							};
                            priceModel = _marketing.GetItemPriceModel(item, lowestPrice, tags);
                        }
                    }

                    if (availabilities != null && availabilities.Any())
                    {
                        var availability =
                            (from a in availabilities
                             where a.ItemId.Equals(item.ItemId, StringComparison.OrdinalIgnoreCase)
                             select a).SingleOrDefault();

                        availabilityModel = new ItemAvailabilityModel(availability);
                    }

                    var itemModel = new CatalogItemWithPriceModel(CatalogHelper.CreateItemModel(item), priceModel, availabilityModel)
                    {
                        SearchOutline = currentOutline
                    };

                    try
                    {
                        itemModel.ItemReviewTotals.AverageRating = double.Parse(searchTags[criteria.ReviewsAverageField].ToString());
                        itemModel.ItemReviewTotals.TotalReviews = int.Parse(searchTags[criteria.ReviewsTotalField].ToString());
                    }
                    catch
                    {
                        //There are no reviews indexed?
                    }
                    itemModelList.Add(itemModel);
                }
            }

            dataSource.FilterGroups = _searchFilter.Convert(results.FacetGroups);
            dataSource.CatalogItems = itemModelList.ToArray();
            dataSource.Criteria = criteria;

            // Create pager
            var pager = new PagerModel
            {
                TotalCount = results.TotalCount,
                CurrentPage = criteria.StartingRecord / criteria.RecordsToRetrieve + 1,
                RecordsPerPage = criteria.RecordsToRetrieve,
                StartingRecord = criteria.StartingRecord,
                DisplayStartingRecord = criteria.StartingRecord + 1,
                SortValues = new[] { "Position", "Name", "Price", "Rating", "Reviews" },
                SelectedSort = sort,
                SortOrder = isDescending ? "desc" : "asc"
            };

            var end = criteria.StartingRecord + criteria.RecordsToRetrieve;
            pager.DisplayEndingRecord = end > results.TotalCount ? results.TotalCount : end;

            dataSource.Pager = pager;
            return dataSource;
        }
        /// <summary>
        /// Restores the search preferences from cookies.
        /// </summary>
        /// <param name="parameters">The parameters.</param>
        private void RestoreSearchPreferences(SearchParameters parameters)
        {
            var pageSize = parameters.PageSize;
            var sort = parameters.Sort;
            var sortOrder = parameters.SortOrder;

            if (pageSize == 0)
            {
                Int32.TryParse(StoreHelper.GetCookieValue("pagesizecookie"), out pageSize);
            }
            else
            {
                StoreHelper.SetCookie(
                    "pagesizecookie", pageSize.ToString(CultureInfo.InvariantCulture), DateTime.Now.AddMonths(1));
            }

            if (pageSize == 0)
            {
                pageSize = SearchParameters.DefaultPageSize;
            }

            parameters.PageSize = pageSize;

            if (String.IsNullOrEmpty(sort))
            {
                sort = StoreHelper.GetCookieValue("sortcookie");
            }
            else
            {
                StoreHelper.SetCookie("sortcookie", sort, DateTime.Now.AddMonths(1));
            }

            if (String.IsNullOrEmpty(sortOrder))
            {
                sortOrder = StoreHelper.GetCookieValue("sortordercookie");
            }
            else
            {
                StoreHelper.SetCookie("sortordercookie", sortOrder, DateTime.Now.AddMonths(1));
            }

            parameters.Sort = sort;
            parameters.SortOrder = sortOrder;
        }
        /// <summary>
        /// Searches by given parameters.
        /// </summary>
        /// <param name="criteria">The criteria.</param>
        /// <param name="parameters">The parameters.</param>
        /// <returns>CatalogItemSearchModel.</returns>
        private CatalogItemSearchModel SearchResults(CatalogItemSearchCriteria criteria, SearchParameters parameters)
        {
            var pageNumber = parameters.PageIndex;
            var pageSize = parameters.PageSize;
            criteria.Locale = UserHelper.CustomerSession.Language;
            criteria.Catalog = UserHelper.CustomerSession.CatalogId;
            criteria.RecordsToRetrieve = pageSize;
            criteria.StartingRecord = (pageNumber - 1) * pageSize;
            criteria.Pricelists = UserHelper.CustomerSession.Pricelists;

            return GetModelFromCriteria(criteria, parameters);
        }
        public ActionResult Find(string term)
        {
            Logger.Info("New search started: " + term);
            ViewBag.Title = String.Format("Searching by '{0}'".Localize(), term);

            var parameters = new SearchParameters { PageSize = 15 };
            var criteria = new CatalogItemSearchCriteria { SearchPhrase = term.EscapeSearchTerm(), IsFuzzySearch = true };
            var results = SearchResults(criteria, parameters);

            var data = from i in results.CatalogItems
                       select new { url = Url.ItemUrl(i.CatalogItem.Item, i.CatalogItem.ParentItemId), value = i.DisplayName };
            return Json(data.ToArray(), JsonRequestBehavior.AllowGet);
        }
        public ActionResult SearchResultsWithinCategory(CategoryModel cat, SearchParameters parameters, string name = "Index", CatalogItemSearchCriteria criteria = null, bool savePreferences = true)
        {
            criteria = criteria ?? new CatalogItemSearchCriteria();
            if (cat != null)
            {
                ViewBag.Title = cat.DisplayName;
                criteria.Outlines.Add(String.Format("{0}*", _catalogClient.BuildCategoryOutline(UserHelper.CustomerSession.CatalogId, cat.Category)));
            }

            if (savePreferences)
            {
                RestoreSearchPreferences(parameters);
            }

            var results = SearchResults(criteria, parameters);
            return PartialView(name, results);
        }
Exemplo n.º 8
0
        /// <summary>
        /// Creates the data model.
        /// </summary>
        /// <param name="criteria">The criteria.</param>
        /// <param name="parameters">The parameters.</param>
        /// <param name="cacheResults">if set to <c>true</c> [cache results].</param>
        /// <returns>CatalogItemSearchModel.</returns>
        private CatalogItemSearchModel CreateDataModel(CatalogItemSearchCriteria criteria, SearchParameters parameters,
                                                       bool cacheResults)
        {
            var session = UserHelper.CustomerSession;

            // Create a model
            var dataSource = new CatalogItemSearchModel();

            // Now fill in filters
            var searchHelper = new SearchHelper(_storeClient.GetCurrentStore());

            var filters = searchHelper.Filters;

            // Add all filters
            foreach (var filter in filters)
            {
                // Check if we already filtering
                if (parameters.Facets.Keys.Any(k => filter.Key.Equals(k, StringComparison.OrdinalIgnoreCase)))
                    continue;

                criteria.Add(filter);
            }

            // Get selected filters
            var facets = parameters.Facets;
            dataSource.SelectedFilters = new List<SelectedFilterModel>();
            if (facets.Count != 0)
            {
                foreach (var key in facets.Keys)
                {
                    var filter = filters.SingleOrDefault(x => x.Key.Equals(key, StringComparison.OrdinalIgnoreCase)
                        && (!(x is PriceRangeFilter) || ((PriceRangeFilter)x).Currency.Equals(StoreHelper.CustomerSession.Currency, StringComparison.OrdinalIgnoreCase)));
                    var val =
                        (from v in searchHelper.GetFilterValues(filter) where v.Id == facets[key] select v)
                            .SingleOrDefault();
                    if (val != null)
                    {
                        criteria.Add(filter, val);
                        dataSource.SelectedFilters.Add(new SelectedFilterModel(searchHelper.Convert(filter),
                                                                               searchHelper.Convert(val)));
                    }
                }
            }

            // Perform search
            var sort = string.IsNullOrEmpty(parameters.Sort) ? "position" : parameters.Sort;
            var sortOrder = parameters.SortOrder;

            bool isDescending = "desc".Equals(sortOrder, StringComparison.OrdinalIgnoreCase);

            SearchSort sortObject = null;

            if (!sort.Equals("position", StringComparison.OrdinalIgnoreCase))
            {
                if (sort.Equals("price", StringComparison.OrdinalIgnoreCase))
                {
                    if (session.Pricelists != null)
                    {
                        sortObject = new SearchSort(session.Pricelists.Select(priceList =>
                            new SearchSortField(
                                String.Format("price_{0}_{1}",
                                    criteria.Currency.ToLower(),
                                    priceList.ToLower()))
                            {
                                IgnoredUnmapped = true,
                                IsDescending = isDescending,
                                DataType = SearchSortField.DOUBLE
                            })
                            .ToArray());
                    }
                }
                else
                {
                    sortObject = new SearchSort(sort.ToLower(), isDescending);
                }
            }

            // Put default sort order if none is set
            if (sortObject == null)
            {
                sortObject = CatalogItemSearchCriteria.DefaultSortOrder;
            }

            criteria.Sort = sortObject;
            CatalogItemSearchResults results;
            // Search using criteria, it will only return IDs of the items
            var items = Search(criteria, cacheResults, out results).ToArray();
            var itemsIdsArray = items.Select(i => i.ItemId).ToArray();

            // Now load items with appropriate 
            var itemModelList = new List<CatalogItemWithPriceModel>();
            if (items.Any())
            {

                // Now convert it to the model

                var prices = _priceListClient.GetLowestPrices(session.Pricelists, itemsIdsArray, 1);
                var availabilities = _catalogClient.GetItemAvailability(itemsIdsArray,
                                                   UserHelper.StoreClient.GetCurrentStore().FulfillmentCenterId);

                foreach (var item in items)
                {
                    PriceModel priceModel = null;
                    ItemAvailabilityModel availabilityModel = null;
                    var catalogIdPath = UserHelper.CustomerSession.CatalogId + "/";
                    var searchTags = results.Items[item.ItemId.ToLower()].ToPropertyDictionary();

                    //Cache outline
                    HttpContext.Items["browsingoutline_" + item.Code.ToLower()] = searchTags[criteria.BrowsingOutlineField].ToString();
                    var currentOutline = searchTags[criteria.OutlineField].ToString().Split(new[] { ';' }, StringSplitOptions.RemoveEmptyEntries)
                        .FirstOrDefault(x => x.StartsWith(catalogIdPath, StringComparison.OrdinalIgnoreCase)) ?? string.Empty;

                    if (prices != null && prices.Any())
                    {
                        var lowestPrice =
                            (from p in prices
                             where p.ItemId.Equals(item.ItemId, StringComparison.OrdinalIgnoreCase)
                             select p).SingleOrDefault();
                        if (lowestPrice != null)
                        {
                            var tags = new Hashtable
							{
								{
									"Outline",
									currentOutline
								}
							};
                            priceModel = _marketing.GetItemPriceModel(item, lowestPrice, tags);
                        }
                    }

                    if (availabilities != null && availabilities.Any())
                    {
                        var availability =
                            (from a in availabilities
                             where a.ItemId.Equals(item.ItemId, StringComparison.OrdinalIgnoreCase)
                             select a).SingleOrDefault();

                        availabilityModel = new ItemAvailabilityModel(availability);
                    }

                    var itemModel = new CatalogItemWithPriceModel(CatalogHelper.CreateItemModel(item), priceModel, availabilityModel)
                    {
                        SearchOutline = currentOutline
                    };
                    itemModelList.Add(itemModel);
                }
            }

            dataSource.FilterGroups = searchHelper.Convert(results.FacetGroups);
            dataSource.CatalogItems = itemModelList.ToArray();
            dataSource.Criteria = criteria;

            // Create pager
            var pager = new PagerModel
            {
                TotalCount = results.TotalCount,
                CurrentPage = criteria.StartingRecord / criteria.RecordsToRetrieve + 1,
                RecordsPerPage = criteria.RecordsToRetrieve,
                StartingRecord = criteria.StartingRecord,
                DisplayStartingRecord = criteria.StartingRecord + 1,
                SortValues = new[] { "Position", "Name", "Price" },
                SelectedSort = sort,
                SortOrder = isDescending ? "desc" : "asc"
            };

            var end = criteria.StartingRecord + criteria.RecordsToRetrieve;
            pager.DisplayEndingRecord = end > results.TotalCount ? results.TotalCount : end;

            dataSource.Pager = pager;

            // Query similar words
            /*
            if (count == 0)
                dataSource.Suggestions = GetSuggestions();
             * */
            //}

            return dataSource;
        }