Exemplo n.º 1
0
        public async Task <IActionResult> UpdateProductDetails(int productId, string itemType, int bundleItemId, ProductVariantQuery query)
        {
            // TODO: (core) UpdateProductDetails action needs some decent refactoring.
            var    form              = HttpContext.Request.Form;
            int    quantity          = 1;
            int    galleryStartIndex = -1;
            string galleryHtml       = null;
            string dynamicThumbUrl   = null;
            var    isAssociated      = itemType.EqualsNoCase("associateditem");

            var product = await _db.Products.FindByIdAsync(productId);

            var batchContext = _productService.CreateProductBatchContext(new[] { product }, includeHidden: false);
            var bItem        = await _db.ProductBundleItem
                               .Include(x => x.BundleProduct)
                               .FindByIdAsync(bundleItemId, false);

            IList <ProductBundleItemData> bundleItemDatas = null;
            ProductBundleItemData         bundleItem      = bItem == null ? null : new ProductBundleItemData(bItem);

            // Quantity required for tier prices.
            string quantityKey = form.Keys.FirstOrDefault(k => k.EndsWith("EnteredQuantity"));

            if (quantityKey.HasValue())
            {
                _ = int.TryParse(form[quantityKey], out quantity);
            }

            if (product.ProductType == ProductType.BundledProduct && product.BundlePerItemPricing)
            {
                var bundleItemQuery = await _db.ProductBundleItem
                                      .AsNoTracking()
                                      .ApplyBundledProductsFilter(new[] { product.Id })
                                      .Include(x => x.Product)
                                      .Include(x => x.BundleProduct)
                                      .ToListAsync();

                if (bundleItemQuery.Count > 0)
                {
                    bundleItemDatas = new List <ProductBundleItemData>();
                    bundleItemQuery.Each(x => bundleItemDatas.Add(new ProductBundleItemData(x)));
                }

                if (query.Variants.Count > 0)
                {
                    batchContext.Collect(bundleItemDatas.Select(x => x.Item.Product.Id).ToArray());

                    // May add elements to query object if they are preselected by bundle item filter.
                    foreach (var itemData in bundleItemDatas)
                    {
                        await _helper.MapProductDetailsPageModelAsync(new ProductDetailsModelContext
                        {
                            Product           = itemData.Item.Product,
                            BatchContext      = batchContext,
                            VariantQuery      = query,
                            ProductBundleItem = itemData
                        });
                    }
                }
            }

            var modelContext = new ProductDetailsModelContext
            {
                Product             = product,
                BatchContext        = batchContext,
                VariantQuery        = query,
                IsAssociatedProduct = isAssociated,
                ProductBundleItem   = bundleItem,
                BundleItemDatas     = bundleItemDatas,
                Customer            = batchContext.Customer,
                Store    = batchContext.Store,
                Currency = Services.WorkContext.WorkingCurrency
            };

            // Get merged model data.
            var model = new ProductDetailsModel();
            await _helper.PrepareProductDetailModelAsync(model, modelContext, quantity);

            if (bundleItem != null)
            {
                // Update bundle item thumbnail.
                if (!bundleItem.Item.HideThumbnail)
                {
                    var assignedMediaIds = model.SelectedCombination?.GetAssignedMediaIds() ?? Array.Empty <int>();
                    var hasFile          = assignedMediaIds.Any() && await _db.MediaFiles.AnyAsync(x => x.Id == assignedMediaIds[0]);

                    if (assignedMediaIds.Any() && hasFile)
                    {
                        var file = await _db.ProductMediaFiles
                                   .AsNoTracking()
                                   .ApplyProductFilter(new[] { bundleItem.Item.ProductId }, 1)
                                   .Select(x => x.MediaFile)
                                   .FirstOrDefaultAsync();

                        dynamicThumbUrl = _mediaService.GetUrl(file, _mediaSettings.BundledProductPictureSize, null, false);
                    }
                }
            }
            else if (isAssociated)
            {
                // Update associated product thumbnail.
                var assignedMediaIds = model.SelectedCombination?.GetAssignedMediaIds() ?? new int[0];
                var hasFile          = await _db.MediaFiles.AnyAsync(x => x.Id == assignedMediaIds[0]);

                if (assignedMediaIds.Any() && hasFile)
                {
                    var file = await _db.ProductMediaFiles
                               .AsNoTracking()
                               .ApplyProductFilter(new[] { productId }, 1)
                               .Select(x => x.MediaFile)
                               .FirstOrDefaultAsync();

                    dynamicThumbUrl = _mediaService.GetUrl(file, _mediaSettings.AssociatedProductPictureSize, null, false);
                }
            }
            else if (product.ProductType != ProductType.BundledProduct)
            {
                // Update image gallery.
                var files = await _db.ProductMediaFiles
                            .AsNoTracking()
                            .ApplyProductFilter(new[] { productId })
                            .Select(x => _mediaService.ConvertMediaFile(x.MediaFile))
                            .ToListAsync();

                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 = model.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 = await _productAttributeService.GetAttributeCombinationFileIdsAsync(product.Id);

                    var mediaModel = _helper.PrepareProductDetailsMediaGalleryModel(
                        files,
                        product.GetLocalized(x => x.Name),
                        allCombinationPictureIds,
                        false,
                        bundleItem,
                        model.SelectedCombination);

                    galleryStartIndex = mediaModel.GalleryStartIndex;
                    galleryHtml       = (await this.InvokeViewAsync("Product.Media", mediaModel)).ToString();
                }

                model.PriceDisplayStyle        = _catalogSettings.PriceDisplayStyle;
                model.DisplayTextForZeroPrices = _catalogSettings.DisplayTextForZeroPrices;
            }

            object partials = null;

            if (model.IsBundlePart)
            {
                partials = new
                {
                    BundleItemPrice    = await this.InvokeViewAsync("Product.Offer.Price", model),
                    BundleItemStock    = await this.InvokeViewAsync("Product.StockInfo", model),
                    BundleItemVariants = await this.InvokeViewAsync("Product.Variants", model.ProductVariantAttributes)
                };
            }
            else
            {
                var dataDictAddToCart = new ViewDataDictionary(ViewData)
                {
                    Model = model
                };
                dataDictAddToCart.TemplateInfo.HtmlFieldPrefix = $"addtocart_{model.Id}";

                decimal adjustment = decimal.Zero;
                decimal taxRate    = decimal.Zero;

                // TODO: (mh) (core) Implement when pricing is available.
                //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        = await this.InvokeViewAsync("Product.Attrs", model),
                    Price        = await this.InvokeViewAsync("Product.Offer.Price", model),
                    Stock        = await this.InvokeViewAsync("Product.StockInfo", model),
                    Variants     = await this.InvokeViewAsync("Product.Variants", model.ProductVariantAttributes),
                    OfferActions = await this.InvokeViewAsync("Product.Offer.Actions", dataDictAddToCart),
                    TierPrices   = await this.InvokeViewAsync("Product.TierPrices", model.TierPrices),
                    BundlePrice  = product.ProductType == ProductType.BundledProduct ? await this.InvokeViewAsync("Product.Bundle.Price", model) : null
                };
            }

            object data = new
            {
                Partials          = partials,
                DynamicThumblUrl  = dynamicThumbUrl,
                GalleryStartIndex = galleryStartIndex,
                GalleryHtml       = galleryHtml
            };

            return(new JsonResult(new { Data = data }));
        }
