public static IEnumerable<ProductOverviewModel> PrepareProductOverviewModels(this Controller controller, IWorkContext workContext, IStoreContext storeContext, ICategoryService categoryService, IProductService productService, ISpecificationAttributeService specificationAttributeService, IPriceCalculationService priceCalculationService, IPriceFormatter priceFormatter, IPermissionService permissionService, ILocalizationService localizationService, ITaxService taxService, ICurrencyService currencyService, IPictureService pictureService, IWebHelper webHelper, ICacheManager cacheManager, CatalogSettings catalogSettings, MediaSettings mediaSettings, IEnumerable<Product> products, bool preparePriceModel = true, bool preparePictureModel = true, int? productThumbPictureSize = null, bool prepareSpecificationAttributes = false, bool forceRedirectionAfterAddingToCart = false) { if (products == null) throw new ArgumentNullException("products"); var models = new List<ProductOverviewModel>(); foreach (var product in products) { var model = new ProductOverviewModel { Id = product.Id, Name = product.GetLocalized(x => x.Name), ShortDescription = product.GetLocalized(x => x.ShortDescription), FullDescription = product.GetLocalized(x => x.FullDescription), SeName = product.GetSeName(), }; //price if (preparePriceModel) { #region Prepare product price var priceModel = new ProductOverviewModel.ProductPriceModel { ForceRedirectionAfterAddingToCart = forceRedirectionAfterAddingToCart }; switch (product.ProductType) { case ProductType.GroupedProduct: { #region Grouped product var associatedProducts = productService.GetAssociatedProducts(product.Id, storeContext.CurrentStore.Id); switch (associatedProducts.Count) { case 0: { //no associated products //priceModel.DisableBuyButton = true; //priceModel.DisableWishlistButton = true; //compare products priceModel.DisableAddToCompareListButton = !catalogSettings.CompareProductsEnabled; //priceModel.AvailableForPreOrder = false; } break; default: { //we have at least one associated product //priceModel.DisableBuyButton = true; //priceModel.DisableWishlistButton = true; //compare products priceModel.DisableAddToCompareListButton = !catalogSettings.CompareProductsEnabled; //priceModel.AvailableForPreOrder = false; if (permissionService.Authorize(StandardPermissionProvider.DisplayPrices)) { //find a minimum possible price decimal? minPossiblePrice = null; Product minPriceProduct = null; foreach (var associatedProduct in associatedProducts) { //calculate for the maximum quantity (in case if we have tier prices) var tmpPrice = priceCalculationService.GetFinalPrice(associatedProduct, workContext.CurrentCustomer, decimal.Zero, true, int.MaxValue); if (!minPossiblePrice.HasValue || tmpPrice < minPossiblePrice.Value) { minPriceProduct = associatedProduct; minPossiblePrice = tmpPrice; } } if (minPriceProduct != null && !minPriceProduct.CustomerEntersPrice) { if (minPriceProduct.CallForPrice) { priceModel.OldPrice = null; priceModel.Price = localizationService.GetResource("Products.CallForPrice"); } else if (minPossiblePrice.HasValue) { //calculate prices decimal taxRate; decimal finalPriceBase = taxService.GetProductPrice(minPriceProduct, minPossiblePrice.Value, out taxRate); decimal finalPrice = currencyService.ConvertFromPrimaryStoreCurrency(finalPriceBase, workContext.WorkingCurrency); priceModel.OldPrice = null; priceModel.Price = String.Format(localizationService.GetResource("Products.PriceRangeFrom"), priceFormatter.FormatPrice(finalPrice)); } else { //Actually it's not possible (we presume that minimalPrice always has a value) //We never should get here Debug.WriteLine("Cannot calculate minPrice for product #{0}", product.Id); } } } else { //hide prices priceModel.OldPrice = null; priceModel.Price = null; } } break; } #endregion } break; case ProductType.SimpleProduct: default: { #region Simple product //add to cart button priceModel.DisableBuyButton = product.DisableBuyButton || !permissionService.Authorize(StandardPermissionProvider.EnableShoppingCart) || !permissionService.Authorize(StandardPermissionProvider.DisplayPrices); //add to wishlist button priceModel.DisableWishlistButton = product.DisableWishlistButton || !permissionService.Authorize(StandardPermissionProvider.EnableWishlist) || !permissionService.Authorize(StandardPermissionProvider.DisplayPrices); //compare products priceModel.DisableAddToCompareListButton = !catalogSettings.CompareProductsEnabled; //rental priceModel.IsRental = product.IsRental; //pre-order if (product.AvailableForPreOrder) { priceModel.AvailableForPreOrder = !product.PreOrderAvailabilityStartDateTimeUtc.HasValue || product.PreOrderAvailabilityStartDateTimeUtc.Value >= DateTime.UtcNow; priceModel.PreOrderAvailabilityStartDateTimeUtc = product.PreOrderAvailabilityStartDateTimeUtc; } //prices if (permissionService.Authorize(StandardPermissionProvider.DisplayPrices)) { if (!product.CustomerEntersPrice) { if (product.CallForPrice) { //call for price priceModel.OldPrice = null; priceModel.Price = localizationService.GetResource("Products.CallForPrice"); } else { //prices //calculate for the maximum quantity (in case if we have tier prices) decimal minPossiblePrice = priceCalculationService.GetFinalPrice(product, workContext.CurrentCustomer, decimal.Zero, true, int.MaxValue); decimal taxRate; decimal oldPriceBase = taxService.GetProductPrice(product, product.OldPrice, out taxRate); decimal finalPriceBase = taxService.GetProductPrice(product, minPossiblePrice, out taxRate); decimal oldPrice = currencyService.ConvertFromPrimaryStoreCurrency(oldPriceBase, workContext.WorkingCurrency); decimal finalPrice = currencyService.ConvertFromPrimaryStoreCurrency(finalPriceBase, workContext.WorkingCurrency); //do we have tier prices configured? var tierPrices = new List<TierPrice>(); if (product.HasTierPrices) { tierPrices.AddRange(product.TierPrices .OrderBy(tp => tp.Quantity) .ToList() .FilterByStore(storeContext.CurrentStore.Id) .FilterForCustomer(workContext.CurrentCustomer) .RemoveDuplicatedQuantities()); } //When there is just one tier (with qty 1), //there are no actual savings in the list. bool displayFromMessage = tierPrices.Count > 0 && !(tierPrices.Count == 1 && tierPrices[0].Quantity <= 1); if (displayFromMessage) { priceModel.OldPrice = null; priceModel.Price = String.Format(localizationService.GetResource("Products.PriceRangeFrom"), priceFormatter.FormatPrice(finalPrice)); } else { if (finalPriceBase != oldPriceBase && oldPriceBase != decimal.Zero) { priceModel.OldPrice = priceFormatter.FormatPrice(oldPrice); priceModel.Price = priceFormatter.FormatPrice(finalPrice); } else { priceModel.OldPrice = null; priceModel.Price = priceFormatter.FormatPrice(finalPrice); } } if (product.IsRental) { //rental product priceModel.OldPrice = priceFormatter.FormatRentalProductPeriod(product, priceModel.OldPrice); priceModel.Price = priceFormatter.FormatRentalProductPeriod(product, priceModel.Price); } //property for German market //we display tax/shipping info only with "shipping enabled" for this product //we also ensure this it's not free shipping priceModel.DisplayTaxShippingInfo = catalogSettings.DisplayTaxShippingInfoProductBoxes && product.IsShipEnabled && !product.IsFreeShipping; } } } else { //hide prices priceModel.OldPrice = null; priceModel.Price = null; } #endregion } break; } model.ProductPrice = priceModel; #endregion } //picture if (preparePictureModel) { #region Prepare product picture //If a size has been set in the view, we use it in priority int pictureSize = productThumbPictureSize.HasValue ? productThumbPictureSize.Value : mediaSettings.ProductThumbPictureSize; //prepare picture model var defaultProductPictureCacheKey = string.Format(ModelCacheEventConsumer.PRODUCT_DEFAULTPICTURE_MODEL_KEY, product.Id, pictureSize, true, workContext.WorkingLanguage.Id, webHelper.IsCurrentConnectionSecured(), storeContext.CurrentStore.Id); model.DefaultPictureModel = cacheManager.Get(defaultProductPictureCacheKey, () => { var picture = pictureService.GetPicturesByProductId(product.Id, 1).FirstOrDefault(); var pictureModel = new PictureModel { ImageUrl = pictureService.GetPictureUrl(picture, pictureSize), FullSizeImageUrl = pictureService.GetPictureUrl(picture) }; //"title" attribute pictureModel.Title = (picture != null && !string.IsNullOrEmpty(picture.TitleAttribute)) ? picture.TitleAttribute : string.Format(localizationService.GetResource("Media.Product.ImageLinkTitleFormat"), model.Name); //"alt" attribute pictureModel.AlternateText = (picture != null && !string.IsNullOrEmpty(picture.AltAttribute)) ? picture.AltAttribute : string.Format(localizationService.GetResource("Media.Product.ImageAlternateTextFormat"), model.Name); return pictureModel; }); #endregion } //specs if (prepareSpecificationAttributes) { model.SpecificationAttributeModels = PrepareProductSpecificationModel(controller, workContext, specificationAttributeService, cacheManager, product); } //reviews model.ReviewOverviewModel = new ProductReviewOverviewModel { ProductId = product.Id, RatingSum = product.ApprovedRatingSum, TotalReviews = product.ApprovedTotalReviews, AllowCustomerReviews = product.AllowCustomerReviews }; models.Add(model); } return models; }
public static IEnumerable <ProductOverviewModel> PrepareProductOverviewModels(this Controller controller, IWorkContext workContext, IStoreContext storeContext, ICategoryService categoryService, IProductService productService, ISpecificationAttributeService specificationAttributeService, IPriceCalculationService priceCalculationService, IPriceFormatter priceFormatter, IPermissionService permissionService, ILocalizationService localizationService, ITaxService taxService, ICurrencyService currencyService, IPictureService pictureService, IWebHelper webHelper, ICacheManager cacheManager, CatalogSettings catalogSettings, MediaSettings mediaSettings, IEnumerable <Product> products, bool preparePriceModel = true, bool preparePictureModel = true, int?productThumbPictureSize = null, bool prepareSpecificationAttributes = false, bool forceRedirectionAfterAddingToCart = false) { if (products == null) { throw new ArgumentNullException("products"); } var models = new List <ProductOverviewModel>(); foreach (var product in products) { var model = new ProductOverviewModel { Id = product.Id, Name = product.GetLocalized(x => x.Name), ShortDescription = product.GetLocalized(x => x.ShortDescription), FullDescription = product.GetLocalized(x => x.FullDescription), SeName = product.GetSeName(), ProductType = product.ProductType, MarkAsNew = product.MarkAsNew && (!product.MarkAsNewStartDateTimeUtc.HasValue || product.MarkAsNewStartDateTimeUtc.Value < DateTime.UtcNow) && (!product.MarkAsNewEndDateTimeUtc.HasValue || product.MarkAsNewEndDateTimeUtc.Value > DateTime.UtcNow) }; //price if (preparePriceModel) { #region Prepare product price var priceModel = new ProductOverviewModel.ProductPriceModel { ForceRedirectionAfterAddingToCart = forceRedirectionAfterAddingToCart }; switch (product.ProductType) { case ProductType.GroupedProduct: { #region Grouped product var associatedProducts = productService.GetAssociatedProducts(product.Id, storeContext.CurrentStore.Id); //add to cart button (ignore "DisableBuyButton" property for grouped products) priceModel.DisableBuyButton = !permissionService.Authorize(StandardPermissionProvider.EnableShoppingCart) || !permissionService.Authorize(StandardPermissionProvider.DisplayPrices); //add to wishlist button (ignore "DisableWishlistButton" property for grouped products) priceModel.DisableWishlistButton = !permissionService.Authorize(StandardPermissionProvider.EnableWishlist) || !permissionService.Authorize(StandardPermissionProvider.DisplayPrices); //compare products priceModel.DisableAddToCompareListButton = !catalogSettings.CompareProductsEnabled; switch (associatedProducts.Count) { case 0: { //no associated products } break; default: { //we have at least one associated product //compare products priceModel.DisableAddToCompareListButton = !catalogSettings.CompareProductsEnabled; //priceModel.AvailableForPreOrder = false; if (permissionService.Authorize(StandardPermissionProvider.DisplayPrices)) { //find a minimum possible price decimal?minPossiblePrice = null; Product minPriceProduct = null; foreach (var associatedProduct in associatedProducts) { //calculate for the maximum quantity (in case if we have tier prices) var tmpPrice = priceCalculationService.GetFinalPrice(associatedProduct, workContext.CurrentCustomer, decimal.Zero, true, int.MaxValue); if (!minPossiblePrice.HasValue || tmpPrice < minPossiblePrice.Value) { minPriceProduct = associatedProduct; minPossiblePrice = tmpPrice; } } if (minPriceProduct != null && !minPriceProduct.CustomerEntersPrice) { if (minPriceProduct.CallForPrice) { priceModel.OldPrice = null; priceModel.Price = localizationService.GetResource("Products.CallForPrice"); } else if (minPossiblePrice.HasValue) { //calculate prices decimal taxRate; decimal finalPriceBase = taxService.GetProductPrice(minPriceProduct, minPossiblePrice.Value, out taxRate); decimal finalPrice = currencyService.ConvertFromPrimaryStoreCurrency(finalPriceBase, workContext.WorkingCurrency); priceModel.OldPrice = null; priceModel.Price = String.Format(localizationService.GetResource("Products.PriceRangeFrom"), priceFormatter.FormatPrice(finalPrice)); priceModel.PriceValue = finalPrice; } else { //Actually it's not possible (we presume that minimalPrice always has a value) //We never should get here Debug.WriteLine("Cannot calculate minPrice for product #{0}", product.Id); } } } else { //hide prices priceModel.OldPrice = null; priceModel.Price = null; } } break; } #endregion } break; case ProductType.SimpleProduct: default: { #region Simple product //add to cart button priceModel.DisableBuyButton = product.DisableBuyButton || !permissionService.Authorize(StandardPermissionProvider.EnableShoppingCart) || !permissionService.Authorize(StandardPermissionProvider.DisplayPrices); //add to wishlist button priceModel.DisableWishlistButton = product.DisableWishlistButton || !permissionService.Authorize(StandardPermissionProvider.EnableWishlist) || !permissionService.Authorize(StandardPermissionProvider.DisplayPrices); //compare products priceModel.DisableAddToCompareListButton = !catalogSettings.CompareProductsEnabled; //rental priceModel.IsRental = product.IsRental; //pre-order if (product.AvailableForPreOrder) { priceModel.AvailableForPreOrder = !product.PreOrderAvailabilityStartDateTimeUtc.HasValue || product.PreOrderAvailabilityStartDateTimeUtc.Value >= DateTime.UtcNow; priceModel.PreOrderAvailabilityStartDateTimeUtc = product.PreOrderAvailabilityStartDateTimeUtc; } //prices if (permissionService.Authorize(StandardPermissionProvider.DisplayPrices)) { if (!product.CustomerEntersPrice) { if (product.CallForPrice) { //call for price priceModel.OldPrice = null; priceModel.Price = localizationService.GetResource("Products.CallForPrice"); } else { //prices //calculate for the maximum quantity (in case if we have tier prices) decimal minPossiblePrice = priceCalculationService.GetFinalPrice(product, workContext.CurrentCustomer, decimal.Zero, true, int.MaxValue); decimal taxRate; decimal oldPriceBase = taxService.GetProductPrice(product, product.OldPrice, out taxRate); decimal finalPriceBase = taxService.GetProductPrice(product, minPossiblePrice, out taxRate); decimal oldPrice = currencyService.ConvertFromPrimaryStoreCurrency(oldPriceBase, workContext.WorkingCurrency); decimal finalPrice = currencyService.ConvertFromPrimaryStoreCurrency(finalPriceBase, workContext.WorkingCurrency); //do we have tier prices configured? var tierPrices = new List <TierPrice>(); if (product.HasTierPrices) { tierPrices.AddRange(product.TierPrices .OrderBy(tp => tp.Quantity) .ToList() .FilterByStore(storeContext.CurrentStore.Id) .FilterForCustomer(workContext.CurrentCustomer) .RemoveDuplicatedQuantities()); } //When there is just one tier (with qty 1), //there are no actual savings in the list. bool displayFromMessage = tierPrices.Count > 0 && !(tierPrices.Count == 1 && tierPrices[0].Quantity <= 1); if (displayFromMessage) { priceModel.OldPrice = null; priceModel.Price = String.Format(localizationService.GetResource("Products.PriceRangeFrom"), priceFormatter.FormatPrice(finalPrice)); priceModel.PriceValue = finalPrice; } else { if (finalPriceBase != oldPriceBase && oldPriceBase != decimal.Zero) { priceModel.OldPrice = priceFormatter.FormatPrice(oldPrice); priceModel.Price = priceFormatter.FormatPrice(finalPrice); priceModel.PriceValue = finalPrice; } else { priceModel.OldPrice = null; priceModel.Price = priceFormatter.FormatPrice(finalPrice); priceModel.PriceValue = finalPrice; } } if (product.IsRental) { //rental product priceModel.OldPrice = priceFormatter.FormatRentalProductPeriod(product, priceModel.OldPrice); priceModel.Price = priceFormatter.FormatRentalProductPeriod(product, priceModel.Price); } //property for German market //we display tax/shipping info only with "shipping enabled" for this product //we also ensure this it's not free shipping priceModel.DisplayTaxShippingInfo = catalogSettings.DisplayTaxShippingInfoProductBoxes && product.IsShipEnabled && !product.IsFreeShipping; } } } else { //hide prices priceModel.OldPrice = null; priceModel.Price = null; } #endregion } break; } model.ProductPrice = priceModel; #endregion } //picture if (preparePictureModel) { #region Prepare product picture //If a size has been set in the view, we use it in priority int pictureSize = productThumbPictureSize.HasValue ? productThumbPictureSize.Value : mediaSettings.ProductThumbPictureSize; //prepare picture model var defaultProductPictureCacheKey = string.Format(ModelCacheEventConsumer.PRODUCT_DEFAULTPICTURE_MODEL_KEY, product.Id, pictureSize, true, workContext.WorkingLanguage.Id, webHelper.IsCurrentConnectionSecured(), storeContext.CurrentStore.Id); model.DefaultPictureModel = cacheManager.Get(defaultProductPictureCacheKey, () => { var picture = pictureService.GetPicturesByProductId(product.Id, 1).FirstOrDefault(); var pictureModel = new PictureModel { ImageUrl = pictureService.GetPictureUrl(picture, pictureSize), FullSizeImageUrl = pictureService.GetPictureUrl(picture) }; //"title" attribute pictureModel.Title = (picture != null && !string.IsNullOrEmpty(picture.TitleAttribute)) ? picture.TitleAttribute : string.Format(localizationService.GetResource("Media.Product.ImageLinkTitleFormat"), model.Name); //"alt" attribute pictureModel.AlternateText = (picture != null && !string.IsNullOrEmpty(picture.AltAttribute)) ? picture.AltAttribute : string.Format(localizationService.GetResource("Media.Product.ImageAlternateTextFormat"), model.Name); return(pictureModel); }); #endregion } //specs if (prepareSpecificationAttributes) { model.SpecificationAttributeModels = PrepareProductSpecificationModel(controller, workContext, specificationAttributeService, cacheManager, product); } //reviews model.ReviewOverviewModel = controller.PrepareProductReviewOverviewModel(storeContext, catalogSettings, cacheManager, product); models.Add(model); } return(models); }
protected IEnumerable <ProductOverviewModel> PrepareProductOverviewModels(IEnumerable <Product> products, bool preparePriceModel = true, bool preparePictureModel = true, int?productThumbPictureSize = null, bool prepareSpecificationAttributes = false, bool forceRedirectionAfterAddingToCart = false) { if (products == null) { throw new ArgumentNullException("products"); } var models = new List <ProductOverviewModel>(); foreach (var product in products) { var model = new ProductOverviewModel { Id = product.Id, Name = product.GetLocalized(x => x.Name), ShortDescription = product.GetLocalized(x => x.ShortDescription), FullDescription = product.GetLocalized(x => x.FullDescription), SeName = product.GetSeName(), }; //price if (preparePriceModel) { #region Prepare product price var priceModel = new ProductOverviewModel.ProductPriceModel(); switch (product.ProductType) { case ProductType.GroupedProduct: { #region Grouped product var associatedProducts = _productService.GetAssociatedProducts(product.Id, _storeContext.CurrentStore.Id); switch (associatedProducts.Count) { case 0: { //no associated products priceModel.OldPrice = null; priceModel.Price = null; priceModel.DisableBuyButton = true; priceModel.DisableWishlistButton = true; priceModel.AvailableForPreOrder = false; } break; default: { //we have at least one associated product priceModel.DisableBuyButton = true; priceModel.DisableWishlistButton = true; priceModel.AvailableForPreOrder = false; if (_permissionService.Authorize(StandardPermissionProvider.DisplayPrices)) { //find a minimum possible price decimal?minPossiblePrice = null; Product minPriceProduct = null; foreach (var associatedProduct in associatedProducts) { //calculate for the maximum quantity (in case if we have tier prices) var tmpPrice = _priceCalculationService.GetFinalPrice(associatedProduct, _workContext.CurrentCustomer, decimal.Zero, true, int.MaxValue); if (!minPossiblePrice.HasValue || tmpPrice < minPossiblePrice.Value) { minPriceProduct = associatedProduct; minPossiblePrice = tmpPrice; } } if (minPriceProduct != null && !minPriceProduct.CustomerEntersPrice) { if (minPriceProduct.CallForPrice) { priceModel.OldPrice = null; priceModel.Price = _localizationService.GetResource("Products.CallForPrice"); } else if (minPossiblePrice.HasValue) { //calculate prices decimal taxRate; decimal finalPriceBase = _taxService.GetProductPrice(minPriceProduct, minPossiblePrice.Value, out taxRate); decimal finalPrice = _currencyService.ConvertFromPrimaryStoreCurrency(finalPriceBase, _workContext.WorkingCurrency); priceModel.OldPrice = null; priceModel.Price = String.Format(_localizationService.GetResource("Products.PriceRangeFrom"), _priceFormatter.FormatPrice(finalPrice)); } else { //Actually it's not possible (we presume that minimalPrice always has a value) //We never should get here Debug.WriteLine("Cannot calculate minPrice for product #{0}", product.Id); } } } else { //hide prices priceModel.OldPrice = null; priceModel.Price = null; } } break; } #endregion } break; default: { #region Simple product //add to cart button priceModel.DisableBuyButton = product.DisableBuyButton || !_permissionService.Authorize(StandardPermissionProvider.EnableShoppingCart) || !_permissionService.Authorize(StandardPermissionProvider.DisplayPrices); //add to wishlist button priceModel.DisableWishlistButton = product.DisableWishlistButton || !_permissionService.Authorize(StandardPermissionProvider.EnableWishlist) || !_permissionService.Authorize(StandardPermissionProvider.DisplayPrices); //rental priceModel.IsRental = product.IsRental; //pre-order if (product.AvailableForPreOrder) { priceModel.AvailableForPreOrder = !product.PreOrderAvailabilityStartDateTimeUtc.HasValue || product.PreOrderAvailabilityStartDateTimeUtc.Value >= DateTime.UtcNow; priceModel.PreOrderAvailabilityStartDateTimeUtc = product.PreOrderAvailabilityStartDateTimeUtc; } //prices if (_permissionService.Authorize(StandardPermissionProvider.DisplayPrices)) { if (!product.CustomerEntersPrice) { if (product.CallForPrice) { //call for price priceModel.OldPrice = null; priceModel.Price = _localizationService.GetResource("Products.CallForPrice"); } else { //prices //calculate for the maximum quantity (in case if we have tier prices) decimal minPossiblePrice = _priceCalculationService.GetFinalPrice(product, _workContext.CurrentCustomer, decimal.Zero, true, int.MaxValue); decimal taxRate; decimal oldPriceBase = _taxService.GetProductPrice(product, product.OldPrice, out taxRate); decimal finalPriceBase = _taxService.GetProductPrice(product, minPossiblePrice, out taxRate); decimal oldPrice = _currencyService.ConvertFromPrimaryStoreCurrency(oldPriceBase, _workContext.WorkingCurrency); decimal finalPrice = _currencyService.ConvertFromPrimaryStoreCurrency(finalPriceBase, _workContext.WorkingCurrency); //do we have tier prices configured? var tierPrices = new List <TierPrice>(); if (product.HasTierPrices) { tierPrices.AddRange(product.TierPrices .OrderBy(tp => tp.Quantity) .ToList() .FilterByStore(_storeContext.CurrentStore.Id) .FilterForCustomer(_workContext.CurrentCustomer) .RemoveDuplicatedQuantities()); } //When there is just one tier (with qty 1), //there are no actual savings in the list. bool displayFromMessage = tierPrices.Count > 0 && !(tierPrices.Count == 1 && tierPrices[0].Quantity <= 1); if (displayFromMessage) { priceModel.OldPrice = null; priceModel.Price = String.Format(_localizationService.GetResource("Products.PriceRangeFrom"), _priceFormatter.FormatPrice(finalPrice)); } else { if (finalPriceBase != oldPriceBase && oldPriceBase != decimal.Zero) { priceModel.OldPrice = _priceFormatter.FormatPrice(oldPrice); priceModel.Price = _priceFormatter.FormatPrice(finalPrice); } else { priceModel.OldPrice = null; priceModel.Price = _priceFormatter.FormatPrice(finalPrice); } } if (product.IsRental) { //rental product priceModel.OldPrice = _priceFormatter.FormatRentalProductPeriod(product, priceModel.OldPrice); priceModel.Price = _priceFormatter.FormatRentalProductPeriod(product, priceModel.Price); } } } } else { //hide prices priceModel.OldPrice = null; priceModel.Price = null; } #endregion } break; } model.ProductPrice = priceModel; #endregion } //picture if (preparePictureModel) { #region Prepare product picture //If a size has been set in the view, we use it in priority int pictureSize = productThumbPictureSize.HasValue ? productThumbPictureSize.Value : 125; //prepare picture model var picture = _pictureService.GetPicturesByProductId(product.Id, 1).FirstOrDefault(); model.DefaultPictureModel = new PictureModel { ImageUrl = _pictureService.GetPictureUrl(picture, pictureSize), FullSizeImageUrl = _pictureService.GetPictureUrl(picture) }; //"title" attribute model.DefaultPictureModel.Title = (picture != null && !string.IsNullOrEmpty(picture.TitleAttribute)) ? picture.TitleAttribute : string.Format(_localizationService.GetResource("Media.Product.ImageLinkTitleFormat"), model.Name); //"alt" attribute model.DefaultPictureModel.AlternateText = (picture != null && !string.IsNullOrEmpty(picture.AltAttribute)) ? picture.AltAttribute : string.Format(_localizationService.GetResource("Media.Product.ImageAlternateTextFormat"), model.Name); #endregion } models.Add(model); } return(models); }
/// <summary> /// Print product collection to PDF /// </summary> /// <param name="stream">Stream</param> /// <param name="products">Products</param> public virtual void PrintProductsToPdf(Stream stream, IList <Product> products) { if (stream == null) { throw new ArgumentNullException("stream"); } if (products == null) { throw new ArgumentNullException("products"); } var lang = _workContext.WorkingLanguage; var pageSize = PageSize.A4; if (_pdfSettings.LetterPageSizeEnabled) { pageSize = PageSize.LETTER; } var doc = new Document(pageSize); PdfWriter.GetInstance(doc, stream); doc.Open(); //fonts var titleFont = GetFont(); titleFont.SetStyle(Font.BOLD); titleFont.Color = BaseColor.BLACK; var font = GetFont(); int productNumber = 1; int prodCount = products.Count; foreach (var product in products) { string productName = product.GetLocalized(x => x.Name, lang.Id); string productDescription = product.GetLocalized(x => x.FullDescription, lang.Id); var productTable = new PdfPTable(1); productTable.WidthPercentage = 100f; productTable.DefaultCell.Border = Rectangle.NO_BORDER; if (lang.Rtl) { productTable.RunDirection = PdfWriter.RUN_DIRECTION_RTL; } productTable.AddCell(new Paragraph(String.Format("{0}. {1}", productNumber, productName), titleFont)); productTable.AddCell(new Paragraph(" ")); productTable.AddCell(new Paragraph(HtmlHelper.StripTags(HtmlHelper.ConvertHtmlToPlainText(productDescription, decode: true)), font)); productTable.AddCell(new Paragraph(" ")); if (product.ProductType == ProductType.SimpleProduct) { //simple product //render its properties such as price, weight, etc var priceStr = string.Format("{0} {1}", product.Price.ToString("0.00"), _currencyService.GetCurrencyById(_currencySettings.PrimaryStoreCurrencyId).CurrencyCode); if (product.IsRental) { priceStr = _priceFormatter.FormatRentalProductPeriod(product, priceStr); } productTable.AddCell(new Paragraph(String.Format("{0}: {1}", _localizationService.GetResource("PDFProductCatalog.Price", lang.Id), priceStr), font)); productTable.AddCell(new Paragraph(String.Format("{0}: {1}", _localizationService.GetResource("PDFProductCatalog.SKU", lang.Id), product.Sku), font)); if (product.IsShipEnabled && product.Weight > Decimal.Zero) { productTable.AddCell(new Paragraph(String.Format("{0}: {1} {2}", _localizationService.GetResource("PDFProductCatalog.Weight", lang.Id), product.Weight.ToString("0.00"), _measureService.GetMeasureWeightById(_measureSettings.BaseWeightId).Name), font)); } if (product.ManageInventoryMethod == ManageInventoryMethod.ManageStock) { productTable.AddCell(new Paragraph(String.Format("{0}: {1}", _localizationService.GetResource("PDFProductCatalog.StockQuantity", lang.Id), product.GetTotalStockQuantity()), font)); } productTable.AddCell(new Paragraph(" ")); } var pictures = _pictureService.GetPicturesByProductId(product.Id); if (pictures.Count > 0) { var table = new PdfPTable(2); table.WidthPercentage = 100f; if (lang.Rtl) { table.RunDirection = PdfWriter.RUN_DIRECTION_RTL; } foreach (var pic in pictures) { var picBinary = _pictureService.LoadPictureBinary(pic); if (picBinary != null && picBinary.Length > 0) { var pictureLocalPath = _pictureService.GetThumbLocalPath(pic, 200, false); var cell = new PdfPCell(Image.GetInstance(pictureLocalPath)); cell.HorizontalAlignment = Element.ALIGN_LEFT; cell.Border = Rectangle.NO_BORDER; table.AddCell(cell); } } if (pictures.Count % 2 > 0) { var cell = new PdfPCell(new Phrase(" ")); cell.Border = Rectangle.NO_BORDER; table.AddCell(cell); } productTable.AddCell(table); productTable.AddCell(new Paragraph(" ")); } if (product.ProductType == ProductType.GroupedProduct) { //grouped product. render its associated products int pvNum = 1; foreach (var associatedProduct in _productService.GetAssociatedProducts(product.Id, showHidden: true)) { productTable.AddCell(new Paragraph(String.Format("{0}-{1}. {2}", productNumber, pvNum, associatedProduct.GetLocalized(x => x.Name, lang.Id)), font)); productTable.AddCell(new Paragraph(" ")); //uncomment to render associated product description //string apDescription = associatedProduct.GetLocalized(x => x.ShortDescription, lang.Id); //if (!String.IsNullOrEmpty(apDescription)) //{ // productTable.AddCell(new Paragraph(HtmlHelper.StripTags(HtmlHelper.ConvertHtmlToPlainText(apDescription)), font)); // productTable.AddCell(new Paragraph(" ")); //} //uncomment to render associated product picture //var apPicture = _pictureService.GetPicturesByProductId(associatedProduct.Id).FirstOrDefault(); //if (apPicture != null) //{ // var picBinary = _pictureService.LoadPictureBinary(apPicture); // if (picBinary != null && picBinary.Length > 0) // { // var pictureLocalPath = _pictureService.GetThumbLocalPath(apPicture, 200, false); // productTable.AddCell(Image.GetInstance(pictureLocalPath)); // } //} productTable.AddCell(new Paragraph(String.Format("{0}: {1} {2}", _localizationService.GetResource("PDFProductCatalog.Price", lang.Id), associatedProduct.Price.ToString("0.00"), _currencyService.GetCurrencyById(_currencySettings.PrimaryStoreCurrencyId).CurrencyCode), font)); productTable.AddCell(new Paragraph(String.Format("{0}: {1}", _localizationService.GetResource("PDFProductCatalog.SKU", lang.Id), associatedProduct.Sku), font)); if (associatedProduct.IsShipEnabled && associatedProduct.Weight > Decimal.Zero) { productTable.AddCell(new Paragraph(String.Format("{0}: {1} {2}", _localizationService.GetResource("PDFProductCatalog.Weight", lang.Id), associatedProduct.Weight.ToString("0.00"), _measureService.GetMeasureWeightById(_measureSettings.BaseWeightId).Name), font)); } if (associatedProduct.ManageInventoryMethod == ManageInventoryMethod.ManageStock) { productTable.AddCell(new Paragraph(String.Format("{0}: {1}", _localizationService.GetResource("PDFProductCatalog.StockQuantity", lang.Id), associatedProduct.GetTotalStockQuantity()), font)); } productTable.AddCell(new Paragraph(" ")); pvNum++; } } doc.Add(productTable); productNumber++; if (productNumber <= prodCount) { doc.NewPage(); } } doc.Close(); }
protected virtual ProductDetailsDto PrepareProductDetailsPageDto(Product product, ShoppingCartItem updatecartitem = null, bool isAssociatedProduct = false) { if (product == null) { throw new ArgumentNullException("product"); } #region Standard properties var model = new ProductDetailsDto { Id = product.Id, Name = product.Name, ShortDescription = product.ShortDescription, FullDescription = product.FullDescription, MetaKeywords = product.MetaKeywords, MetaDescription = product.MetaDescription, MetaTitle = product.MetaTitle, //SeName = product.GetSeName(), ShowSku = CatalogSettings.ShowProductSku, Sku = product.Sku, ShowManufacturerPartNumber = CatalogSettings.ShowManufacturerPartNumber, FreeShippingNotificationEnabled = CatalogSettings.ShowFreeShippingNotification, ManufacturerPartNumber = product.ManufacturerPartNumber, ShowGtin = CatalogSettings.ShowGtin, Gtin = product.Gtin, StockAvailability = product.FormatStockMessage("", _productAttributeParser), HasSampleDownload = product.IsDownload && product.HasSampleDownload, DisplayDiscontinuedMessage = !product.Published && CatalogSettings.DisplayDiscontinuedMessageForUnpublishedProducts }; //automatically generate product description? if (SeoSettings.GenerateProductMetaDescription && String.IsNullOrEmpty(model.MetaDescription)) { //based on short description model.MetaDescription = model.ShortDescription; } //shipping info model.IsShipEnabled = product.IsShipEnabled; if (product.IsShipEnabled) { model.IsFreeShipping = product.IsFreeShipping; //delivery date var deliveryDate = _shippingDomainServie.GetDeliveryDateById(product.DeliveryDateId); if (deliveryDate != null) { //model.DeliveryDate = deliveryDate.GetLocalized(dd => dd.Name); model.DeliveryDate = deliveryDate.Name; } } //email a friend model.EmailAFriendEnabled = CatalogSettings.EmailAFriendEnabled; //compare products model.CompareProductsEnabled = CatalogSettings.CompareProductsEnabled; #endregion #region Vendor details //vendor //if (_vendorSettings.ShowVendorOnProductDetailsPage) { var vendor = _vendorDomainService.GetVendorById(product.VendorId); if (vendor != null && !vendor.Deleted && vendor.Active) { model.ShowVendor = true; model.VendorDto = Mapper.Map <VendorBriefInfoDto>(vendor); //model.VendorModel = new VendorBriefInfoDto //{ // Id = vendor.Id, // Name = vendor.GetLocalized(x => x.Name), // SeName = vendor.GetSeName(), //}; } } #endregion #region Page sharing //if (_catalogSettings.ShowShareButton && !String.IsNullOrEmpty(_catalogSettings.PageShareCode)) //{ // var shareCode = _catalogSettings.PageShareCode; // if (_webHelper.IsCurrentConnectionSecured()) // { // //need to change the addthis link to be https linked when the page is, so that the page doesnt ask about mixed mode when viewed in https... // shareCode = shareCode.Replace("http://", "https://"); // } // model.PageShareCode = shareCode; //} #endregion #region Back in stock subscriptions if (product.ManageInventoryMethod == ManageInventoryMethod.ManageStock && product.BackorderMode == BackorderMode.NoBackorders && product.AllowBackInStockSubscriptions && product.GetTotalStockQuantity() <= 0) { //out of stock model.DisplayBackInStockSubscription = true; } #endregion #region Breadcrumb //do not prepare this model for the associated products. anyway it's not used //if (_catalogSettings.CategoryBreadcrumbEnabled && !isAssociatedProduct) //{ // var breadcrumbCacheKey = string.Format(ModelCacheEventConsumer.PRODUCT_BREADCRUMB_MODEL_KEY, // product.Id, // _workContext.WorkingLanguage.Id, // string.Join(",", _workContext.CurrentCustomer.GetCustomerRoleIds()), // _storeContext.CurrentStore.Id); // model.Breadcrumb = _cacheManager.Get(breadcrumbCacheKey, () => // { // var breadcrumbModel = new ProductDetailsModel.ProductBreadcrumbModel // { // Enabled = _catalogSettings.CategoryBreadcrumbEnabled, // ProductId = product.Id, // ProductName = product.GetLocalized(x => x.Name), // ProductSeName = product.GetSeName() // }; // var productCategories = _categoryService.GetProductCategoriesByProductId(product.Id); // if (productCategories.Count > 0) // { // var category = productCategories[0].Category; // if (category != null) // { // foreach ( // var catBr in // category.GetCategoryBreadCrumb(_categoryService, _aclService, _storeMappingService)) // { // breadcrumbModel.CategoryBreadcrumb.Add(new CategorySimpleModel // { // Id = catBr.Id, // Name = catBr.GetLocalized(x => x.Name), // SeName = catBr.GetSeName(), // IncludeInTopMenu = catBr.IncludeInTopMenu // }); // } // } // } // return breadcrumbModel; // }); //} #endregion #region Product tags //do not prepare this model for the associated products. anyway it's not used //if (!isAssociatedProduct) //{ // var productTagsCacheKey = string.Format(ModelCacheEventConsumer.PRODUCTTAG_BY_PRODUCT_MODEL_KEY, product.Id, _workContext.WorkingLanguage.Id, _storeContext.CurrentStore.Id); // model.ProductTags = _cacheManager.Get(productTagsCacheKey, () => // product.ProductTags // //filter by store // .Where(x => _productTagService.GetProductCount(x.Id, _storeContext.CurrentStore.Id) > 0) // .Select(x => new ProductTagDto // { // Id = x.Id, // Name = x.GetLocalized(y => y.Name), // SeName = x.GetSeName(), // ProductCount = _productTagService.GetProductCount(x.Id, _storeContext.CurrentStore.Id) // }) // .ToList()); //} #endregion #region Templates //var templateCacheKey = string.Format(ModelCacheEventConsumer.PRODUCT_TEMPLATE_MODEL_KEY, product.ProductTemplateId); //model.ProductTemplateViewPath = _cacheManager.Get(templateCacheKey, () => //{ var template = _productTemplateService.GetProductTemplateById(product.ProductTemplateId); if (template == null) { template = _productTemplateService.GetAllProductTemplates().FirstOrDefault(); } if (template == null) { throw new Exception("No default template could be loaded"); } //return template.ViewPath; model.ProductTemplateViewPath = template.ViewPath; //}); #endregion #region Pictures model.DefaultPictureZoomEnabled = MediaSettings.DefaultPictureZoomEnabled; //default picture var defaultPictureSize = isAssociatedProduct ? MediaSettings.AssociatedProductPictureSize : MediaSettings.ProductDetailsPictureSize; //prepare picture models //var productPicturesCacheKey = string.Format(ModelCacheEventConsumer.PRODUCT_DETAILS_PICTURES_MODEL_KEY, product.Id, defaultPictureSize, isAssociatedProduct, _workContext.WorkingLanguage.Id, _webHelper.IsCurrentConnectionSecured(), _storeContext.CurrentStore.Id); //var cachedPictures = _cacheManager.Get(productPicturesCacheKey, () => //{ var pictures = _pictureDomainService.GetPicturesByProductId(product.Id); var defaultPicture = pictures.FirstOrDefault(); var defaultPictureModel = new PictureDto { ImageUrl = _pictureDomainService.GetPictureUrl(defaultPicture, defaultPictureSize, !isAssociatedProduct), FullSizeImageUrl = _pictureDomainService.GetPictureUrl(defaultPicture, 0, !isAssociatedProduct), Title = string.Format(InfoMsg.Media_Product_ImageLinkTitleFormat_Details, model.Name), AlternateText = string.Format(InfoMsg.Media_Product_ImageAlternateTextFormat_Details, model.Name), }; //"title" attribute defaultPictureModel.Title = (defaultPicture != null && !string.IsNullOrEmpty(defaultPicture.TitleAttribute)) ? defaultPicture.TitleAttribute : string.Format(InfoMsg.Media_Product_ImageLinkTitleFormat_Details, model.Name); //"alt" attribute defaultPictureModel.AlternateText = (defaultPicture != null && !string.IsNullOrEmpty(defaultPicture.AltAttribute)) ? defaultPicture.AltAttribute : string.Format(InfoMsg.Media_Product_ImageAlternateTextFormat_Details, model.Name); //all pictures var pictureModels = new List <PictureDto>(); foreach (var picture in pictures) { var pictureModel = new PictureDto { ImageUrl = _pictureDomainService.GetPictureUrl(picture, MediaSettings.ProductThumbPictureSizeOnProductDetailsPage), FullSizeImageUrl = _pictureDomainService.GetPictureUrl(picture), Title = string.Format(InfoMsg.Media_Product_ImageLinkTitleFormat_Details, model.Name), AlternateText = string.Format(InfoMsg.Media_Product_ImageAlternateTextFormat_Details, model.Name), }; //"title" attribute pictureModel.Title = !string.IsNullOrEmpty(picture.TitleAttribute) ? picture.TitleAttribute : string.Format(InfoMsg.Media_Product_ImageLinkTitleFormat_Details, model.Name); //"alt" attribute pictureModel.AlternateText = !string.IsNullOrEmpty(picture.AltAttribute) ? picture.AltAttribute : string.Format(InfoMsg.Media_Product_ImageAlternateTextFormat_Details, model.Name); pictureModels.Add(pictureModel); } //return new { DefaultPictureModel = defaultPictureModel, PictureModels = pictureModels }; var cachedPictures = new { DefaultPictureModel = defaultPictureModel, PictureModels = pictureModels }; //}); model.DefaultPictureModel = cachedPictures.DefaultPictureModel; model.PictureModels = cachedPictures.PictureModels; #endregion #region Product price model.ProductPrice.ProductId = product.Id; //if (_permissionService.Authorize(StandardPermissionProvider.DisplayPrices)) { model.ProductPrice.HidePrices = false; if (product.CustomerEntersPrice) { model.ProductPrice.CustomerEntersPrice = true; } else { if (product.CallForPrice) { model.ProductPrice.CallForPrice = true; } else { decimal taxRate; decimal oldPriceBase = _taxDomainService.GetProductPrice(product, product.OldPrice, CurrentUser, out taxRate); decimal finalPriceWithoutDiscountBase = _taxDomainService.GetProductPrice(product, _priceCalculationDomainService.GetFinalPrice(product, CurrentUser, includeDiscounts: false), CurrentUser, out taxRate); decimal finalPriceWithDiscountBase = _taxDomainService.GetProductPrice(product, _priceCalculationDomainService.GetFinalPrice(product, CurrentUser, includeDiscounts: true), CurrentUser, out taxRate); decimal oldPrice = _currencyDomainService.ConvertFromPrimaryStoreCurrency(oldPriceBase, WorkingCurrency); decimal finalPriceWithoutDiscount = _currencyDomainService.ConvertFromPrimaryStoreCurrency(finalPriceWithoutDiscountBase, WorkingCurrency); decimal finalPriceWithDiscount = _currencyDomainService.ConvertFromPrimaryStoreCurrency(finalPriceWithDiscountBase, WorkingCurrency); if (finalPriceWithoutDiscountBase != oldPriceBase && oldPriceBase > decimal.Zero) { model.ProductPrice.OldPrice = _priceFormatter.FormatPrice(oldPrice, true, WorkingCurrency); } model.ProductPrice.Price = _priceFormatter.FormatPrice(finalPriceWithoutDiscount, true, WorkingCurrency); if (finalPriceWithoutDiscountBase != finalPriceWithDiscountBase) { model.ProductPrice.PriceWithDiscount = _priceFormatter.FormatPrice(finalPriceWithDiscount, true, WorkingCurrency); } model.ProductPrice.PriceValue = finalPriceWithDiscount; //property for German market //we display tax/shipping info only with "shipping enabled" for this product //we also ensure this it's not free shipping model.ProductPrice.DisplayTaxShippingInfo = CatalogSettings.DisplayTaxShippingInfoProductDetailsPage && product.IsShipEnabled && !product.IsFreeShipping; //PAngV baseprice (used in Germany) //model.ProductPrice.BasePricePAngV = product.FormatBasePrice(finalPriceWithDiscountBase, // _localizationService, _measureService, _currencyService, _workContext, _priceFormatter); //currency code model.ProductPrice.CurrencyCode = WorkingCurrency.CurrencyCode; //rental if (product.IsRental) { model.ProductPrice.IsRental = true; var priceStr = _priceFormatter.FormatPrice(finalPriceWithDiscount, true, WorkingCurrency); model.ProductPrice.RentalPrice = _priceFormatter.FormatRentalProductPeriod(product, priceStr); } } } } //else //{ // model.ProductPrice.HidePrices = true; // model.ProductPrice.OldPrice = null; // model.ProductPrice.Price = null; //} #endregion #region 'Add to cart' model model.AddToCart.ProductId = product.Id; model.AddToCart.UpdatedShoppingCartItemId = updatecartitem != null ? updatecartitem.Id : 0; //quantity model.AddToCart.EnteredQuantity = updatecartitem != null ? updatecartitem.Quantity : product.OrderMinimumQuantity; //allowed quantities var allowedQuantities = product.ParseAllowedQuantities(); foreach (var qty in allowedQuantities) { //model.AddToCart.AllowedQuantities.Add(new SelectListItem //{ // Text = qty.ToString(), // Value = qty.ToString(), // Selected = updatecartitem != null && updatecartitem.Quantity == qty //}); model.AddToCart.AllowedQuantities.Add(qty); } //minimum quantity notification if (product.OrderMinimumQuantity > 1) { model.AddToCart.MinimumQuantityNotification = string.Format(InfoMsg.Products_MinimumQuantityNotification, product.OrderMinimumQuantity); } //'add to cart', 'add to wishlist' buttons model.AddToCart.DisableBuyButton = product.DisableBuyButton; //|| !_permissionService.Authorize(StandardPermissionProvider.EnableShoppingCart); model.AddToCart.DisableWishlistButton = product.DisableWishlistButton; //|| !_permissionService.Authorize(StandardPermissionProvider.EnableWishlist); //if (!_permissionService.Authorize(StandardPermissionProvider.DisplayPrices)) //{ // model.AddToCart.DisableBuyButton = true; // model.AddToCart.DisableWishlistButton = true; //} //pre-order if (product.AvailableForPreOrder) { model.AddToCart.AvailableForPreOrder = !product.PreOrderAvailabilityStartDateTimeUtc.HasValue || product.PreOrderAvailabilityStartDateTimeUtc.Value >= DateTime.UtcNow; model.AddToCart.PreOrderAvailabilityStartDateTimeUtc = product.PreOrderAvailabilityStartDateTimeUtc; } //rental model.AddToCart.IsRental = product.IsRental; //customer entered price model.AddToCart.CustomerEntersPrice = product.CustomerEntersPrice; if (model.AddToCart.CustomerEntersPrice) { decimal minimumCustomerEnteredPrice = _currencyDomainService.ConvertFromPrimaryStoreCurrency(product.MinimumCustomerEnteredPrice, WorkingCurrency); decimal maximumCustomerEnteredPrice = _currencyDomainService.ConvertFromPrimaryStoreCurrency(product.MaximumCustomerEnteredPrice, WorkingCurrency); model.AddToCart.CustomerEnteredPrice = updatecartitem != null ? updatecartitem.CustomerEnteredPrice : minimumCustomerEnteredPrice; model.AddToCart.CustomerEnteredPriceRange = string.Format(InfoMsg.Products_EnterProductPrice_Range, _priceFormatter.FormatPrice(minimumCustomerEnteredPrice, false, false, WorkingCurrency), _priceFormatter.FormatPrice(maximumCustomerEnteredPrice, false, false, WorkingCurrency)); } #endregion #region Gift card model.GiftCard.IsGiftCard = product.IsGiftCard; if (model.GiftCard.IsGiftCard) { model.GiftCard.GiftCardType = product.GiftCardType; if (updatecartitem == null) { model.GiftCard.SenderName = CurrentUser.FullName; model.GiftCard.SenderEmail = CurrentUser.EmailAddress; } else { string giftCardRecipientName, giftCardRecipientEmail, giftCardSenderName, giftCardSenderEmail, giftCardMessage; _productAttributeParser.GetGiftCardAttribute(updatecartitem.AttributesXml, out giftCardRecipientName, out giftCardRecipientEmail, out giftCardSenderName, out giftCardSenderEmail, out giftCardMessage); model.GiftCard.RecipientName = giftCardRecipientName; model.GiftCard.RecipientEmail = giftCardRecipientEmail; model.GiftCard.SenderName = giftCardSenderName; model.GiftCard.SenderEmail = giftCardSenderEmail; model.GiftCard.Message = giftCardMessage; } } #endregion #region Product attributes //performance optimization //We cache a value indicating whether a product has attributes IList <ProductAttributeMapping> productAttributeMapping = null; // string cacheKey = string.Format(ModelCacheEventConsumer.PRODUCT_HAS_PRODUCT_ATTRIBUTES_KEY, product.Id); //var hasProductAttributesCache = _cacheManager.Get<bool?>(cacheKey); //if (!hasProductAttributesCache.HasValue) { //no value in the cache yet //let's load attributes and cache the result (true/false) productAttributeMapping = _productAttributeDomainService.GetProductAttributeMappingsByProductId(product.Id); //hasProductAttributesCache = productAttributeMapping.Count > 0; //_cacheManager.Set(cacheKey, hasProductAttributesCache, 60); } //if (hasProductAttributesCache.Value && productAttributeMapping == null) //{ // //cache indicates that the product has attributes // //let's load them // productAttributeMapping = _productAttributeService.GetProductAttributeMappingsByProductId(product.Id); //} if (productAttributeMapping == null) { productAttributeMapping = new List <ProductAttributeMapping>(); } foreach (var attribute in productAttributeMapping) { var attributeModel = new ProductDetailsDto.ProductAttributeDto { Id = attribute.Id, ProductId = product.Id, ProductAttributeId = attribute.ProductAttributeId, Name = attribute.ProductAttribute.Name, Description = attribute.ProductAttribute.Description, TextPrompt = attribute.TextPrompt, IsRequired = attribute.IsRequired, AttributeControlType = attribute.AttributeControlType, DefaultValue = updatecartitem != null ? null : attribute.DefaultValue, HasCondition = !String.IsNullOrEmpty(attribute.ConditionAttributeXml) }; if (!String.IsNullOrEmpty(attribute.ValidationFileAllowedExtensions)) { attributeModel.AllowedFileExtensions = attribute.ValidationFileAllowedExtensions .Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries) .ToList(); } if (attribute.ShouldHaveValues()) { //values var attributeValues = _productAttributeDomainService.GetProductAttributeValues(attribute.Id); foreach (var attributeValue in attributeValues) { var valueModel = new ProductDetailsDto.ProductAttributeValueDto { Id = attributeValue.Id, Name = attributeValue.Name, ColorSquaresRgb = attributeValue.ColorSquaresRgb, //used with "Color squares" attribute type IsPreSelected = attributeValue.IsPreSelected }; attributeModel.Values.Add(valueModel); //display price if allowed //if (_permissionService.Authorize(StandardPermissionProvider.DisplayPrices)) { decimal taxRate; decimal attributeValuePriceAdjustment = _priceCalculationDomainService.GetProductAttributeValuePriceAdjustment(attributeValue); decimal priceAdjustmentBase = _taxDomainService.GetProductPrice(product, attributeValuePriceAdjustment, CurrentUser, out taxRate); decimal priceAdjustment = _currencyDomainService.ConvertFromPrimaryStoreCurrency(priceAdjustmentBase, WorkingCurrency); if (priceAdjustmentBase > decimal.Zero) { valueModel.PriceAdjustment = "+" + _priceFormatter.FormatPrice(priceAdjustment, false, false, WorkingCurrency); } else if (priceAdjustmentBase < decimal.Zero) { valueModel.PriceAdjustment = "-" + _priceFormatter.FormatPrice(-priceAdjustment, false, false, WorkingCurrency); } valueModel.PriceAdjustmentValue = priceAdjustment; } //picture if (attributeValue.PictureId > 0) { //var productAttributePictureCacheKey = string.Format(ModelCacheEventConsumer.PRODUCTATTRIBUTE_PICTURE_MODEL_KEY, // attributeValue.PictureId, // _webHelper.IsCurrentConnectionSecured(), // _storeContext.CurrentStore.Id); //valueModel.PictureModel = _cacheManager.Get(productAttributePictureCacheKey, () => //{ var valuePicture = _pictureDomainService.GetPictureById(attributeValue.PictureId); if (valuePicture != null) { valueModel.PictureModel = new PictureDto() { FullSizeImageUrl = _pictureDomainService.GetPictureUrl(valuePicture), ImageUrl = _pictureDomainService.GetPictureUrl(valuePicture, defaultPictureSize) }; } valueModel.PictureModel = new PictureDto(); //}); } } } //set already selected attributes (if we're going to update the existing shopping cart item) if (updatecartitem != null) { switch (attribute.AttributeControlType) { case AttributeControlType.DropdownList: case AttributeControlType.RadioList: case AttributeControlType.Checkboxes: case AttributeControlType.ColorSquares: { if (!String.IsNullOrEmpty(updatecartitem.AttributesXml)) { //clear default selection foreach (var item in attributeModel.Values) { item.IsPreSelected = false; } //select new values var selectedValues = _productAttributeParser.ParseProductAttributeValues(updatecartitem.AttributesXml); foreach (var attributeValue in selectedValues) { foreach (var item in attributeModel.Values) { if (attributeValue.Id == item.Id) { item.IsPreSelected = true; } } } } } break; case AttributeControlType.ReadonlyCheckboxes: { //do nothing //values are already pre-set } break; case AttributeControlType.TextBox: case AttributeControlType.MultilineTextbox: { if (!String.IsNullOrEmpty(updatecartitem.AttributesXml)) { var enteredText = _productAttributeParser.ParseValues(updatecartitem.AttributesXml, attribute.Id); if (enteredText.Count > 0) { attributeModel.DefaultValue = enteredText[0]; } } } break; case AttributeControlType.Datepicker: { //keep in mind my that the code below works only in the current culture var selectedDateStr = _productAttributeParser.ParseValues(updatecartitem.AttributesXml, attribute.Id); if (selectedDateStr.Count > 0) { DateTime selectedDate; if (DateTime.TryParseExact(selectedDateStr[0], "D", CultureInfo.CurrentCulture, DateTimeStyles.None, out selectedDate)) { //successfully parsed attributeModel.SelectedDay = selectedDate.Day; attributeModel.SelectedMonth = selectedDate.Month; attributeModel.SelectedYear = selectedDate.Year; } } } break; case AttributeControlType.FileUpload: { if (!String.IsNullOrEmpty(updatecartitem.AttributesXml)) { var downloadGuidStr = _productAttributeParser.ParseValues(updatecartitem.AttributesXml, attribute.Id).FirstOrDefault(); Guid downloadGuid; Guid.TryParse(downloadGuidStr, out downloadGuid); var download = _downloadDomainService.GetDownloadByGuid(downloadGuid); if (download != null) { attributeModel.DefaultValue = download.DownloadGuid.ToString(); } } } break; default: break; } } model.ProductAttributes.Add(attributeModel); } #endregion #region Product specifications //do not prepare this model for the associated products. any it's not used if (!isAssociatedProduct) { model.ProductSpecifications = this.PrepareProductSpecificationModel( _specificationAttributeDomainService, _cacheManager, product); } #endregion #region Product review overview model.ProductReviewOverview = new ProductReviewOverviewDto { ProductId = product.Id, RatingSum = product.ApprovedRatingSum, TotalReviews = product.ApprovedTotalReviews, AllowCustomerReviews = product.AllowCustomerReviews }; #endregion #region Tier prices //if (product.HasTierPrices && _permissionService.Authorize(StandardPermissionProvider.DisplayPrices)) { model.TierPrices = product.TierPrices .OrderBy(x => x.Quantity) .ToList() .FilterByStore(_storeContext.CurrentStore.Id) .FilterForCustomer(CurrentUser) .RemoveDuplicatedQuantities() .Select(tierPrice => { var m = new ProductDetailsDto.TierPriceDto { Quantity = tierPrice.Quantity, }; decimal taxRate; decimal priceBase = _taxDomainService.GetProductPrice(product, _priceCalculationDomainService.GetFinalPrice(product, CurrentUser, decimal.Zero, CatalogSettings.DisplayTierPricesWithDiscounts, tierPrice.Quantity), CurrentUser, out taxRate); decimal price = _currencyDomainService.ConvertFromPrimaryStoreCurrency(priceBase, WorkingCurrency); m.Price = _priceFormatter.FormatPrice(price, false, false, WorkingCurrency); return(m); }) .ToList(); } #endregion #region Manufacturers //do not prepare this model for the associated products. any it's not used if (!isAssociatedProduct) { //string manufacturersCacheKey = string.Format(ModelCacheEventConsumer.PRODUCT_MANUFACTURERS_MODEL_KEY, // product.Id, // _workContext.WorkingLanguage.Id, // string.Join(",", _workContext.CurrentCustomer.GetCustomerRoleIds()), // _storeContext.CurrentStore.Id); //model.ProductManufacturers = _cacheManager.Get(manufacturersCacheKey, () => // _manufacturerDomainService.GetProductManufacturersByProductId(product.Id) // .Select(x => x.Manufacturer.ToModel()) // .ToList() // ); var manufacturers = _manufacturerDomainService.GetProductManufacturersByProductId(product.Id); model.ProductManufacturers = Mapper.Map <IList <ManufacturerDto> >(manufacturers); } #endregion #region Rental products if (product.IsRental) { model.IsRental = true; //set already entered dates attributes (if we're going to update the existing shopping cart item) if (updatecartitem != null) { model.RentalStartDate = updatecartitem.RentalStartDateUtc; model.RentalEndDate = updatecartitem.RentalEndDateUtc; } } #endregion #region Associated products if (product.ProductType == ProductType.GroupedProduct) { //ensure no circular references if (!isAssociatedProduct) { var associatedProducts = _productDomainService.GetAssociatedProducts(product.Id, _storeContext.CurrentStore.Id); foreach (var associatedProduct in associatedProducts) { model.AssociatedProducts.Add(PrepareProductDetailsPageDto(associatedProduct, null, true)); } } } #endregion return(model); }