/// <summary> /// Validates shopping cart item (gift card) /// </summary> /// <param name="shoppingCartType">Shopping cart type</param> /// <param name="productVariant">Product variant</param> /// <param name="selectedAttributes">Selected attributes</param> /// <returns>Warnings</returns> public virtual IList <string> GetShoppingCartItemGiftCardWarnings(ShoppingCartType shoppingCartType, ProductVariant productVariant, string selectedAttributes) { if (productVariant == null) { throw new ArgumentNullException("productVariant"); } var warnings = new List <string>(); //gift cards if (productVariant.IsGiftCard) { string giftCardRecipientName = string.Empty; string giftCardRecipientEmail = string.Empty; string giftCardSenderName = string.Empty; string giftCardSenderEmail = string.Empty; string giftCardMessage = string.Empty; _productAttributeParser.GetGiftCardAttribute(selectedAttributes, out giftCardRecipientName, out giftCardRecipientEmail, out giftCardSenderName, out giftCardSenderEmail, out giftCardMessage); if (String.IsNullOrEmpty(giftCardRecipientName)) { warnings.Add(_localizationService.GetResource("ShoppingCart.RecipientNameError")); } if (productVariant.GiftCardType == GiftCardType.Virtual) { //validate for virtual gift cards only if (String.IsNullOrEmpty(giftCardRecipientEmail) || !CommonHelper.IsValidEmail(giftCardRecipientEmail)) { warnings.Add(_localizationService.GetResource("ShoppingCart.RecipientEmailError")); } } if (String.IsNullOrEmpty(giftCardSenderName)) { warnings.Add(_localizationService.GetResource("ShoppingCart.SenderNameError")); } if (productVariant.GiftCardType == GiftCardType.Virtual) { //validate for virtual gift cards only if (String.IsNullOrEmpty(giftCardSenderEmail) || !CommonHelper.IsValidEmail(giftCardSenderEmail)) { warnings.Add(_localizationService.GetResource("ShoppingCart.SenderEmailError")); } } } return(warnings); }
public void CanAddAndParseGiftCardAttributes() { var attributes = string.Empty; attributes = _productAttributeParser.AddGiftCardAttribute(attributes, "recipientName 1", "*****@*****.**", "senderName 1", "*****@*****.**", "custom message"); _productAttributeParser.GetGiftCardAttribute(attributes, out var recipientName, out var recipientEmail, out var senderName, out var senderEmail, out var giftCardMessage); recipientName.Should().Be("recipientName 1"); recipientEmail.Should().Be("*****@*****.**"); senderName.Should().Be("senderName 1"); senderEmail.Should().Be("*****@*****.**"); giftCardMessage.Should().Be("custom message"); }
public void Can_add_and_parse_giftCardAttributes() { var attributes = ""; attributes = _productAttributeParser.AddGiftCardAttribute(attributes, "recipientName 1", "*****@*****.**", "senderName 1", "*****@*****.**", "custom message"); _productAttributeParser.GetGiftCardAttribute(attributes, out var recipientName, out var recipientEmail, out var senderName, out var senderEmail, out var giftCardMessage); recipientName.ShouldEqual("recipientName 1"); recipientEmail.ShouldEqual("*****@*****.**"); senderName.ShouldEqual("senderName 1"); senderEmail.ShouldEqual("*****@*****.**"); giftCardMessage.ShouldEqual("custom message"); }
public void Can_add_and_parse_giftCardAttributes() { string attributes = ""; attributes = _productAttributeParser.AddGiftCardAttribute(attributes, "recipientName 1", "*****@*****.**", "senderName 1", "*****@*****.**", "custom message"); string recipientName, recipientEmail, senderName, senderEmail, giftCardMessage; _productAttributeParser.GetGiftCardAttribute(attributes, out recipientName, out recipientEmail, out senderName, out senderEmail, out giftCardMessage); Assert.AreEqual("recipientName 1", recipientName); Assert.AreEqual("*****@*****.**", recipientEmail); Assert.AreEqual("senderName 1", senderName); Assert.AreEqual("*****@*****.**", senderEmail); Assert.AreEqual("custom message", giftCardMessage); }
/// <summary> /// Formats attributes /// </summary> /// <param name="product">Product</param> /// <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="renderProductAttributes">A value indicating whether to render product attributes</param> /// <param name="renderGiftCardAttributes">A value indicating whether to render gift card attributes</param> /// <param name="allowHyperlinks">A value indicating whether to HTML hyperink tags could be rendered (if required)</param> /// <returns>Attributes</returns> public virtual async Task <string> FormatAttributes(Product product, string attributesXml, Customer customer, string serapator = "<br />", bool htmlEncode = true, bool renderPrices = true, bool renderProductAttributes = true, bool renderGiftCardAttributes = true, bool allowHyperlinks = true, bool showInAdmin = false) { var result = new StringBuilder(); var langId = string.Empty; if (_workContext.WorkingLanguage != null) { langId = _workContext.WorkingLanguage.Id; } else { langId = customer?.GetAttributeFromEntity <string>(SystemCustomerAttributeNames.LanguageId); } if (string.IsNullOrEmpty(langId)) { langId = ""; } //attributes if (renderProductAttributes) { result = await PrepareFormattedAttribute(product, attributesXml, langId, serapator, htmlEncode, renderPrices, allowHyperlinks, showInAdmin); if (product.ProductType == ProductType.BundledProduct) { int i = 0; foreach (var bundle in product.BundleProducts) { var p1 = await _productService.GetProductById(bundle.ProductId); if (p1 != null) { if (i > 0) { result.Append(serapator); } result.Append($"<a href=\"{p1.GetSeName(langId)}\"> {p1.GetLocalized(x => x.Name, langId)} </a>"); var formattedAttribute = await PrepareFormattedAttribute(p1, attributesXml, langId, serapator, htmlEncode, renderPrices, allowHyperlinks, showInAdmin); if (formattedAttribute.Length > 0) { result.Append(serapator); result.Append(formattedAttribute); } i++; } } } } //gift cards if (renderGiftCardAttributes) { if (product.IsGiftCard) { string giftCardRecipientName; string giftCardRecipientEmail; string giftCardSenderName; string giftCardSenderEmail; string giftCardMessage; _productAttributeParser.GetGiftCardAttribute(attributesXml, out giftCardRecipientName, out giftCardRecipientEmail, out giftCardSenderName, out giftCardSenderEmail, out giftCardMessage); //sender var giftCardFrom = product.GiftCardType == GiftCardType.Virtual ? string.Format(_localizationService.GetResource("GiftCardAttribute.From.Virtual"), giftCardSenderName, giftCardSenderEmail) : string.Format(_localizationService.GetResource("GiftCardAttribute.From.Physical"), giftCardSenderName); //recipient var giftCardFor = product.GiftCardType == GiftCardType.Virtual ? string.Format(_localizationService.GetResource("GiftCardAttribute.For.Virtual"), giftCardRecipientName, giftCardRecipientEmail) : string.Format(_localizationService.GetResource("GiftCardAttribute.For.Physical"), giftCardRecipientName); //encode (if required) if (htmlEncode) { giftCardFrom = WebUtility.HtmlEncode(giftCardFrom); giftCardFor = WebUtility.HtmlEncode(giftCardFor); } if (!String.IsNullOrEmpty(result.ToString())) { result.Append(serapator); } result.Append(giftCardFrom); result.Append(serapator); result.Append(giftCardFor); } } return(result.ToString()); }
/// <summary> /// Formats attributes /// </summary> /// <param name="product">Product</param> /// <param name="attributesXml">Attributes in XML format</param> /// <param name="customer">Customer</param> /// <param name="separator">Separator</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="renderProductAttributes">A value indicating whether to render product attributes</param> /// <param name="renderGiftCardAttributes">A value indicating whether to render gift card attributes</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(Product product, string attributesXml, Customer customer, string separator = "<br />", bool htmlEncode = true, bool renderPrices = true, bool renderProductAttributes = true, bool renderGiftCardAttributes = true, bool allowHyperlinks = true) { var result = new StringBuilder(); //attributes if (renderProductAttributes) { foreach (var attribute in _productAttributeParser.ParseProductAttributeMappings(attributesXml)) { //attributes without values if (!attribute.ShouldHaveValues()) { foreach (var value in _productAttributeParser.ParseValues(attributesXml, attribute.Id)) { var formattedAttribute = string.Empty; if (attribute.AttributeControlType == AttributeControlType.MultilineTextbox) { //multiline textbox var attributeName = _localizationService.GetLocalized(attribute.ProductAttribute, a => a.Name, _workContext.WorkingLanguage.Id); //encode (if required) if (htmlEncode) { attributeName = WebUtility.HtmlEncode(attributeName); } //we never encode multiline textbox input formattedAttribute = $"{attributeName}: {HtmlHelper.FormatText(value, false, true, false, false, false, false)}"; } else if (attribute.AttributeControlType == AttributeControlType.FileUpload) { //file upload Guid.TryParse(value, out var downloadGuid); var download = _downloadService.GetDownloadByGuid(downloadGuid); if (download != null) { var fileName = $"{download.Filename ?? download.DownloadGuid.ToString()}{download.Extension}"; //encode (if required) if (htmlEncode) { fileName = WebUtility.HtmlEncode(fileName); } //TODO add a method for getting URL (use routing because it handles all SEO friendly URLs) var attributeText = allowHyperlinks ? $"<a href=\"{_webHelper.GetStoreLocation(false)}download/getfileupload/?downloadId={download.DownloadGuid}\" class=\"fileuploadattribute\">{fileName}</a>" : fileName; var attributeName = _localizationService.GetLocalized(attribute.ProductAttribute, a => a.Name, _workContext.WorkingLanguage.Id); //encode (if required) if (htmlEncode) { attributeName = WebUtility.HtmlEncode(attributeName); } formattedAttribute = $"{attributeName}: {attributeText}"; } } else { //other attributes (textbox, datepicker) formattedAttribute = $"{_localizationService.GetLocalized(attribute.ProductAttribute, a => a.Name, _workContext.WorkingLanguage.Id)}: {value}"; //encode (if required) if (htmlEncode) { formattedAttribute = WebUtility.HtmlEncode(formattedAttribute); } } if (string.IsNullOrEmpty(formattedAttribute)) { continue; } if (result.Length > 0) { result.Append(separator); } result.Append(formattedAttribute); } } //product attribute values else { foreach (var attributeValue in _productAttributeParser.ParseProductAttributeValues(attributesXml, attribute.Id)) { var formattedAttribute = $"{_localizationService.GetLocalized(attribute.ProductAttribute, a => a.Name, _workContext.WorkingLanguage.Id)}: {_localizationService.GetLocalized(attributeValue, a => a.Name, _workContext.WorkingLanguage.Id)}"; if (renderPrices) { if (attributeValue.PriceAdjustmentUsePercentage) { if (attributeValue.PriceAdjustment > decimal.Zero) { formattedAttribute += string.Format( _localizationService.GetResource("FormattedAttributes.PriceAdjustment"), "+", attributeValue.PriceAdjustment.ToString("G29"), "%"); } else if (attributeValue.PriceAdjustment < decimal.Zero) { formattedAttribute += string.Format( _localizationService.GetResource("FormattedAttributes.PriceAdjustment"), string.Empty, attributeValue.PriceAdjustment.ToString("G29"), "%"); } } else { var attributeValuePriceAdjustment = _priceCalculationService.GetProductAttributeValuePriceAdjustment(attributeValue, customer); var priceAdjustmentBase = _taxService.GetProductPrice(product, attributeValuePriceAdjustment, customer, out var _); var priceAdjustment = _currencyService.ConvertFromPrimaryStoreCurrency(priceAdjustmentBase, _workContext.WorkingCurrency); if (priceAdjustmentBase > decimal.Zero) { formattedAttribute += string.Format( _localizationService.GetResource("FormattedAttributes.PriceAdjustment"), "+", _priceFormatter.FormatPrice(priceAdjustment, false, false), string.Empty); } else if (priceAdjustmentBase < decimal.Zero) { formattedAttribute += string.Format( _localizationService.GetResource("FormattedAttributes.PriceAdjustment"), "-", _priceFormatter.FormatPrice(-priceAdjustment, false, false), string.Empty); } } } //display quantity if (_shoppingCartSettings.RenderAssociatedAttributeValueQuantity && attributeValue.AttributeValueType == AttributeValueType.AssociatedToProduct) { //render only when more than 1 if (attributeValue.Quantity > 1) { formattedAttribute += string.Format(_localizationService.GetResource("ProductAttributes.Quantity"), attributeValue.Quantity); } } //encode (if required) if (htmlEncode) { formattedAttribute = WebUtility.HtmlEncode(formattedAttribute); } if (string.IsNullOrEmpty(formattedAttribute)) { continue; } if (result.Length > 0) { result.Append(separator); } result.Append(formattedAttribute); } } } } //gift cards if (!renderGiftCardAttributes) { return(result.ToString()); } if (!product.IsGiftCard) { return(result.ToString()); } _productAttributeParser.GetGiftCardAttribute(attributesXml, out var giftCardRecipientName, out var giftCardRecipientEmail, out var giftCardSenderName, out var giftCardSenderEmail, out var _); //sender var giftCardFrom = product.GiftCardType == GiftCardType.Virtual ? string.Format(_localizationService.GetResource("GiftCardAttribute.From.Virtual"), giftCardSenderName, giftCardSenderEmail) : string.Format(_localizationService.GetResource("GiftCardAttribute.From.Physical"), giftCardSenderName); //recipient var giftCardFor = product.GiftCardType == GiftCardType.Virtual ? string.Format(_localizationService.GetResource("GiftCardAttribute.For.Virtual"), giftCardRecipientName, giftCardRecipientEmail) : string.Format(_localizationService.GetResource("GiftCardAttribute.For.Physical"), giftCardRecipientName); //encode (if required) if (htmlEncode) { giftCardFrom = WebUtility.HtmlEncode(giftCardFrom); giftCardFor = WebUtility.HtmlEncode(giftCardFor); } if (!string.IsNullOrEmpty(result.ToString())) { result.Append(separator); } result.Append(giftCardFrom); result.Append(separator); result.Append(giftCardFor); return(result.ToString()); }
/// <summary> /// Formats attributes. /// </summary> /// <param name="product">Product</param> /// <param name="attributes">Attributes</param> /// <param name="customer">Customer</param> /// <param name="separator">Separator</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="renderProductAttributes">A value indicating whether to render product attributes</param> /// <param name="renderGiftCardAttributes">A value indicating whether to render gift card attributes</param> /// <param name="allowHyperlinks">A value indicating whether to render HTML hyperlinks</param> /// <returns>Formatted attributes.</returns> public string FormatAttributes( Product product, string attributes, Customer customer, string separator = "<br />", bool htmlEncode = true, bool renderPrices = true, bool renderProductAttributes = true, bool renderGiftCardAttributes = true, bool allowHyperlinks = true) { var result = new StringBuilder(); // Attributes. if (renderProductAttributes) { var languageId = _workContext.WorkingLanguage.Id; var pvaCollection = _productAttributeParser.ParseProductVariantAttributes(attributes); for (var i = 0; i < pvaCollection.Count; ++i) { var pva = pvaCollection[i]; var valuesStr = _productAttributeParser.ParseValues(attributes, pva.Id); for (var j = 0; j < valuesStr.Count; ++j) { var valueStr = valuesStr[j]; var pvaAttribute = string.Empty; if (!pva.ShouldHaveValues()) { // No values. if (pva.AttributeControlType == AttributeControlType.MultilineTextbox) { // Multiline textbox. string attributeName = pva.ProductAttribute.GetLocalized(a => a.Name, languageId); if (htmlEncode) { attributeName = HttpUtility.HtmlEncode(attributeName); } pvaAttribute = string.Format("{0}: {1}", attributeName, HtmlUtils.ConvertPlainTextToHtml(valueStr.HtmlEncode())); // We never encode multiline textbox input. } else if (pva.AttributeControlType == AttributeControlType.FileUpload) { Guid.TryParse(valueStr, out var downloadGuid); var download = _downloadService.GetDownloadByGuid(downloadGuid); if (download?.MediaFile != null) { // TODO: add a method for getting URL (use routing because it handles all SEO friendly URLs). var attributeText = ""; var fileName = download.MediaFile.Name; if (htmlEncode) { fileName = HttpUtility.HtmlEncode(fileName); } if (allowHyperlinks) { var downloadLink = string.Format("{0}download/getfileupload/?downloadId={1}", _webHelper.GetStoreLocation(false), download.DownloadGuid); attributeText = string.Format("<a href=\"{0}\" class=\"fileuploadattribute\">{1}</a>", downloadLink, fileName); } else { attributeText = fileName; } string attributeName = pva.ProductAttribute.GetLocalized(a => a.Name, languageId); if (htmlEncode) { attributeName = HttpUtility.HtmlEncode(attributeName); } pvaAttribute = string.Format("{0}: {1}", attributeName, attributeText); } } else { // Other attributes (textbox, datepicker). pvaAttribute = string.Format("{0}: {1}", pva.ProductAttribute.GetLocalized(a => a.Name, languageId), valueStr); if (htmlEncode) { pvaAttribute = HttpUtility.HtmlEncode(pvaAttribute); } } } else { // Attributes with values. if (int.TryParse(valueStr, out var pvaId)) { var pvaValue = _productAttributeService.GetProductVariantAttributeValueById(pvaId); if (pvaValue != null) { pvaAttribute = "{0}: {1}".FormatInvariant( pva.ProductAttribute.GetLocalized(a => a.Name, languageId), pvaValue.GetLocalized(a => a.Name, languageId)); if (renderPrices) { var attributeValuePriceAdjustment = _priceCalculationService.GetProductVariantAttributeValuePriceAdjustment(pvaValue, product, customer, null, 1); var priceAdjustmentBase = _taxService.GetProductPrice(product, attributeValuePriceAdjustment, customer, out var taxRate); var priceAdjustment = _currencyService.ConvertFromPrimaryStoreCurrency(priceAdjustmentBase, _workContext.WorkingCurrency); if (_shoppingCartSettings.ShowLinkedAttributeValueQuantity && pvaValue.ValueType == ProductVariantAttributeValueType.ProductLinkage && pvaValue.Quantity > 1) { pvaAttribute += string.Format(" × {0}", pvaValue.Quantity); } if (_catalogSettings.ShowVariantCombinationPriceAdjustment) { if (priceAdjustmentBase > 0) { pvaAttribute += " (+{0})".FormatInvariant(_priceFormatter.FormatPrice(priceAdjustment, true, false)); } else if (priceAdjustmentBase < decimal.Zero) { pvaAttribute += " (-{0})".FormatInvariant(_priceFormatter.FormatPrice(-priceAdjustment, true, false)); } } } } if (htmlEncode) { pvaAttribute = HttpUtility.HtmlEncode(pvaAttribute); } } } if (!string.IsNullOrEmpty(pvaAttribute)) { if (i != 0 || j != 0) { result.Append(separator); } result.Append(pvaAttribute); } } } } // Gift cards. if (renderGiftCardAttributes) { if (product.IsGiftCard) { _productAttributeParser.GetGiftCardAttribute(attributes, out var giftCardRecipientName, out var giftCardRecipientEmail, out var giftCardSenderName, out var giftCardSenderEmail, out var giftCardMessage); // Sender. var giftCardFrom = product.GiftCardType == GiftCardType.Virtual ? string.Format(_localizationService.GetResource("GiftCardAttribute.From.Virtual"), giftCardSenderName, giftCardSenderEmail) : string.Format(_localizationService.GetResource("GiftCardAttribute.From.Physical"), giftCardSenderName); // Recipient. var giftCardFor = product.GiftCardType == GiftCardType.Virtual ? string.Format(_localizationService.GetResource("GiftCardAttribute.For.Virtual"), giftCardRecipientName, giftCardRecipientEmail) : string.Format(_localizationService.GetResource("GiftCardAttribute.For.Physical"), giftCardRecipientName); if (htmlEncode) { giftCardFrom = HttpUtility.HtmlEncode(giftCardFrom); giftCardFor = HttpUtility.HtmlEncode(giftCardFor); } if (!string.IsNullOrEmpty(result.ToString())) { result.Append(separator); } result.Append(giftCardFrom); result.Append(separator); result.Append(giftCardFor); } } return(result.ToString()); }
/// <summary> /// Formats attributes /// </summary> /// <param name="productVariant">Product variant</param> /// <param name="attributes">Attributes</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="renderProductAttributes">A value indicating whether to render product attributes</param> /// <param name="renderGiftCardAttributes">A value indicating whether to render gift card attributes</param> /// <param name="allowHyperlinks">A value indicating whether to HTML hyperink tags could be rendered (if required)</param> /// <returns>Attributes</returns> public string FormatAttributes(ProductVariant productVariant, string attributes, Customer customer, string serapator = "<br />", bool htmlEncode = true, bool renderPrices = true, bool renderProductAttributes = true, bool renderGiftCardAttributes = true, bool allowHyperlinks = true) { var result = new StringBuilder(); //attributes if (renderProductAttributes) { var pvaCollection = _productAttributeParser.ParseProductVariantAttributes(attributes); for (int i = 0; i < pvaCollection.Count; i++) { var pva = pvaCollection[i]; var valuesStr = _productAttributeParser.ParseValues(attributes, pva.Id); for (int j = 0; j < valuesStr.Count; j++) { string valueStr = valuesStr[j]; string pvaAttribute = string.Empty; if (!pva.ShouldHaveValues()) { //no values if (pva.AttributeControlType == AttributeControlType.TextBox) { //multiline textbox var attributeName = pva.ProductAttribute.GetLocalized(a => a.Name, _workContext.WorkingLanguage.Id); //encode (if required) if (htmlEncode) { attributeName = HttpUtility.HtmlEncode(attributeName); } pvaAttribute = string.Format("{0}: {1}", attributeName, HtmlHelper.FormatText(valueStr, false, true, false, false, false, false)); //we never encode multiline textbox input } else if (pva.AttributeControlType == AttributeControlType.TextBox) { //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); attributeText = string.Format("<a href=\"{0}\" class=\"fileuploadattribute\">{1}</a>", downloadLink, fileName); } else { //hyperlinks aren't allowed attributeText = fileName; } var attributeName = pva.ProductAttribute.GetLocalized(a => a.Name, _workContext.WorkingLanguage.Id); //encode (if required) if (htmlEncode) { attributeName = HttpUtility.HtmlEncode(attributeName); } pvaAttribute = string.Format("{0}: {1}", attributeName, attributeText); } } else { //other attributes (textbox, datepicker) pvaAttribute = string.Format("{0}: {1}", pva.ProductAttribute.GetLocalized(a => a.Name, _workContext.WorkingLanguage.Id), valueStr); //encode (if required) if (htmlEncode) { pvaAttribute = HttpUtility.HtmlEncode(pvaAttribute); } } } else { //attributes with values int pvaId = 0; if (int.TryParse(valueStr, out pvaId)) { var pvaValue = _productAttributeService.GetProductVariantAttributeValueById(pvaId); if (pvaValue != null) { pvaAttribute = string.Format("{0}: {1}", pva.ProductAttribute.GetLocalized(a => a.Name, _workContext.WorkingLanguage.Id), pvaValue.GetLocalized(a => a.Name, _workContext.WorkingLanguage.Id)); if (renderPrices) { decimal taxRate = decimal.Zero; decimal priceAdjustmentBase = _taxService.GetProductPrice(productVariant, pvaValue.PriceAdjustment, customer, out taxRate); decimal priceAdjustment = _currencyService.ConvertFromPrimaryStoreCurrency(priceAdjustmentBase, _workContext.WorkingCurrency); if (priceAdjustmentBase > 0) { string priceAdjustmentStr = _priceFormatter.FormatPrice(priceAdjustment, false, false); pvaAttribute += string.Format(" [+{0}]", priceAdjustmentStr); } else if (priceAdjustmentBase < decimal.Zero) { string priceAdjustmentStr = _priceFormatter.FormatPrice(-priceAdjustment, false, false); pvaAttribute += string.Format(" [-{0}]", priceAdjustmentStr); } } } //encode (if required) if (htmlEncode) { pvaAttribute = HttpUtility.HtmlEncode(pvaAttribute); } } } if (!String.IsNullOrEmpty(pvaAttribute)) { if (i != 0 || j != 0) { result.Append(serapator); } result.Append(pvaAttribute); } } } } //gift cards if (renderGiftCardAttributes) { if (productVariant.IsGiftCard) { string giftCardRecipientName = ""; string giftCardRecipientEmail = ""; string giftCardSenderName = ""; string giftCardSenderEmail = ""; string giftCardMessage = ""; _productAttributeParser.GetGiftCardAttribute(attributes, out giftCardRecipientName, out giftCardRecipientEmail, out giftCardSenderName, out giftCardSenderEmail, out giftCardMessage); //sender var giftCardFrom = productVariant.GiftCardType == GiftCardType.Virtual ? string.Format(_localizationService.GetResource("GiftCardAttribute.From.Virtual"), giftCardSenderName, giftCardSenderEmail) : string.Format(_localizationService.GetResource("GiftCardAttribute.From.Physical"), giftCardSenderName); //recipient var giftCardFor = productVariant.GiftCardType == GiftCardType.Virtual ? string.Format(_localizationService.GetResource("GiftCardAttribute.For.Virtual"), giftCardRecipientName, giftCardRecipientEmail) : string.Format(_localizationService.GetResource("GiftCardAttribute.For.Physical"), giftCardRecipientName); //encode (if required) if (htmlEncode) { giftCardFrom = HttpUtility.HtmlEncode(giftCardFrom); giftCardFor = HttpUtility.HtmlEncode(giftCardFor); } if (!String.IsNullOrEmpty(result.ToString())) { result.Append(serapator); } result.Append(giftCardFrom); result.Append(serapator); result.Append(giftCardFor); } } return(result.ToString()); }
/// <summary> /// Formats attributes /// </summary> /// <param name="product">Product</param> /// <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="renderProductAttributes">A value indicating whether to render product attributes</param> /// <param name="renderGiftCardAttributes">A value indicating whether to render gift card attributes</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(Product product, string attributesXml, Customer customer, string serapator = "<br />", bool htmlEncode = true, bool renderPrices = true, bool renderProductAttributes = true, bool renderGiftCardAttributes = true, bool allowHyperlinks = true) { var result = new StringBuilder(); //attributes if (renderProductAttributes) { var attributes = _productAttributeParser.ParseProductAttributeMappings(product, attributesXml); for (int i = 0; i < attributes.Count; i++) { var productAttribute = _productAttributeService.GetProductAttributeById(attributes[i].ProductAttributeId); var attribute = attributes[i]; var valuesStr = _productAttributeParser.ParseValues(attributesXml, attribute.Id); for (int j = 0; j < valuesStr.Count; j++) { string valueStr = valuesStr[j]; string formattedAttribute = string.Empty; if (!attribute.ShouldHaveValues()) { //no values if (attribute.AttributeControlType == AttributeControlType.MultilineTextbox) { //multiline textbox var attributeName = productAttribute.GetLocalized(a => a.Name, _workContext.WorkingLanguage.Id); //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); attributeText = string.Format("<a href=\"{0}\" class=\"fileuploadattribute\">{1}</a>", downloadLink, fileName); } else { //hyperlinks aren't allowed attributeText = fileName; } var attributeName = productAttribute.GetLocalized(a => a.Name, _workContext.WorkingLanguage.Id); //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}", productAttribute.GetLocalized(a => a.Name, _workContext.WorkingLanguage.Id), valueStr); //encode (if required) if (htmlEncode) { formattedAttribute = HttpUtility.HtmlEncode(formattedAttribute); } } } else { //attributes with values int attributeValueId; if (int.TryParse(valueStr, out attributeValueId)) { if (product.ProductAttributeMappings.Where(x => x.ProductAttributeId == attributes[i].ProductAttributeId).FirstOrDefault() != null) { var attributeValue = product.ProductAttributeMappings.Where(x => x.ProductAttributeId == attributes[i].ProductAttributeId).FirstOrDefault().ProductAttributeValues.Where(x => x.Id == attributeValueId).FirstOrDefault(); //_productAttributeService.GetProductAttributeValueById(attributeValueId); if (attributeValue != null) { formattedAttribute = string.Format("{0}: {1}", productAttribute.GetLocalized(a => a.Name, _workContext.WorkingLanguage.Id), attributeValue.GetLocalized(a => a.Name, _workContext.WorkingLanguage.Id)); if (renderPrices) { decimal taxRate; decimal attributeValuePriceAdjustment = _priceCalculationService.GetProductAttributeValuePriceAdjustment(attributeValue); decimal priceAdjustmentBase = _taxService.GetProductPrice(product, attributeValuePriceAdjustment, customer, out taxRate); decimal priceAdjustment = _currencyService.ConvertFromPrimaryStoreCurrency(priceAdjustmentBase, _workContext.WorkingCurrency); if (priceAdjustmentBase > 0) { string priceAdjustmentStr = _priceFormatter.FormatPrice(priceAdjustment, false, false); formattedAttribute += string.Format(" [+{0}]", priceAdjustmentStr); } else if (priceAdjustmentBase < decimal.Zero) { string priceAdjustmentStr = _priceFormatter.FormatPrice(-priceAdjustment, false, false); formattedAttribute += string.Format(" [-{0}]", priceAdjustmentStr); } } //display quantity if (_shoppingCartSettings.RenderAssociatedAttributeValueQuantity && attributeValue.AttributeValueType == AttributeValueType.AssociatedToProduct) { //render only when more than 1 if (attributeValue.Quantity > 1) { //TODO localize resource formattedAttribute += string.Format(" - qty {0}", attributeValue.Quantity); } } } } //encode (if required) if (htmlEncode) { formattedAttribute = HttpUtility.HtmlEncode(formattedAttribute); } } } if (!String.IsNullOrEmpty(formattedAttribute)) { if (i != 0 || j != 0) { result.Append(serapator); } result.Append(formattedAttribute); } } } } //gift cards if (renderGiftCardAttributes) { if (product.IsGiftCard) { string giftCardRecipientName; string giftCardRecipientEmail; string giftCardSenderName; string giftCardSenderEmail; string giftCardMessage; _productAttributeParser.GetGiftCardAttribute(attributesXml, out giftCardRecipientName, out giftCardRecipientEmail, out giftCardSenderName, out giftCardSenderEmail, out giftCardMessage); //sender var giftCardFrom = product.GiftCardType == GiftCardType.Virtual ? string.Format(_localizationService.GetResource("GiftCardAttribute.From.Virtual"), giftCardSenderName, giftCardSenderEmail) : string.Format(_localizationService.GetResource("GiftCardAttribute.From.Physical"), giftCardSenderName); //recipient var giftCardFor = product.GiftCardType == GiftCardType.Virtual ? string.Format(_localizationService.GetResource("GiftCardAttribute.For.Virtual"), giftCardRecipientName, giftCardRecipientEmail) : string.Format(_localizationService.GetResource("GiftCardAttribute.For.Physical"), giftCardRecipientName); //encode (if required) if (htmlEncode) { giftCardFrom = HttpUtility.HtmlEncode(giftCardFrom); giftCardFor = HttpUtility.HtmlEncode(giftCardFor); } if (!String.IsNullOrEmpty(result.ToString())) { result.Append(serapator); } result.Append(giftCardFrom); result.Append(serapator); result.Append(giftCardFor); } } return(result.ToString()); }
/// <summary> /// Formats attributes /// </summary> /// <param name="productVariant">Product variant</param> /// <param name="attributes">Attributes</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="renderProductAttributes">A value indicating whether to render product attributes</param> /// <param name="renderGiftCardAttributes">A value indicating whether to render gift card attributes</param> /// <returns>Attributes</returns> public string FormatAttributes(ProductVariant productVariant, string attributes, Customer customer, string serapator = "<br />", bool htmlEncode = true, bool renderPrices = true, bool renderProductAttributes = true, bool renderGiftCardAttributes = true) { var result = new StringBuilder(); //attributes if (renderProductAttributes) { var pvaCollection = _productAttributeParser.ParseProductVariantAttributes(attributes); for (int i = 0; i < pvaCollection.Count; i++) { var pva = pvaCollection[i]; var valuesStr = _productAttributeParser.ParseValues(attributes, pva.Id); for (int j = 0; j < valuesStr.Count; j++) { string valueStr = valuesStr[j]; string pvaAttribute = string.Empty; if (!pva.ShouldHaveValues()) { if (pva.AttributeControlType == AttributeControlType.MultilineTextbox) { pvaAttribute = string.Format("{0}: {1}", pva.ProductAttribute.GetLocalized(a => a.Name, _workContext.WorkingLanguage.Id), HtmlHelper.FormatText(valueStr, false, true, true, false, false, false)); } else { pvaAttribute = string.Format("{0}: {1}", pva.ProductAttribute.GetLocalized(a => a.Name, _workContext.WorkingLanguage.Id), valueStr); } } else { int pvaId = 0; if (int.TryParse(valueStr, out pvaId)) { var pvaValue = _productAttributeService.GetProductVariantAttributeValueById(pvaId); if (pvaValue != null) { pvaAttribute = string.Format("{0}: {1}", pva.ProductAttribute.GetLocalized(a => a.Name, _workContext.WorkingLanguage.Id), pvaValue.GetLocalized(a => a.Name, _workContext.WorkingLanguage.Id)); if (renderPrices) { decimal taxRate = decimal.Zero; decimal priceAdjustmentBase = _taxService.GetProductPrice(productVariant, pvaValue.PriceAdjustment, customer, out taxRate); decimal priceAdjustment = _currencyService.ConvertFromPrimaryStoreCurrency(priceAdjustmentBase, _workContext.WorkingCurrency); if (priceAdjustmentBase > 0) { string priceAdjustmentStr = _priceFormatter.FormatPrice(priceAdjustment, false, false); pvaAttribute += string.Format(" [+{0}]", priceAdjustmentStr); } else if (priceAdjustmentBase < decimal.Zero) { string priceAdjustmentStr = _priceFormatter.FormatPrice(-priceAdjustment, false, false); pvaAttribute += string.Format(" [-{0}]", priceAdjustmentStr); } } } } } if (!String.IsNullOrEmpty(pvaAttribute)) { if (i != 0 || j != 0) { result.Append(serapator); } //we don't encode multiline textbox input if (htmlEncode && pva.AttributeControlType != AttributeControlType.MultilineTextbox) { result.Append(HttpUtility.HtmlEncode(pvaAttribute)); } else { result.Append(pvaAttribute); } } } } } //gift cards if (renderGiftCardAttributes) { if (productVariant.IsGiftCard) { string giftCardRecipientName = string.Empty; string giftCardRecipientEmail = string.Empty; string giftCardSenderName = string.Empty; string giftCardSenderEmail = string.Empty; string giftCardMessage = string.Empty; _productAttributeParser.GetGiftCardAttribute(attributes, out giftCardRecipientName, out giftCardRecipientEmail, out giftCardSenderName, out giftCardSenderEmail, out giftCardMessage); if (!String.IsNullOrEmpty(result.ToString())) { result.Append(serapator); } if (htmlEncode) { result.Append(HttpUtility.HtmlEncode(string.Format(_localizationService.GetResource("GiftCardAttribute.For"), giftCardRecipientName))); result.Append(serapator); result.Append(HttpUtility.HtmlEncode(string.Format(_localizationService.GetResource("GiftCardAttribute.From"), giftCardSenderName))); } else { result.Append(string.Format(_localizationService.GetResource("GiftCardAttribute.For"), giftCardRecipientName)); result.Append(serapator); result.Append(string.Format(_localizationService.GetResource("GiftCardAttribute.From"), giftCardSenderName)); } } } 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); }