Exemplo n.º 2
0
        public async Task <IActionResult> UpdateProductDetails(int productId, string itemType, int bundleItemId, ProductVariantQuery query)
        {
            // TODO: (core) UpdateProductDetails action needs some decent refactoring.
            var    form              = HttpContext.Request.Form;
            var    quantity          = 1;
            var    galleryStartIndex = -1;
            string galleryHtml       = null;
            string dynamicThumbUrl   = null;
            var    isAssociated      = itemType.EqualsNoCase("associateditem");
            var    currency          = Services.WorkContext.WorkingCurrency;
            var    displayPrices     = await Services.Permissions.AuthorizeAsync(Permissions.Catalog.DisplayPrice);

            var product = await _db.Products.FindByIdAsync(productId);

            var batchContext = _productService.CreateProductBatchContext(new[] { product }, includeHidden: false);
            var bundleItem   = await _db.ProductBundleItem
                               .Include(x => x.BundleProduct)
                               .FindByIdAsync(bundleItemId, false);

            // Quantity required for tier prices.
            string quantityKey = form.Keys.FirstOrDefault(k => k.EndsWith("EnteredQuantity"));

            if (quantityKey.HasValue())
            {
                _ = int.TryParse(form[quantityKey], out quantity);
            }

            var modelContext = new ProductDetailsModelContext
            {
                Product             = product,
                BatchContext        = batchContext,
                VariantQuery        = query,
                IsAssociatedProduct = isAssociated,
                ProductBundleItem   = bundleItem,
                Customer            = batchContext.Customer,
                Store         = batchContext.Store,
                Currency      = currency,
                DisplayPrices = displayPrices
            };

            // Get merged model data.
            var model = new ProductDetailsModel();
            await _helper.PrepareProductDetailModelAsync(model, modelContext, quantity);

            if (bundleItem != null)
            {
                // Update bundle item thumbnail.
                if (!bundleItem.HideThumbnail)
                {
                    var assignedMediaIds = model.SelectedCombination?.GetAssignedMediaIds() ?? Array.Empty <int>();

                    if (assignedMediaIds.Any() && await _db.MediaFiles.AnyAsync(x => x.Id == assignedMediaIds[0]))
                    {
                        var file = await _db.ProductMediaFiles
                                   .AsNoTracking()
                                   .Include(x => x.MediaFile)
                                   .ApplyProductFilter(bundleItem.ProductId)
                                   .FirstOrDefaultAsync();

                        dynamicThumbUrl = _mediaService.GetUrl(file?.MediaFile, _mediaSettings.BundledProductPictureSize, null, false);
                    }
                }
            }
            else if (isAssociated)
            {
                // Update associated product thumbnail.
                var assignedMediaIds = model.SelectedCombination?.GetAssignedMediaIds() ?? Array.Empty <int>();

                if (assignedMediaIds.Any() && await _db.MediaFiles.AnyAsync(x => x.Id == assignedMediaIds[0]))
                {
                    var file = await _db.ProductMediaFiles
                               .AsNoTracking()
                               .Include(x => x.MediaFile)
                               .ApplyProductFilter(productId)
                               .FirstOrDefaultAsync();

                    dynamicThumbUrl = _mediaService.GetUrl(file?.MediaFile, _mediaSettings.AssociatedProductPictureSize, null, false);
                }
            }
            else if (product.ProductType != ProductType.BundledProduct)
            {
                // Update image gallery.
                var files = await _db.ProductMediaFiles
                            .AsNoTracking()
                            .Include(x => x.MediaFile)
                            .ApplyProductFilter(productId)
                            .ToListAsync();

                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 = model.SelectedCombination?.GetAssignedMediaIds() ?? Array.Empty <int>();
                    if (assignedMediaIds.Any())
                    {
                        var file = files.FirstOrDefault(p => p.Id == assignedMediaIds[0]);
                        galleryStartIndex = file == null ? 0 : files.IndexOf(file);
                    }
                }
                else
                {
                    var allCombinationPictureIds = await _productAttributeService.GetAttributeCombinationFileIdsAsync(product.Id);

                    var mediaFiles = files
                                     .Where(x => x.MediaFile != null)
                                     .Select(x => _mediaService.ConvertMediaFile(x.MediaFile))
                                     .ToList();

                    var mediaModel = _helper.PrepareProductDetailsMediaGalleryModel(
                        mediaFiles,
                        product.GetLocalized(x => x.Name),
                        allCombinationPictureIds,
                        false,
                        bundleItem,
                        model.SelectedCombination);

                    galleryStartIndex = mediaModel.GalleryStartIndex;
                    galleryHtml       = (await this.InvokeViewAsync("Product.Media", mediaModel)).ToString();
                }

                model.PriceDisplayStyle        = _catalogSettings.PriceDisplayStyle;
                model.DisplayTextForZeroPrices = _catalogSettings.DisplayTextForZeroPrices;
            }

            object partials = null;

            if (model.IsBundlePart)
            {
                partials = new
                {
                    BundleItemPrice    = await this.InvokeViewAsync("Product.Offer.Price", model),
                    BundleItemStock    = await this.InvokeViewAsync("Product.StockInfo", model),
                    BundleItemVariants = await this.InvokeViewAsync("Product.Variants", model.ProductVariantAttributes)
                };
            }
            else
            {
                var dataDictAddToCart = new ViewDataDictionary(ViewData)
                {
                    Model = model
                };
                dataDictAddToCart.TemplateInfo.HtmlFieldPrefix = $"addtocart_{model.Id}";

                partials = new
                {
                    Attrs        = await this.InvokeViewAsync("Product.Attrs", model),
                    Price        = await this.InvokeViewAsync("Product.Offer.Price", model),
                    Stock        = await this.InvokeViewAsync("Product.StockInfo", model),
                    Variants     = await this.InvokeViewAsync("Product.Variants", model.ProductVariantAttributes),
                    OfferActions = await this.InvokeViewAsync("Product.Offer.Actions", dataDictAddToCart),
                    TierPrices   = await this.InvokeViewAsync("Product.TierPrices", model.TierPrices),
                    BundlePrice  = product.ProductType == ProductType.BundledProduct ? await this.InvokeViewAsync("Product.Bundle.Price", model) : null
                };
            }

            object data = new
            {
                Partials          = partials,
                DynamicThumblUrl  = dynamicThumbUrl,
                GalleryStartIndex = galleryStartIndex,
                GalleryHtml       = galleryHtml
            };

            return(new JsonResult(data));
        }