/// <summary>
        /// Async search products by given criteria
        /// </summary>
        /// <param name="criteria"></param>
        /// <returns></returns>
        public virtual async Task <CatalogSearchResult> SearchProductsAsync(ProductSearchCriteria criteria)
        {
            var workContext = _workContextAccessor.WorkContext;
            var cacheKey    = CacheKey.With(GetType(), "SearchProductsAsync", criteria.GetCacheKey(), workContext.CurrentStore.Id, workContext.CurrentLanguage.CultureName, workContext.CurrentCurrency.Code);

            return(await _memoryCache.GetOrCreateExclusiveAsync(cacheKey, async (cacheEntry) =>
            {
                cacheEntry.AddExpirationToken(CatalogCacheRegion.CreateChangeToken());
                cacheEntry.AddExpirationToken(_apiChangesWatcher.CreateChangeToken());

                criteria = criteria.Clone();

                var searchCriteria = criteria.ToProductSearchCriteriaDto(workContext);
                var result = await _searchApi.SearchProductsAsync(searchCriteria);
                var products = result.Items?.Select(x => x.ToProduct(workContext.CurrentLanguage, workContext.CurrentCurrency, workContext.CurrentStore)).ToList() ?? new List <Product>();

                if (products.Any())
                {
                    var productsWithVariations = products.Concat(products.SelectMany(x => x.Variations)).ToList();
                    var taskList = new List <Task>();

                    if (criteria.ResponseGroup.HasFlag(ItemResponseGroup.Inventory))
                    {
                        taskList.Add(LoadProductInventoriesAsync(productsWithVariations, workContext));
                    }

                    if (criteria.ResponseGroup.HasFlag(ItemResponseGroup.ItemAssociations))
                    {
                        taskList.Add(LoadProductsAssociationsAsync(productsWithVariations, workContext));
                    }

                    if (criteria.ResponseGroup.HasFlag(ItemResponseGroup.ItemWithVendor))
                    {
                        taskList.Add(LoadProductVendorsAsync(productsWithVariations, workContext));
                    }

                    if (criteria.ResponseGroup.HasFlag(ItemResponseGroup.ItemWithPrices))
                    {
                        taskList.Add(_pricingService.EvaluateProductPricesAsync(productsWithVariations, workContext));
                    }

                    await Task.WhenAll(taskList.ToArray());

                    foreach (var product in productsWithVariations)
                    {
                        product.IsBuyable = new ProductIsBuyableSpecification().IsSatisfiedBy(product);
                        product.IsAvailable = new ProductIsAvailableSpecification(product).IsSatisfiedBy(1);
                        product.IsInStock = new ProductIsInStockSpecification().IsSatisfiedBy(product);
                    }
                }
                return new CatalogSearchResult
                {
                    Products = new StaticPagedList <Product>(products, criteria.PageNumber, criteria.PageSize, (int?)result.TotalCount ?? 0),
                    Aggregations = !result.Aggregations.IsNullOrEmpty() ? result.Aggregations.Select(x => x.ToAggregation(workContext.CurrentLanguage.CultureName)).ToArray() : new Aggregation[] { }
                };
            }));
        }
Example #2
0
        protected virtual async Task <catalogDto.ProductSearchResult> SearchProductsAsync(ProductSearchCriteria criteria, WorkContext workContext)
        {
            var cacheKey = CacheKey.With(GetType(), "SearchProductsAsync", criteria.GetCacheKey(), workContext.CurrentStore.Id, workContext.CurrentLanguage.CultureName, workContext.CurrentCurrency.Code);

            return(await _memoryCache.GetOrCreateExclusiveAsync(cacheKey, async (cacheEntry) =>
            {
                cacheEntry.AddExpirationToken(CatalogCacheRegion.CreateChangeToken());
                cacheEntry.AddExpirationToken(_apiChangesWatcher.CreateChangeToken());

                criteria = criteria.Clone() as ProductSearchCriteria;

                var searchCriteria = criteria.ToProductSearchCriteriaDto(workContext);
                return await _searchApi.SearchProductsAsync(searchCriteria);
            }));
        }