/// <summary> /// Formats attributes /// </summary> /// <param name="attributesXml">Attributes in XML format</param> /// <param name="customer">Customer</param> /// <param name="serapator">Serapator</param> /// <param name="htmlEncode">A value indicating whether to encode (HTML) values</param> /// <param name="renderPrices">A value indicating whether to render prices</param> /// <param name="allowHyperlinks">A value indicating whether to HTML hyperink tags could be rendered (if required)</param> /// <returns>Attributes</returns> public virtual string FormatAttributes(string attributesXml, User customer, Currency workingCurrency, string serapator = "<br />", bool htmlEncode = true, bool renderPrices = true, bool allowHyperlinks = true) { var result = new StringBuilder(); var attributes = _checkoutAttributeParser.ParseCheckoutAttributes(attributesXml); for (int i = 0; i < attributes.Count; i++) { var attribute = attributes[i]; var valuesStr = _checkoutAttributeParser.ParseValues(attributesXml, attribute.Id); for (int j = 0; j < valuesStr.Count; j++) { string valueStr = valuesStr[j]; string formattedAttribute = ""; if (!attribute.ShouldHaveValues()) { //no values if (attribute.AttributeControlType == AttributeControlType.MultilineTextbox) { //multiline textbox var attributeName = attribute.Name; //encode (if required) //if (htmlEncode) // attributeName = HttpUtility.HtmlEncode(attributeName); formattedAttribute = string.Format("{0}: {1}", attributeName, HtmlHelper.FormatText(valueStr, false, true, false, false, false, false)); //we never encode multiline textbox input } else if (attribute.AttributeControlType == AttributeControlType.FileUpload) { //file upload Guid downloadGuid; Guid.TryParse(valueStr, out downloadGuid); var download = _downloadService.GetDownloadByGuid(downloadGuid); if (download != null) { //TODO add a method for getting URL (use routing because it handles all SEO friendly URLs) string attributeText; var fileName = string.Format("{0}{1}", download.Filename ?? download.DownloadGuid.ToString(), download.Extension); //encode (if required) //if (htmlEncode) // fileName = HttpUtility.HtmlEncode(fileName); if (allowHyperlinks) { //hyperlinks are allowed //var downloadLink = string.Format("{0}download/getfileupload/?downloadId={1}", _webHelper.GetStoreLocation(false), download.DownloadGuid); var downloadLink = string.Empty; attributeText = string.Format("<a href=\"{0}\" class=\"fileuploadattribute\">{1}</a>", downloadLink, fileName); } else { //hyperlinks aren't allowed attributeText = fileName; } var attributeName = attribute.Name; //encode (if required) //if (htmlEncode) // attributeName = HttpUtility.HtmlEncode(attributeName); formattedAttribute = string.Format("{0}: {1}", attributeName, attributeText); } } else { //other attributes (textbox, datepicker) formattedAttribute = string.Format("{0}: {1}", attribute.Name, valueStr); //encode (if required) //if (htmlEncode) // formattedAttribute = HttpUtility.HtmlEncode(formattedAttribute); } } else { int attributeValueId; if (int.TryParse(valueStr, out attributeValueId)) { var attributeValue = _checkoutAttributeService.GetCheckoutAttributeValueById(attributeValueId); if (attributeValue != null) { formattedAttribute = string.Format("{0}: {1}", attribute.Name, attributeValue.Name); if (renderPrices) { decimal priceAdjustmentBase = _taxService.GetCheckoutAttributePrice(attributeValue, customer); decimal priceAdjustment = _currencyService.ConvertFromPrimaryStoreCurrency(priceAdjustmentBase, workingCurrency); if (priceAdjustmentBase > 0) { string priceAdjustmentStr = _priceFormatter.FormatPrice(priceAdjustment, true, workingCurrency); formattedAttribute += string.Format(" [+{0}]", priceAdjustmentStr); } } } //encode (if required) //if (htmlEncode) // formattedAttribute = HttpUtility.HtmlEncode(formattedAttribute); } } if (!String.IsNullOrEmpty(formattedAttribute)) { if (i != 0 || j != 0) { result.Append(serapator); } result.Append(formattedAttribute); } } } return(result.ToString()); }
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); }