public ProductPageViewModel Build(BaseProduct baseProduct)
        {
            var productModel = _productModelBuilder.BuildFromBaseProduct(baseProduct);
            var viewModel    = Build(productModel);

            viewModel.Variants         = GetVariants(productModel, _requestModelAccessor.RequestModel.WebsiteModel.SystemId, _requestModelAccessor.RequestModel.ChannelModel.SystemId);
            viewModel.MostSoldProducts = GetMostSoldProducts(baseProduct.Id);

            return(viewModel);
        }
            private ProductModel CreateProductModel(SearchQuery searchQuery, BaseProduct baseProduct, ICollection <Variant> variants, Guid channelSystemId)
            {
                IEnumerable <Variant> currentVariants = variants;

                if (searchQuery.CategorySystemId != null && searchQuery.CategorySystemId != Guid.Empty)
                {
                    var product      = baseProduct ?? _baseProductService.Get(currentVariants.First().BaseProductSystemId);
                    var categoryLink = _categoryService.Get(searchQuery.CategorySystemId.Value)?.ProductLinks.FirstOrDefault(x => x.BaseProductSystemId == product.SystemId);
                    if (categoryLink != null)
                    {
                        currentVariants = currentVariants.Where(x => categoryLink.ActiveVariantSystemIds.Contains(x.SystemId));
                    }
                }

                currentVariants = currentVariants
                                  .Where(x => x.ChannelLinks.Any(z => z.ChannelSystemId == channelSystemId))
                                  .OrderBy(x => x.SortIndex);

                if (searchQuery.Tags.Count > 0)
                {
                    var     order        = new ConcurrentDictionary <Variant, int>();
                    Variant firstVariant = null;
                    foreach (var tag in searchQuery.Tags)
                    {
                        var fieldDefinition = _fieldDefinitionService.Get <ProductArea>(tag.Key);
                        // ReSharper disable once PossibleMultipleEnumeration
                        foreach (var variant in currentVariants)
                        {
                            if (firstVariant == null)
                            {
                                firstVariant = variant;
                            }

                            var value = GetTranslatedValue((variant.Fields[tag.Key, CultureInfo.CurrentCulture] ?? variant.Fields[tag.Key]) as string, CultureInfo.CurrentCulture, fieldDefinition);
                            if (tag.Value.Contains(value))
                            {
                                order.AddOrUpdate(variant, _ => 1, (_, c) => c + 1);
                            }
                        }
                    }

                    if (order.Count > 0)
                    {
                        currentVariants = order.OrderByDescending(x => x.Value).Select(x => x.Key);
                    }
                }

                return(baseProduct == null
                    ? _productModelBuilder.BuildFromVariant(currentVariants.First())
                    : _productModelBuilder.BuildFromBaseProduct(baseProduct, currentVariants.First()));
            }
      /// <summary>
      /// Build the product block view model
      /// </summary>
      /// <param name="blockModel">The current product block</param>
      /// <returns>Return the product block view model</returns>
      public virtual async Task <ProductBlockViewModel> BuildAsync(BlockModel blockModel)
      {
          var data      = blockModel.MapTo <ProductBlockViewModelData>();
          var viewModel = new ProductBlockViewModel();
          var channel   = _requestModelAccessor.RequestModel.ChannelModel.Channel;

          if (data != null)
          {
              viewModel.FooterLinkText = data.LinkText;
              if (data.LinkToCategorySystemId != Guid.Empty)
              {
                  viewModel.FooterLinkUrl = data.LinkToCategorySystemId.MapTo <Category>().GetUrl(_requestModelAccessor.RequestModel.ChannelModel.SystemId, true);
              }
              else if (!string.IsNullOrEmpty(data.LinkToPage.Href))
              {
                  viewModel.FooterLinkUrl = data.LinkToPage.Href;
              }

              viewModel.Title = data.Title;

              var products = new List <ProductModel>();
              if (data.SectionProductsType == BlockProductsType.Products)
              {
                  products.AddRange(data.ProductSystemIds.Select(x => _productModelBuilder.BuildFromVariant(_variantService.Get(x)) ?? _productModelBuilder.BuildFromBaseProduct(_baseProductService.Get(x), channel)).Where(x => x != null));
              }
              else
              {
                  var searchQuery = new SearchQuery
                  {
                      PageSize = data.NumberOfProducts
                  };

                  switch (data.SectionProductsType)
                  {
                  case BlockProductsType.Category:
                      searchQuery.CategoryShowRecursively = true;
                      searchQuery.SortBy           = data.ProductSorting;
                      searchQuery.CategorySystemId = data.CategorySystemId;
                      break;

                  case BlockProductsType.ProductList:
                      searchQuery.ProductListSystemId = data.ProductListSystemId;
                      break;
                  }
                  var items = (await _productSearchService.SearchAsync(searchQuery))?.Items.Value;
                  if (items != null)
                  {
                      products.AddRange(items.OfType <ProductSearchResult>().Select(x => x.Item));
                  }
              }

              viewModel.Products = products.Select(x => _productItemViewModelBuilder.Build(x)).ToList();
          }
          return(viewModel);
      }