protected virtual async Task LoadProductDependencies(List <Product> products, ItemResponseGroup responseGroup, WorkContext workContext) { if (products.IsNullOrEmpty()) { return; } var taskList = new List <Task>(); taskList .AddIf(responseGroup.HasFlag(ItemResponseGroup.Inventory), () => LoadProductInventoriesAsync(products, workContext)) .AddIf(responseGroup.HasFlag(ItemResponseGroup.ItemAssociations), () => LoadProductsAssociationsAsync(products, workContext)) .AddIf(responseGroup.HasFlag(ItemResponseGroup.ItemWithPrices), () => _pricingService.EvaluateProductPricesAsync(products, workContext)) .AddIf(responseGroup.HasFlag(ItemResponseGroup.ItemWithVendor), () => LoadProductVendorsAsync(products, workContext)) .AddIf(workContext.CurrentStore.SubscriptionEnabled && responseGroup.HasFlag(ItemResponseGroup.ItemWithPaymentPlan), () => LoadProductPaymentPlanAsync(products, workContext)) .AddIf(workContext.CurrentStore.CustomerReviewsEnabled, () => LoadProductCustomerReviewsAsync(products)); await Task.WhenAll(taskList); foreach (var product in products) { product.IsBuyable = new ProductIsBuyableSpecification().IsSatisfiedBy(product); product.IsAvailable = new ProductIsAvailableSpecification(product).IsSatisfiedBy(1); product.IsInStock = new ProductIsInStockSpecification().IsSatisfiedBy(product); } }
protected virtual void LoadVariationsByParentIds(string[] parentIds, ItemResponseGroup respGroup) { // TODO: Call GetItemByIds for variations recursively (need to measure performance and data amount first) var variationIds = Items.Where(x => parentIds.Contains(x.ParentId)).Select(x => x.Id).ToArray(); if (!variationIds.IsNullOrEmpty()) { // Always load info, images and property values for variations var variations = Items.Include(x => x.Images).Where(x => variationIds.Contains(x.Id)).ToArray(); if (variations.Any()) { variationIds = variations.Select(x => x.Id).ToArray(); var variationPropertyValues = PropertyValues.Include(x => x.DictionaryItem.DictionaryItemValues).Where(x => variationIds.Contains(x.ItemId)).ToArray(); if (respGroup.HasFlag(ItemResponseGroup.ItemAssets)) { var variationAssets = Assets.Where(x => variationIds.Contains(x.ItemId)).ToArray(); } if (respGroup.HasFlag(ItemResponseGroup.ItemEditorialReviews)) { var variationEditorialReviews = EditorialReviews.Where(x => variationIds.Contains(x.ItemId)).ToArray(); } if (respGroup.HasFlag(ItemResponseGroup.Links)) { var variationLinks = CategoryItemRelations.Where(x => variationIds.Contains(x.ItemId)).ToArray(); } } } }
public virtual async Task <Product[]> GetProductsAsync(string[] ids, ItemResponseGroup responseGroup = ItemResponseGroup.None) { Product[] result; if (ids.IsNullOrEmpty()) { result = new Product[0]; } else { var workContext = _workContextFactory(); if (responseGroup == ItemResponseGroup.None) { responseGroup = workContext.CurrentProductResponseGroup; } result = await GetProductsAsync(ids, responseGroup, workContext); var allProducts = result.Concat(result.SelectMany(p => p.Variations)).ToList(); if (!allProducts.IsNullOrEmpty()) { var taskList = new List <Task>(); if (responseGroup.HasFlag(ItemResponseGroup.ItemAssociations)) { taskList.Add(LoadProductAssociationsAsync(allProducts)); } if (responseGroup.HasFlag(ItemResponseGroup.Inventory)) { taskList.Add(LoadProductInventoriesAsync(allProducts)); } if (responseGroup.HasFlag(ItemResponseGroup.ItemWithPrices)) { taskList.Add(_pricingService.EvaluateProductPricesAsync(allProducts, workContext)); } if (responseGroup.HasFlag(ItemResponseGroup.ItemWithVendor)) { taskList.Add(LoadProductVendorsAsync(allProducts, workContext)); } if (workContext.CurrentStore.SubscriptionEnabled && responseGroup.HasFlag(ItemResponseGroup.ItemWithPaymentPlan)) { taskList.Add(LoadProductPaymentPlanAsync(allProducts, workContext)); } await Task.WhenAll(taskList.ToArray()); } } return(result); }
/// <summary> /// Reduce product details according to response group /// </summary> /// <param name="product"></param> /// <param name="respGroup"></param> protected virtual void ReduceDetails(CatalogProduct product, ItemResponseGroup respGroup) { if (product == null) { throw new ArgumentNullException(nameof(product)); } if (!respGroup.HasFlag(ItemResponseGroup.ItemAssets)) { product.Assets = null; } if (!respGroup.HasFlag(ItemResponseGroup.ItemAssociations)) { product.Associations = null; } if (!respGroup.HasFlag(ItemResponseGroup.ReferencedAssociations)) { product.ReferencedAssociations = null; } if (!respGroup.HasFlag(ItemResponseGroup.ItemEditorialReviews)) { product.Reviews = null; } if (!respGroup.HasFlag(ItemResponseGroup.Inventory)) { product.Inventories = null; } if (!respGroup.HasFlag(ItemResponseGroup.ItemProperties)) { product.Properties = null; product.PropertyValues = null; } if (!respGroup.HasFlag(ItemResponseGroup.Links)) { product.Links = null; } if (!respGroup.HasFlag(ItemResponseGroup.Outlines)) { product.Outlines = null; } if (!respGroup.HasFlag(ItemResponseGroup.Seo)) { product.SeoInfos = null; } if (!respGroup.HasFlag(ItemResponseGroup.Variations)) { product.Variations = null; } }
public async Task <Product[]> GetProductsAsync(string[] ids, ItemResponseGroup responseGroup = ItemResponseGroup.None) { var workContext = _workContextFactory(); if (responseGroup == ItemResponseGroup.None) { responseGroup = workContext.CurrentProductResponseGroup; } var retVal = (await _catalogModuleApi.CatalogModuleProductsGetProductByIdsAsync(ids.ToList(), ((int)responseGroup).ToString())).Select(x => x.ToWebModel(workContext.CurrentLanguage, workContext.CurrentCurrency, workContext.CurrentStore)).ToArray(); var allProducts = retVal.Concat(retVal.SelectMany(x => x.Variations)).ToList(); if (!allProducts.IsNullOrEmpty()) { var taskList = new List <Task>(); if (responseGroup.HasFlag(ItemResponseGroup.ItemAssociations)) { taskList.Add(LoadProductAssociationsAsync(allProducts)); } if (responseGroup.HasFlag(ItemResponseGroup.Inventory)) { taskList.Add(LoadProductInventoriesAsync(allProducts)); } if (responseGroup.HasFlag(ItemResponseGroup.ItemWithPrices)) { await _pricingService.EvaluateProductPricesAsync(allProducts); if ((responseGroup | ItemResponseGroup.ItemWithDiscounts) == responseGroup) { await LoadProductDiscountsAsync(allProducts); } } if (responseGroup.HasFlag(ItemResponseGroup.ItemWithVendor)) { await LoadProductVendorsAsync(allProducts); } await Task.WhenAll(taskList.ToArray()); } return(retVal); }
public virtual CatalogProduct[] GetByIds(string[] itemIds, ItemResponseGroup respGroup, string catalogId = null) { var result = Array.Empty <CatalogProduct>(); if (!itemIds.IsNullOrEmpty()) { using (var repository = _repositoryFactory()) { //Optimize performance and CPU usage repository.DisableChangesTracking(); result = repository.GetItemByIds(itemIds, respGroup) .Select(x => x.ToModel(AbstractTypeFactory <CatalogProduct> .TryCreateInstance())) .ToArray(); } if (result.Any()) { LoadDependencies(result); ApplyInheritanceRules(result); var productsWithVariationsList = result.Concat(result.Where(p => p.Variations != null) .SelectMany(p => p.Variations)); // Fill outlines for products and variations if (respGroup.HasFlag(ItemResponseGroup.Outlines)) { _outlineService.FillOutlinesForObjects(productsWithVariationsList, catalogId); } // Fill SEO info for products, variations and outline items if ((respGroup & ItemResponseGroup.Seo) == ItemResponseGroup.Seo) { var objectsWithSeo = productsWithVariationsList.OfType <ISeoSupport>().ToList(); //Load SEO information for all Outline.Items var outlineItems = productsWithVariationsList.Where(p => p.Outlines != null) .SelectMany(p => p.Outlines.SelectMany(o => o.Items)); objectsWithSeo.AddRange(outlineItems); _commerceService.LoadSeoForObjects(objectsWithSeo.ToArray()); } //Reduce details according to response group foreach (var product in productsWithVariationsList) { ReduceDetails(product, respGroup); } } } return(result); }
public async Task<Product[]> GetProductsAsync(string[] ids, ItemResponseGroup responseGroup = ItemResponseGroup.ItemInfo) { var workContext = _workContextFactory(); var retVal = (await _catalogModuleApi.CatalogModuleProductsGetProductByIdsAsync(ids.ToList(), ((int)responseGroup).ToString())).Select(x => x.ToWebModel(workContext.CurrentLanguage, workContext.CurrentCurrency, workContext.CurrentStore)).ToArray(); var allProducts = retVal.Concat(retVal.SelectMany(x => x.Variations)).ToArray(); if (!allProducts.IsNullOrEmpty()) { var taskList = new List<Task>(); if (responseGroup.HasFlag(ItemResponseGroup.ItemAssociations)) { taskList.Add(LoadProductsAssociationsAsync(allProducts)); } if (responseGroup.HasFlag(ItemResponseGroup.Inventory)) { taskList.Add(LoadProductsInventoriesAsync(allProducts)); } if (responseGroup.HasFlag(ItemResponseGroup.ItemWithPrices)) { await _pricingService.EvaluateProductPricesAsync(allProducts); if ((responseGroup | ItemResponseGroup.ItemWithDiscounts) == responseGroup) { await LoadProductsDiscountsAsync(allProducts); } } await Task.WhenAll(taskList.ToArray()); } return retVal; }
protected virtual void ReduceSearchResult(ISearchCriteria criteria, ItemResponseGroup responseGroup, catalogModel.Product product) { if (!responseGroup.HasFlag(ItemResponseGroup.ItemAssets)) { product.Assets = null; } if (!responseGroup.HasFlag(ItemResponseGroup.ItemAssociations)) { product.Associations = null; } if (!responseGroup.HasFlag(ItemResponseGroup.ItemEditorialReviews)) { product.Reviews = null; } if (!responseGroup.HasFlag(ItemResponseGroup.ItemInfo)) { product.Properties = null; } if (!responseGroup.HasFlag(ItemResponseGroup.Links)) { product.Links = null; } if (!responseGroup.HasFlag(ItemResponseGroup.Outlines)) { product.Outlines = null; } if (!responseGroup.HasFlag(ItemResponseGroup.Seo)) { product.SeoInfos = null; } if (!responseGroup.HasFlag(ItemResponseGroup.Variations)) { product.Variations = null; } }
public virtual async Task <Product[]> GetProductsAsync(string[] ids, ItemResponseGroup responseGroup = ItemResponseGroup.None) { Product[] result; if (ids.IsNullOrEmpty()) { result = new Product[0]; } else { var workContext = _workContextAccessor.WorkContext; if (responseGroup == ItemResponseGroup.None) { responseGroup = workContext.CurrentProductResponseGroup; } result = await GetProductsAsync(ids, responseGroup, workContext); var allProducts = result.Concat(result.SelectMany(p => p.Variations)).ToList(); if (!allProducts.IsNullOrEmpty()) { var taskList = new List <Task>(); if (responseGroup.HasFlag(ItemResponseGroup.Inventory)) { taskList.Add(LoadProductInventoriesAsync(allProducts, workContext)); } if (responseGroup.HasFlag(ItemResponseGroup.ItemAssociations)) { taskList.Add(LoadProductsAssociationsAsync(allProducts, workContext)); } if (responseGroup.HasFlag(ItemResponseGroup.ItemWithPrices)) { taskList.Add(_pricingService.EvaluateProductPricesAsync(allProducts, workContext)); } if (responseGroup.HasFlag(ItemResponseGroup.ItemWithVendor)) { taskList.Add(LoadProductVendorsAsync(allProducts, workContext)); } if (workContext.CurrentStore.SubscriptionEnabled && responseGroup.HasFlag(ItemResponseGroup.ItemWithPaymentPlan)) { taskList.Add(LoadProductPaymentPlanAsync(allProducts, workContext)); } taskList.Add(LoadProductCustomerReviewsAsync(allProducts, workContext)); await Task.WhenAll(taskList.ToArray()); foreach (var product in allProducts) { product.IsBuyable = new ProductIsBuyableSpecification().IsSatisfiedBy(product); product.IsAvailable = new ProductIsAvailableSpecification(product).IsSatisfiedBy(1); product.IsInStock = new ProductIsInStockSpecification().IsSatisfiedBy(product); } } } return(result); }
public virtual CatalogProduct[] GetByIds(string[] itemIds, ItemResponseGroup respGroup, string catalogId = null) { CatalogProduct[] result; using (var repository = _repositoryFactory()) { //Optimize performance and CPU usage repository.DisableChangesTracking(); result = repository.GetItemByIds(itemIds, respGroup) .Select(x => x.ToModel(AbstractTypeFactory <CatalogProduct> .TryCreateInstance())) .ToArray(); } LoadDependencies(result); ApplyInheritanceRules(result); // Fill outlines for products if (respGroup.HasFlag(ItemResponseGroup.Outlines)) { _outlineService.FillOutlinesForObjects(result, catalogId); } // Fill SEO info for products, variations and outline items if ((respGroup & ItemResponseGroup.Seo) == ItemResponseGroup.Seo) { var objectsWithSeo = new List <ISeoSupport>(result); var variations = result.Where(p => p.Variations != null) .SelectMany(p => p.Variations); objectsWithSeo.AddRange(variations); var outlineItems = result.Where(p => p.Outlines != null) .SelectMany(p => p.Outlines.SelectMany(o => o.Items)); objectsWithSeo.AddRange(outlineItems); _commerceService.LoadSeoForObjects(objectsWithSeo.ToArray()); } //Reduce details according to response group foreach (var product in result) { if (!respGroup.HasFlag(ItemResponseGroup.ItemAssets)) { product.Assets = null; } if (!respGroup.HasFlag(ItemResponseGroup.ItemAssociations)) { product.Associations = null; } if (!respGroup.HasFlag(ItemResponseGroup.ReferencedAssociations)) { product.ReferencedAssociations = null; } if (!respGroup.HasFlag(ItemResponseGroup.ItemEditorialReviews)) { product.Reviews = null; } if (!respGroup.HasFlag(ItemResponseGroup.Inventory)) { product.Inventories = null; } if (!respGroup.HasFlag(ItemResponseGroup.ItemProperties)) { product.Properties = null; } if (!respGroup.HasFlag(ItemResponseGroup.Links)) { product.Links = null; } if (!respGroup.HasFlag(ItemResponseGroup.Outlines)) { product.Outlines = null; } if (!respGroup.HasFlag(ItemResponseGroup.Seo)) { product.SeoInfos = null; } if (!respGroup.HasFlag(ItemResponseGroup.Variations)) { product.Variations = null; } } return(result); }
public ItemEntity[] GetItemByIds(string[] itemIds, ItemResponseGroup respGroup = ItemResponseGroup.ItemLarge) { if (itemIds == null) { throw new ArgumentNullException(nameof(itemIds)); } if (!itemIds.Any()) { return(new ItemEntity[] { }); } // Use breaking query EF performance concept https://msdn.microsoft.com/en-us/data/hh949853.aspx#8 var retVal = Items.Include(x => x.Images).Where(x => itemIds.Contains(x.Id)).ToArray(); if (respGroup.HasFlag(ItemResponseGroup.Outlines)) { respGroup |= ItemResponseGroup.Links; } if (respGroup.HasFlag(ItemResponseGroup.ItemProperties)) { var propertyValues = PropertyValues.Where(x => itemIds.Contains(x.ItemId)).ToArray(); } if (respGroup.HasFlag(ItemResponseGroup.Links)) { var relations = CategoryItemRelations.Where(x => itemIds.Contains(x.ItemId)).ToArray(); } if (respGroup.HasFlag(ItemResponseGroup.ItemAssets)) { var assets = Assets.Where(x => itemIds.Contains(x.ItemId)).ToArray(); } if (respGroup.HasFlag(ItemResponseGroup.ItemEditorialReviews)) { var editorialReviews = EditorialReviews.Where(x => itemIds.Contains(x.ItemId)).ToArray(); } if (respGroup.HasFlag(ItemResponseGroup.Variations)) { // TODO: Call GetItemByIds for variations recursively (need to measure performance and data amount first) var variationIds = Items.Where(x => itemIds.Contains(x.ParentId)).Select(x => x.Id).ToArray(); // Always load info, images and property values for variations var variations = Items.Include(x => x.Images).Where(x => variationIds.Contains(x.Id)).ToArray(); var variationPropertyValues = PropertyValues.Where(x => variationIds.Contains(x.ItemId)).ToArray(); if (respGroup.HasFlag(ItemResponseGroup.ItemAssets)) { var variationAssets = Assets.Where(x => variationIds.Contains(x.ItemId)).ToArray(); } if (respGroup.HasFlag(ItemResponseGroup.ItemEditorialReviews)) { var variationEditorialReviews = EditorialReviews.Where(x => variationIds.Contains(x.ItemId)).ToArray(); } } if (respGroup.HasFlag(ItemResponseGroup.ItemAssociations)) { var assosiations = Associations.Where(x => itemIds.Contains(x.ItemId)).ToArray(); var assosiatedProductIds = assosiations.Where(x => x.AssociatedItemId != null) .Select(x => x.AssociatedItemId).Distinct().ToArray(); var assosiatedItems = GetItemByIds(assosiatedProductIds, ItemResponseGroup.ItemInfo | ItemResponseGroup.ItemAssets); var assosiatedCategoryIdsIds = assosiations.Where(x => x.AssociatedCategoryId != null).Select(x => x.AssociatedCategoryId).Distinct().ToArray(); var associatedCategories = GetCategoriesByIds(assosiatedCategoryIdsIds, CategoryResponseGroup.Info.ToString()); } if (respGroup.HasFlag(ItemResponseGroup.ReferencedAssociations)) { var referencedAssociations = Associations.Where(x => itemIds.Contains(x.AssociatedItemId)).ToArray(); var referencedProductIds = referencedAssociations.Select(x => x.ItemId).Distinct().ToArray(); var referencedProducts = GetItemByIds(referencedProductIds, ItemResponseGroup.ItemInfo); } // Load parents var parentIds = retVal.Where(x => x.Parent == null && x.ParentId != null).Select(x => x.ParentId).ToArray(); var parents = GetItemByIds(parentIds, respGroup); return(retVal); }
public async Task <ItemEntity[]> GetItemByIdsAsync(string[] itemIds, ItemResponseGroup respGroup = ItemResponseGroup.ItemLarge) { var result = Array.Empty <ItemEntity>(); if (!itemIds.IsNullOrEmpty()) { // Use breaking query EF performance concept https://msdn.microsoft.com/en-us/data/hh949853.aspx#8 result = await Items.Include(x => x.Images).Where(x => itemIds.Contains(x.Id)).ToArrayAsync(); if (result.Any()) { if (respGroup.HasFlag(ItemResponseGroup.Outlines)) { respGroup |= ItemResponseGroup.Links; } if (respGroup.HasFlag(ItemResponseGroup.ItemProperties)) { var propertyValues = await PropertyValues.Include(x => x.DictionaryItem.DictionaryItemValues).Where(x => itemIds.Contains(x.ItemId)).ToArrayAsync(); } if (respGroup.HasFlag(ItemResponseGroup.Links)) { var relations = await CategoryItemRelations.Where(x => itemIds.Contains(x.ItemId)).ToArrayAsync(); } if (respGroup.HasFlag(ItemResponseGroup.ItemAssets)) { var assets = await Assets.Where(x => itemIds.Contains(x.ItemId)).ToArrayAsync(); } if (respGroup.HasFlag(ItemResponseGroup.ItemEditorialReviews)) { var editorialReviews = await EditorialReviews.Where(x => itemIds.Contains(x.ItemId)).ToArrayAsync(); } if (respGroup.HasFlag(ItemResponseGroup.WithSeo)) { var seoInfos = await SeoInfos.Where(x => itemIds.Contains(x.ItemId)).ToArrayAsync(); } if (respGroup.HasFlag(ItemResponseGroup.Variations)) { // TODO: Call GetItemByIds for variations recursively (need to measure performance and data amount first) var variationIds = await Items.Where(x => itemIds.Contains(x.ParentId)).Select(x => x.Id).ToArrayAsync(); // Always load info, images and property values for variations var variationsTask = Items.Include(x => x.Images).Where(x => variationIds.Contains(x.Id)).ToArrayAsync(); var variationPropertyValuesTask = PropertyValues.Where(x => variationIds.Contains(x.ItemId)).ToArrayAsync(); await Task.WhenAll(variationsTask, variationPropertyValuesTask); if (respGroup.HasFlag(ItemResponseGroup.ItemAssets)) { var variationAssets = await Assets.Where(x => variationIds.Contains(x.ItemId)).ToArrayAsync(); } if (respGroup.HasFlag(ItemResponseGroup.ItemEditorialReviews)) { var variationEditorialReviews = await EditorialReviews.Where(x => variationIds.Contains(x.ItemId)).ToArrayAsync(); } if (respGroup.HasFlag(ItemResponseGroup.Seo)) { var variationsSeoInfos = await SeoInfos.Where(x => variationIds.Contains(x.ItemId)).ToArrayAsync(); } } if (respGroup.HasFlag(ItemResponseGroup.ItemAssociations)) { var assosiations = await Associations.Where(x => itemIds.Contains(x.ItemId)).ToArrayAsync(); var assosiatedProductIds = assosiations.Where(x => x.AssociatedItemId != null) .Select(x => x.AssociatedItemId).Distinct().ToArray(); var assosiatedItems = await GetItemByIdsAsync(assosiatedProductIds, ItemResponseGroup.ItemInfo | ItemResponseGroup.ItemAssets); var assosiatedCategoryIdsIds = assosiations.Where(x => x.AssociatedCategoryId != null).Select(x => x.AssociatedCategoryId).Distinct().ToArray(); var associatedCategories = await GetCategoriesByIdsAsync(assosiatedCategoryIdsIds, CategoryResponseGroup.Info | CategoryResponseGroup.WithImages); } if (respGroup.HasFlag(ItemResponseGroup.ReferencedAssociations)) { var referencedAssociations = await Associations.Where(x => itemIds.Contains(x.AssociatedItemId)).ToArrayAsync(); var referencedProductIds = referencedAssociations.Select(x => x.ItemId).Distinct().ToArray(); var referencedProducts = await GetItemByIdsAsync(referencedProductIds, ItemResponseGroup.ItemInfo); } // Load parents var parentIds = result.Where(x => x.Parent == null && x.ParentId != null).Select(x => x.ParentId).ToArray(); var parents = await GetItemByIdsAsync(parentIds, respGroup); } } return(result); }