public ActionResult UpdateProductDetails(int productId, string itemType, int bundleItemId, ProductVariantQuery query, FormCollection form) { int quantity = 1; int galleryStartIndex = -1; string galleryHtml = null; string dynamicThumbUrl = null; var isAssociated = itemType.IsCaseInsensitiveEqual("associateditem"); var m = new ProductDetailsModel(); var product = _productService.GetProductById(productId); var bItem = _productService.GetBundleItemById(bundleItemId); IList <ProductBundleItemData> bundleItems = null; ProductBundleItemData bundleItem = bItem == null ? null : new ProductBundleItemData(bItem); // Quantity required for tier prices. string quantityKey = form.AllKeys.FirstOrDefault(k => k.EndsWith("EnteredQuantity")); if (quantityKey.HasValue()) { int.TryParse(form[quantityKey], out quantity); } if (product.ProductType == ProductType.BundledProduct && product.BundlePerItemPricing) { bundleItems = _productService.GetBundleItems(product.Id); if (query.Variants.Count > 0) { // May add elements to query object if they are preselected by bundle item filter. foreach (var itemData in bundleItems) { _helper.PrepareProductDetailsPageModel(itemData.Item.Product, query, false, itemData, null); } } } // Get merged model data. _helper.PrepareProductDetailModel(m, product, query, isAssociated, bundleItem, bundleItems, quantity); if (bundleItem != null) { // Update bundle item thumbnail. if (!bundleItem.Item.HideThumbnail) { var assignedMediaIds = m.SelectedCombination?.GetAssignedMediaIds() ?? new int[0]; if (assignedMediaIds.Any() && _mediaService.GetFileById(assignedMediaIds[0], MediaLoadFlags.AsNoTracking) != null) { var file = _productService.GetProductPicturesByProductId(bundleItem.Item.ProductId, 1) .Select(x => x.MediaFile) .FirstOrDefault(); dynamicThumbUrl = _mediaService.GetUrl(file, _mediaSettings.BundledProductPictureSize, null, false); } } } else if (isAssociated) { // Update associated product thumbnail. var assignedMediaIds = m.SelectedCombination?.GetAssignedMediaIds() ?? new int[0]; if (assignedMediaIds.Any() && _mediaService.GetFileById(assignedMediaIds[0], MediaLoadFlags.AsNoTracking) != null) { var file = _productService.GetProductPicturesByProductId(productId, 1) .Select(x => x.MediaFile) .FirstOrDefault(); dynamicThumbUrl = _mediaService.GetUrl(file, _mediaSettings.AssociatedProductPictureSize, null, false); } } else if (product.ProductType != ProductType.BundledProduct) { // Update image gallery. var files = _productService.GetProductPicturesByProductId(productId) .Select(x => _mediaService.ConvertMediaFile(x.MediaFile)) .ToList(); if (product.HasPreviewPicture && files.Count > 1) { files.RemoveAt(0); } if (files.Count <= _catalogSettings.DisplayAllImagesNumber) { // All pictures rendered... only index is required. galleryStartIndex = 0; var assignedMediaIds = m.SelectedCombination?.GetAssignedMediaIds() ?? new int[0]; if (assignedMediaIds.Any()) { var file = files.FirstOrDefault(p => p.Id == assignedMediaIds[0]); galleryStartIndex = file == null ? 0 : files.IndexOf(file); } } else { var allCombinationPictureIds = _productAttributeService.GetAllProductVariantAttributeCombinationPictureIds(product.Id); var mediaModel = _helper.PrepareProductDetailsMediaGalleryModel( files, product.GetLocalized(x => x.Name), allCombinationPictureIds, false, bundleItem, m.SelectedCombination); galleryStartIndex = mediaModel.GalleryStartIndex; galleryHtml = this.RenderPartialViewToString("Product.Media", mediaModel); } m.PriceDisplayStyle = _catalogSettings.PriceDisplayStyle; m.DisplayTextForZeroPrices = _catalogSettings.DisplayTextForZeroPrices; } object partials = null; if (m.IsBundlePart) { partials = new { BundleItemPrice = this.RenderPartialViewToString("Product.Offer.Price", m), BundleItemStock = this.RenderPartialViewToString("Product.StockInfo", m), BundleItemVariants = this.RenderPartialViewToString("Product.Variants", m.ProductVariantAttributes) }; } else { var dataDictAddToCart = new ViewDataDictionary(); dataDictAddToCart.TemplateInfo.HtmlFieldPrefix = string.Format("addtocart_{0}", m.Id); decimal adjustment = decimal.Zero; decimal taxRate = decimal.Zero; var finalPriceWithDiscountBase = _taxService.GetProductPrice(product, product.Price, _services.WorkContext.CurrentCustomer, out taxRate); if (!_taxSettings.Value.PricesIncludeTax && _services.WorkContext.TaxDisplayType == TaxDisplayType.IncludingTax) { adjustment = (m.ProductPrice.PriceValue - finalPriceWithDiscountBase) / (taxRate / 100 + 1); } else if (_taxSettings.Value.PricesIncludeTax && _services.WorkContext.TaxDisplayType == TaxDisplayType.ExcludingTax) { adjustment = (m.ProductPrice.PriceValue - finalPriceWithDiscountBase) * (taxRate / 100 + 1); } else { adjustment = m.ProductPrice.PriceValue - finalPriceWithDiscountBase; } partials = new { Attrs = this.RenderPartialViewToString("Product.Attrs", m), Price = this.RenderPartialViewToString("Product.Offer.Price", m), Stock = this.RenderPartialViewToString("Product.StockInfo", m), Variants = this.RenderPartialViewToString("Product.Variants", m.ProductVariantAttributes), OfferActions = this.RenderPartialViewToString("Product.Offer.Actions", m, dataDictAddToCart), TierPrices = this.RenderPartialViewToString("Product.TierPrices", _helper.CreateTierPriceModel(product, adjustment)), BundlePrice = product.ProductType == ProductType.BundledProduct ? this.RenderPartialViewToString("Product.Bundle.Price", m) : (string)null }; } object data = new { Partials = partials, DynamicThumblUrl = dynamicThumbUrl, GalleryStartIndex = galleryStartIndex, GalleryHtml = galleryHtml }; return(new JsonResult { Data = data }); }