public void CanAddAndParseCheckoutAttributes() { var attributes = string.Empty; //color: green attributes = _checkoutAttributeParser.AddCheckoutAttribute(attributes, _ca1, _cav11.Id.ToString()); //custom option: option 1, option 2 attributes = _checkoutAttributeParser.AddCheckoutAttribute(attributes, _ca2, _cav21.Id.ToString()); attributes = _checkoutAttributeParser.AddCheckoutAttribute(attributes, _ca2, _cav22.Id.ToString()); //custom text attributes = _checkoutAttributeParser.AddCheckoutAttribute(attributes, _ca3, "Some custom text goes here"); var parsedAttributeValues = _checkoutAttributeParser.ParseCheckoutAttributeValues(attributes).ToList(); parsedAttributeValues.SelectMany(x => x.values.Select(p => p.Id)).Contains(_cav11.Id).Should().BeTrue(); parsedAttributeValues.SelectMany(x => x.values.Select(p => p.Id)).Contains(_cav12.Id).Should().BeFalse(); parsedAttributeValues.SelectMany(x => x.values.Select(p => p.Id)).Contains(_cav21.Id).Should().BeTrue(); parsedAttributeValues.SelectMany(x => x.values.Select(p => p.Id)).Contains(_cav22.Id).Should().BeTrue(); parsedAttributeValues.SelectMany(x => x.values.Select(p => p.Id)).Contains(_cav22.Id).Should().BeTrue(); var parsedValues = _checkoutAttributeParser.ParseValues(attributes, _ca3.Id); parsedValues.Count.Should().Be(1); parsedValues.Contains("Some custom text goes here").Should().BeTrue(); parsedValues.Contains("Some other custom text").Should().BeFalse(); }
public void Can_add_and_parse_checkoutAttributes() { var attributes = ""; //color: green attributes = _checkoutAttributeParser.AddCheckoutAttribute(attributes, ca1, cav1_1.Id.ToString()); //custom option: option 1, option 2 attributes = _checkoutAttributeParser.AddCheckoutAttribute(attributes, ca2, cav2_1.Id.ToString()); attributes = _checkoutAttributeParser.AddCheckoutAttribute(attributes, ca2, cav2_2.Id.ToString()); //custom text attributes = _checkoutAttributeParser.AddCheckoutAttribute(attributes, ca3, "Some custom text goes here"); var parsed_attributeValues = _checkoutAttributeParser.ParseCheckoutAttributeValues(attributes); parsed_attributeValues.Contains(cav1_1).ShouldEqual(true); parsed_attributeValues.Contains(cav1_2).ShouldEqual(false); parsed_attributeValues.Contains(cav2_1).ShouldEqual(true); parsed_attributeValues.Contains(cav2_2).ShouldEqual(true); parsed_attributeValues.Contains(cav2_2).ShouldEqual(true); var parsedValues = _checkoutAttributeParser.ParseValues(attributes, ca3.Id); parsedValues.Count.ShouldEqual(1); parsedValues.Contains("Some custom text goes here").ShouldEqual(true); parsedValues.Contains("Some other custom text").ShouldEqual(false); }
public void Can_add_and_parse_checkoutAttributes() { var attributes = ""; //color: green attributes = _checkoutAttributeParser.AddCheckoutAttribute(attributes, ca1, cav1_1.Id.ToString()); //custom option: option 1, option 2 attributes = _checkoutAttributeParser.AddCheckoutAttribute(attributes, ca2, cav2_1.Id.ToString()); attributes = _checkoutAttributeParser.AddCheckoutAttribute(attributes, ca2, cav2_2.Id.ToString()); //custom text attributes = _checkoutAttributeParser.AddCheckoutAttribute(attributes, ca3, "Some custom text goes here"); RunWithTestServiceProvider(() => { var parsedAttributeValues = _checkoutAttributeParser.ParseCheckoutAttributeValues(attributes).ToList(); parsedAttributeValues.SelectMany(x => x.values).Contains(cav1_1).Should().BeTrue(); parsedAttributeValues.SelectMany(x => x.values).Contains(cav1_2).Should().BeFalse(); parsedAttributeValues.SelectMany(x => x.values).Contains(cav2_1).Should().BeTrue(); parsedAttributeValues.SelectMany(x => x.values).Contains(cav2_2).Should().BeTrue(); parsedAttributeValues.SelectMany(x => x.values).Contains(cav2_2).Should().BeTrue(); var parsedValues = _checkoutAttributeParser.ParseValues(attributes, ca3.Id); parsedValues.Count.Should().Be(1); parsedValues.Contains("Some custom text goes here").Should().BeTrue(); parsedValues.Contains("Some other custom text").Should().BeFalse(); }); }
public async Task Can_add_and_parse_checkoutAttributes() { string attributes = ""; //color: green attributes = _checkoutAttributeParser.AddCheckoutAttribute(attributes, ca1, cav1_1.Id.ToString()); //custom option: option 1, option 2 attributes = _checkoutAttributeParser.AddCheckoutAttribute(attributes, ca2, cav2_1.Id.ToString()); attributes = _checkoutAttributeParser.AddCheckoutAttribute(attributes, ca2, cav2_2.Id.ToString()); //custom text attributes = _checkoutAttributeParser.AddCheckoutAttribute(attributes, ca3, "absolutely any value"); var parsed_attributeValues = await _checkoutAttributeParser.ParseCheckoutAttributeValues(attributes); Assert.IsTrue(parsed_attributeValues.Contains(cav1_1)); Assert.IsFalse(parsed_attributeValues.Contains(cav1_2)); //not inserted Assert.IsTrue(parsed_attributeValues.Contains(cav2_1)); Assert.IsTrue(parsed_attributeValues.Contains(cav2_2)); Assert.IsTrue(parsed_attributeValues.Contains(cav2_2)); var parsedValues = _checkoutAttributeParser.ParseValues(attributes, ca3.Id); Assert.AreEqual(1, parsedValues.Count); Assert.IsTrue(parsedValues.Contains("absolutely any value")); Assert.IsFalse(parsedValues.Contains("it shouldn't be valid in any case")); }
private string GetSelectedCheckoutAttributesThatHasNotBeenSentToKlarna(Customer customer, int currentStoreId) { string checkoutAttributesXml = null; var originalCheckoutAttributesXml = customer.GetAttribute <string>(SystemCustomerAttributeNames.CheckoutAttributes, currentStoreId); var allCheckoutAttributes = _checkoutAttributeService.GetAllCheckoutAttributes(currentStoreId); foreach (var checkoutAttribute in allCheckoutAttributes.Where(x => !x.ShouldHaveValues())) { var selectedValues = _checkoutAttributeParser.ParseValues(originalCheckoutAttributesXml, checkoutAttribute.Id); foreach (var selectedValue in selectedValues) { checkoutAttributesXml = _checkoutAttributeParser.AddCheckoutAttribute(checkoutAttributesXml, checkoutAttribute, selectedValue); } } return(checkoutAttributesXml); }
/// <summary> /// Formats attributes /// </summary> /// <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="allowHyperlinks">A value indicating whether to HTML hyperink tags could be rendered (if required)</param> /// <returns>Attributes</returns> public string FormatAttributes(string attributes, Customer customer, string serapator = "<br />", bool htmlEncode = true, bool renderPrices = true, bool allowHyperlinks = true) { var result = new StringBuilder(); var caCollection = _checkoutAttributeParser.ParseCheckoutAttributes(attributes); for (int i = 0; i < caCollection.Count; i++) { var ca = caCollection[i]; var valuesStr = _checkoutAttributeParser.ParseValues(attributes, ca.Id); for (int j = 0; j < valuesStr.Count; j++) { string valueStr = valuesStr[j]; string caAttribute = ""; if (!ca.ShouldHaveValues()) { //no values if (ca.AttributeControlType == AttributeControlType.MultilineTextbox) { //multiline textbox var attributeName = ca.GetLocalized(a => a.Name, _workContext.WorkingLanguage.Id); //encode (if required) if (htmlEncode) { attributeName = HttpUtility.HtmlEncode(attributeName); } caAttribute = string.Format("{0}: {1}", attributeName, HtmlHelper.FormatText(valueStr, false, true, false, false, false, false)); //we never encode multiline textbox input } else if (ca.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 = ca.GetLocalized(a => a.Name, _workContext.WorkingLanguage.Id); //encode (if required) if (htmlEncode) { attributeName = HttpUtility.HtmlEncode(attributeName); } caAttribute = string.Format("{0}: {1}", attributeName, attributeText); } } else { //other attributes (textbox, datepicker) caAttribute = string.Format("{0}: {1}", ca.GetLocalized(a => a.Name, _workContext.WorkingLanguage.Id), valueStr); //encode (if required) if (htmlEncode) { caAttribute = HttpUtility.HtmlEncode(caAttribute); } } } else { int caId = 0; if (int.TryParse(valueStr, out caId)) { var caValue = _checkoutAttributeService.GetCheckoutAttributeValueById(caId); if (caValue != null) { caAttribute = string.Format("{0}: {1}", ca.GetLocalized(a => a.Name, _workContext.WorkingLanguage.Id), caValue.GetLocalized(a => a.Name, _workContext.WorkingLanguage.Id)); if (renderPrices) { decimal priceAdjustmentBase = _taxService.GetCheckoutAttributePrice(caValue, customer); decimal priceAdjustment = _currencyService.ConvertFromPrimaryStoreCurrency(priceAdjustmentBase, _workContext.WorkingCurrency); if (priceAdjustmentBase > 0) { string priceAdjustmentStr = _priceFormatter.FormatPrice(priceAdjustment); caAttribute += string.Format(" [+{0}]", priceAdjustmentStr); } } } //encode (if required) if (htmlEncode) { caAttribute = HttpUtility.HtmlEncode(caAttribute); } } } if (!String.IsNullOrEmpty(caAttribute)) { if (i != 0 || j != 0) { result.Append(serapator); } result.Append(caAttribute); } } } return(result.ToString()); }
private async Task PrepareCheckoutAttributes(ShoppingCartModel model, GetShoppingCart request) { #region Checkout attributes var checkoutAttributes = await _checkoutAttributeService.GetAllCheckoutAttributes(request.Store.Id, !request.Cart.RequiresShipping()); foreach (var attribute in checkoutAttributes) { var attributeModel = new ShoppingCartModel.CheckoutAttributeModel { Id = attribute.Id, Name = attribute.GetLocalized(x => x.Name, request.Language.Id), TextPrompt = attribute.GetLocalized(x => x.TextPrompt, request.Language.Id), IsRequired = attribute.IsRequired, AttributeControlType = attribute.AttributeControlType, DefaultValue = attribute.DefaultValue }; if (!String.IsNullOrEmpty(attribute.ValidationFileAllowedExtensions)) { attributeModel.AllowedFileExtensions = attribute.ValidationFileAllowedExtensions .Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries) .ToList(); } if (attribute.ShouldHaveValues()) { //values var attributeValues = attribute.CheckoutAttributeValues; foreach (var attributeValue in attributeValues) { var attributeValueModel = new ShoppingCartModel.CheckoutAttributeValueModel { Id = attributeValue.Id, Name = attributeValue.GetLocalized(x => x.Name, request.Language.Id), ColorSquaresRgb = attributeValue.ColorSquaresRgb, IsPreSelected = attributeValue.IsPreSelected, }; attributeModel.Values.Add(attributeValueModel); //display price if allowed if (await _permissionService.Authorize(StandardPermissionProvider.DisplayPrices)) { decimal priceAdjustmentBase = (await _taxService.GetCheckoutAttributePrice(attribute, attributeValue)).checkoutPrice; decimal priceAdjustment = await _currencyService.ConvertFromPrimaryStoreCurrency(priceAdjustmentBase, request.Currency); if (priceAdjustmentBase > decimal.Zero) { attributeValueModel.PriceAdjustment = "+" + _priceFormatter.FormatPrice(priceAdjustment); } else if (priceAdjustmentBase < decimal.Zero) { attributeValueModel.PriceAdjustment = "-" + _priceFormatter.FormatPrice(-priceAdjustment); } } } } //set already selected attributes var selectedCheckoutAttributes = request.Customer.GetAttributeFromEntity <string>(SystemCustomerAttributeNames.CheckoutAttributes, request.Store.Id); switch (attribute.AttributeControlType) { case AttributeControlType.DropdownList: case AttributeControlType.RadioList: case AttributeControlType.Checkboxes: case AttributeControlType.ColorSquares: case AttributeControlType.ImageSquares: { if (!String.IsNullOrEmpty(selectedCheckoutAttributes)) { //clear default selection foreach (var item in attributeModel.Values) { item.IsPreSelected = false; } //select new values var selectedValues = await _checkoutAttributeParser.ParseCheckoutAttributeValues(selectedCheckoutAttributes); foreach (var attributeValue in selectedValues) { if (attributeModel.Id == attributeValue.CheckoutAttributeId) { 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(selectedCheckoutAttributes)) { var enteredText = _checkoutAttributeParser.ParseValues(selectedCheckoutAttributes, attribute.Id); if (enteredText.Any()) { attributeModel.DefaultValue = enteredText[0]; } } } break; case AttributeControlType.Datepicker: { //keep in mind my that the code below works only in the current culture var selectedDateStr = _checkoutAttributeParser.ParseValues(selectedCheckoutAttributes, attribute.Id); if (selectedDateStr.Any()) { 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(selectedCheckoutAttributes)) { var downloadGuidStr = _checkoutAttributeParser.ParseValues(selectedCheckoutAttributes, attribute.Id).FirstOrDefault(); Guid downloadGuid; Guid.TryParse(downloadGuidStr, out downloadGuid); var download = await _downloadService.GetDownloadByGuid(downloadGuid); if (download != null) { attributeModel.DefaultValue = download.DownloadGuid.ToString(); } } } break; default: break; } model.CheckoutAttributes.Add(attributeModel); } #endregion }
/// <summary> /// Validates whether this shopping cart is valid /// </summary> /// <param name="shoppingCart">Shopping cart</param> /// <param name="checkoutAttributes">Checkout attributes</param> /// <param name="validateCheckoutAttributes">A value indicating whether to validate checkout attributes</param> /// <returns>Warnings</returns> public virtual IList <string> GetShoppingCartWarnings(IList <ShoppingCartItem> shoppingCart, string checkoutAttributes, bool validateCheckoutAttributes) { var warnings = new List <string>(); bool hasStandartProducts = false; bool hasRecurringProducts = false; foreach (var sci in shoppingCart) { var productVariant = sci.ProductVariant; if (productVariant == null) { warnings.Add(string.Format(_localizationService.GetResource("ShoppingCart.CannotLoadProductVariant"), sci.ProductVariantId)); return(warnings); } if (productVariant.IsRecurring) { hasRecurringProducts = true; } else { hasStandartProducts = true; } } //don't mix standard and recurring products if (hasStandartProducts && hasRecurringProducts) { warnings.Add(_localizationService.GetResource("ShoppingCart.CannotMixStandardAndAutoshipProducts")); } //recurring cart validation if (hasRecurringProducts) { int cycleLength = 0; RecurringProductCyclePeriod cyclePeriod = RecurringProductCyclePeriod.Days; int totalCycles = 0; string cyclesError = shoppingCart.GetRecurringCycleInfo(out cycleLength, out cyclePeriod, out totalCycles); if (!string.IsNullOrEmpty(cyclesError)) { warnings.Add(cyclesError); return(warnings); } } //validate checkout attributes if (validateCheckoutAttributes) { //selected attributes var ca1Collection = _checkoutAttributeParser.ParseCheckoutAttributes(checkoutAttributes); //existing checkout attributes var ca2Collection = _checkoutAttributeService.GetAllCheckoutAttributes(); if (!shoppingCart.RequiresShipping()) { //remove attributes which require shippable products ca2Collection = ca2Collection.RemoveShippableAttributes(); } foreach (var ca2 in ca2Collection) { if (ca2.IsRequired) { bool found = false; //selected checkout attributes foreach (var ca1 in ca1Collection) { if (ca1.Id == ca2.Id) { var caValuesStr = _checkoutAttributeParser.ParseValues(checkoutAttributes, ca1.Id); foreach (string str1 in caValuesStr) { if (!String.IsNullOrEmpty(str1.Trim())) { found = true; break; } } } } //if not found if (!found) { if (!string.IsNullOrEmpty(ca2.GetLocalized(a => a.TextPrompt))) { warnings.Add(ca2.GetLocalized(a => a.TextPrompt)); } else { warnings.Add(string.Format(_localizationService.GetResource("ShoppingCart.SelectAttribute"), ca2.GetLocalized(a => a.Name))); } } } } } return(warnings); }
/// <summary> /// Formats attributes /// </summary> /// <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="allowHyperlinks">A value indicating whether to HTML hyperlink tags could be rendered (if required)</param> /// <returns>Attributes</returns> public virtual string FormatAttributes(string attributesXml, Customer customer, string separator = "<br />", bool htmlEncode = true, bool renderPrices = true, bool allowHyperlinks = true) { var result = new StringBuilder(); var attributes = _checkoutAttributeParser.ParseCheckoutAttributes(attributesXml); for (var i = 0; i < attributes.Count; i++) { var attribute = attributes[i]; var valuesStr = _checkoutAttributeParser.ParseValues(attributesXml, attribute.Id); for (var j = 0; j < valuesStr.Count; j++) { var valueStr = valuesStr[j]; var formattedAttribute = ""; if (!attribute.ShouldHaveValues()) { //no values if (attribute.AttributeControlType == AttributeControlType.MultilineTextbox) { //multiline textbox var attributeName = _localizationService.GetLocalized(attribute, a => a.Name, _workContext.WorkingLanguage.Id); //encode (if required) if (htmlEncode) { attributeName = WebUtility.HtmlEncode(attributeName); } formattedAttribute = $"{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.TryParse(valueStr, out Guid 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 = $"{download.Filename ?? download.DownloadGuid.ToString()}{download.Extension}"; //encode (if required) if (htmlEncode) { fileName = WebUtility.HtmlEncode(fileName); } if (allowHyperlinks) { //hyperlinks are allowed var downloadLink = $"{_webHelper.GetStoreLocation(false)}download/getfileupload/?downloadId={download.DownloadGuid}"; attributeText = $"<a href=\"{downloadLink}\" class=\"fileuploadattribute\">{fileName}</a>"; } else { //hyperlinks aren't allowed attributeText = fileName; } var attributeName = _localizationService.GetLocalized(attribute, 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, a => a.Name, _workContext.WorkingLanguage.Id)}: {valueStr}"; //encode (if required) if (htmlEncode) { formattedAttribute = WebUtility.HtmlEncode(formattedAttribute); } } } else { if (int.TryParse(valueStr, out int attributeValueId)) { var attributeValue = _checkoutAttributeService.GetCheckoutAttributeValueById(attributeValueId); if (attributeValue != null) { formattedAttribute = $"{_localizationService.GetLocalized(attribute, a => a.Name, _workContext.WorkingLanguage.Id)}: {_localizationService.GetLocalized(attributeValue, a => a.Name, _workContext.WorkingLanguage.Id)}"; if (renderPrices) { var priceAdjustmentBase = _taxService.GetCheckoutAttributePrice(attributeValue, customer); var priceAdjustment = _currencyService.ConvertFromPrimaryStoreCurrency(priceAdjustmentBase, _workContext.WorkingCurrency); if (priceAdjustmentBase > 0) { var priceAdjustmentStr = _priceFormatter.FormatPrice(priceAdjustment); formattedAttribute += $" [+{priceAdjustmentStr}]"; } } } //encode (if required) if (htmlEncode) { formattedAttribute = WebUtility.HtmlEncode(formattedAttribute); } } } if (!string.IsNullOrEmpty(formattedAttribute)) { if (i != 0 || j != 0) { result.Append(separator); } result.Append(formattedAttribute); } } } return(result.ToString()); }
/// <summary> /// Formats attributes /// </summary> /// <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="allowHyperlinks">A value indicating whether to HTML hyperlink tags could be rendered (if required)</param> /// <returns> /// A task that represents the asynchronous operation /// The task result contains the attributes /// </returns> public virtual async Task <string> FormatAttributesAsync(string attributesXml, Customer customer, string separator = "<br />", bool htmlEncode = true, bool renderPrices = true, bool allowHyperlinks = true) { var result = new StringBuilder(); var attributes = await _checkoutAttributeParser.ParseCheckoutAttributesAsync(attributesXml); for (var i = 0; i < attributes.Count; i++) { var attribute = attributes[i]; var valuesStr = _checkoutAttributeParser.ParseValues(attributesXml, attribute.Id); for (var j = 0; j < valuesStr.Count; j++) { var valueStr = valuesStr[j]; var formattedAttribute = string.Empty; if (!attribute.ShouldHaveValues()) { //no values if (attribute.AttributeControlType == AttributeControlType.MultilineTextbox) { //multiline textbox var attributeName = await _localizationService.GetLocalizedAsync(attribute, a => a.Name, (await _workContext.GetWorkingLanguageAsync()).Id); //encode (if required) if (htmlEncode) { attributeName = WebUtility.HtmlEncode(attributeName); } formattedAttribute = $"{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.TryParse(valueStr, out var downloadGuid); var download = await _downloadService.GetDownloadByGuidAsync(downloadGuid); if (download != null) { string attributeText; var fileName = $"{download.Filename ?? download.DownloadGuid.ToString()}{download.Extension}"; //encode (if required) if (htmlEncode) { fileName = WebUtility.HtmlEncode(fileName); } if (allowHyperlinks) { //hyperlinks are allowed var downloadLink = $"{_webHelper.GetStoreLocation(false)}download/getfileupload/?downloadId={download.DownloadGuid}"; attributeText = $"<a href=\"{downloadLink}\" class=\"fileuploadattribute\">{fileName}</a>"; } else { //hyperlinks aren't allowed attributeText = fileName; } var attributeName = await _localizationService.GetLocalizedAsync(attribute, a => a.Name, (await _workContext.GetWorkingLanguageAsync()).Id); //encode (if required) if (htmlEncode) { attributeName = WebUtility.HtmlEncode(attributeName); } formattedAttribute = $"{attributeName}: {attributeText}"; } } else { //other attributes (textbox, datepicker) formattedAttribute = $"{await _localizationService.GetLocalizedAsync(attribute, a => a.Name, (await _workContext.GetWorkingLanguageAsync()).Id)}: {valueStr}"; //encode (if required) if (htmlEncode) { formattedAttribute = WebUtility.HtmlEncode(formattedAttribute); } } } else { if (int.TryParse(valueStr, out var attributeValueId)) { var attributeValue = await _checkoutAttributeService.GetCheckoutAttributeValueByIdAsync(attributeValueId); if (attributeValue != null) { formattedAttribute = $"{await _localizationService.GetLocalizedAsync(attribute, a => a.Name, (await _workContext.GetWorkingLanguageAsync()).Id)}: {await _localizationService.GetLocalizedAsync(attributeValue, a => a.Name, (await _workContext.GetWorkingLanguageAsync()).Id)}"; if (renderPrices) { var priceAdjustmentBase = (await _taxService.GetCheckoutAttributePriceAsync(attribute, attributeValue, customer)).price; var priceAdjustment = await _currencyService.ConvertFromPrimaryStoreCurrencyAsync(priceAdjustmentBase, await _workContext.GetWorkingCurrencyAsync()); if (priceAdjustmentBase > 0) { formattedAttribute += string.Format( await _localizationService.GetResourceAsync("FormattedAttributes.PriceAdjustment"), "+", await _priceFormatter.FormatPriceAsync(priceAdjustment), string.Empty); } } } //encode (if required) if (htmlEncode) { formattedAttribute = WebUtility.HtmlEncode(formattedAttribute); } } } if (string.IsNullOrEmpty(formattedAttribute)) { continue; } if (i != 0 || j != 0) { result.Append(separator); } result.Append(formattedAttribute); } } return(result.ToString()); }
public virtual void PrepareShoppingCartModel(ShoppingCartModel model, IList <ShoppingCartItem> cart, bool isEditable = true, bool validateCheckoutAttributes = false, bool prepareEstimateShippingIfEnabled = true, bool setEstimateShippingDefaultAddress = true, bool prepareAndDisplayOrderReviewData = false) { if (cart == null) { throw new ArgumentNullException("cart"); } if (model == null) { throw new ArgumentNullException("model"); } model.OnePageCheckoutEnabled = _orderSettings.OnePageCheckoutEnabled; if (cart.Count == 0) { return; } #region Simple properties model.IsEditable = isEditable; model.ShowProductImages = _shoppingCartSettings.ShowProductImagesOnShoppingCart; model.ShowSku = _catalogSettings.ShowProductSku; var checkoutAttributesXml = _workContext.CurrentCustomer.GetAttribute <string>(SystemCustomerAttributeNames.CheckoutAttributes, _genericAttributeService, _storeContext.CurrentStore.Id); model.CheckoutAttributeInfo = _checkoutAttributeFormatter.FormatAttributes(checkoutAttributesXml, _workContext.CurrentCustomer); bool minOrderSubtotalAmountOk = _orderProcessingService.ValidateMinOrderSubtotalAmount(cart); if (!minOrderSubtotalAmountOk) { decimal minOrderSubtotalAmount = _currencyService.ConvertFromPrimaryStoreCurrency(_orderSettings.MinOrderSubtotalAmount, _workContext.WorkingCurrency); model.MinOrderSubtotalWarning = string.Format(_localizationService.GetResource("Checkout.MinOrderSubtotalAmount"), _priceFormatter.FormatPrice(minOrderSubtotalAmount, true, false)); } model.TermsOfServiceOnShoppingCartPage = _orderSettings.TermsOfServiceOnShoppingCartPage; model.TermsOfServiceOnOrderConfirmPage = _orderSettings.TermsOfServiceOnOrderConfirmPage; //gift card and gift card boxes model.DiscountBox.Display = _shoppingCartSettings.ShowDiscountBox; var discountCouponCode = _workContext.CurrentCustomer.GetAttribute <string>(SystemCustomerAttributeNames.DiscountCouponCode); var discount = _discountService.GetDiscountByCouponCode(discountCouponCode); if (discount != null && discount.RequiresCouponCode && _discountService.IsDiscountValid(discount, _workContext.CurrentCustomer)) { model.DiscountBox.CurrentCode = discount.CouponCode; } model.GiftCardBox.Display = _shoppingCartSettings.ShowGiftCardBox; //cart warnings var cartWarnings = _shoppingCartService.GetShoppingCartWarnings(cart, checkoutAttributesXml, validateCheckoutAttributes); foreach (var warning in cartWarnings) { model.Warnings.Add(warning); } #endregion #region Checkout attributes var checkoutAttributes = _checkoutAttributeService.GetAllCheckoutAttributes(_storeContext.CurrentStore.Id, !cart.RequiresShipping()); foreach (var attribute in checkoutAttributes) { var attributeModel = new ShoppingCartModel.CheckoutAttributeModel { Id = attribute.Id, Name = attribute.GetLocalized(x => x.Name), TextPrompt = attribute.GetLocalized(x => x.TextPrompt), IsRequired = attribute.IsRequired, AttributeControlType = attribute.AttributeControlType, DefaultValue = attribute.DefaultValue }; if (!String.IsNullOrEmpty(attribute.ValidationFileAllowedExtensions)) { attributeModel.AllowedFileExtensions = attribute.ValidationFileAllowedExtensions .Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries) .ToList(); } if (attribute.ShouldHaveValues()) { //values var attributeValues = _checkoutAttributeService.GetCheckoutAttributeValues(attribute.Id); foreach (var attributeValue in attributeValues) { var attributeValueModel = new ShoppingCartModel.CheckoutAttributeValueModel { Id = attributeValue.Id, Name = attributeValue.GetLocalized(x => x.Name), ColorSquaresRgb = attributeValue.ColorSquaresRgb, IsPreSelected = attributeValue.IsPreSelected, }; attributeModel.Values.Add(attributeValueModel); //display price if allowed if (_permissionService.Authorize(StandardPermissionProvider.DisplayPrices)) { decimal priceAdjustmentBase = _taxService.GetCheckoutAttributePrice(attributeValue); decimal priceAdjustment = _currencyService.ConvertFromPrimaryStoreCurrency(priceAdjustmentBase, _workContext.WorkingCurrency); if (priceAdjustmentBase > decimal.Zero) { attributeValueModel.PriceAdjustment = "+" + _priceFormatter.FormatPrice(priceAdjustment); } else if (priceAdjustmentBase < decimal.Zero) { attributeValueModel.PriceAdjustment = "-" + _priceFormatter.FormatPrice(-priceAdjustment); } } } } //set already selected attributes var selectedCheckoutAttributes = _workContext.CurrentCustomer.GetAttribute <string>(SystemCustomerAttributeNames.CheckoutAttributes, _genericAttributeService, _storeContext.CurrentStore.Id); switch (attribute.AttributeControlType) { case AttributeControlType.DropdownList: case AttributeControlType.RadioList: case AttributeControlType.Checkboxes: case AttributeControlType.ColorSquares: { if (!String.IsNullOrEmpty(selectedCheckoutAttributes)) { //clear default selection foreach (var item in attributeModel.Values) { item.IsPreSelected = false; } //select new values var selectedValues = _checkoutAttributeParser.ParseCheckoutAttributeValues(selectedCheckoutAttributes); 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(selectedCheckoutAttributes)) { var enteredText = _checkoutAttributeParser.ParseValues(selectedCheckoutAttributes, 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 = _checkoutAttributeParser.ParseValues(selectedCheckoutAttributes, 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; default: break; } model.CheckoutAttributes.Add(attributeModel); } #endregion #region Estimate shipping if (prepareEstimateShippingIfEnabled) { model.EstimateShipping.Enabled = cart.Count > 0 && cart.RequiresShipping() && _shippingSettings.EstimateShippingEnabled; if (model.EstimateShipping.Enabled) { //countries int?defaultEstimateCountryId = (setEstimateShippingDefaultAddress && _workContext.CurrentCustomer.ShippingAddress != null) ? _workContext.CurrentCustomer.ShippingAddress.CountryId : model.EstimateShipping.CountryId; model.EstimateShipping.AvailableCountries.Add(new SelectListItem { Text = _localizationService.GetResource("Address.SelectCountry"), Value = "0" }); foreach (var c in _countryService.GetAllCountriesForShipping()) { model.EstimateShipping.AvailableCountries.Add(new SelectListItem { Text = c.GetLocalized(x => x.Name), Value = c.Id.ToString(), Selected = c.Id == defaultEstimateCountryId }); } //states int?defaultEstimateStateId = (setEstimateShippingDefaultAddress && _workContext.CurrentCustomer.ShippingAddress != null) ? _workContext.CurrentCustomer.ShippingAddress.StateProvinceId : model.EstimateShipping.StateProvinceId; var states = defaultEstimateCountryId.HasValue ? _stateProvinceService.GetStateProvincesByCountryId(defaultEstimateCountryId.Value).ToList() : new List <StateProvince>(); if (states.Count > 0) { foreach (var s in states) { model.EstimateShipping.AvailableStates.Add(new SelectListItem { Text = s.GetLocalized(x => x.Name), Value = s.Id.ToString(), Selected = s.Id == defaultEstimateStateId }); } } else { model.EstimateShipping.AvailableStates.Add(new SelectListItem { Text = _localizationService.GetResource("Address.OtherNonUS"), Value = "0" }); } if (setEstimateShippingDefaultAddress && _workContext.CurrentCustomer.ShippingAddress != null) { model.EstimateShipping.ZipPostalCode = _workContext.CurrentCustomer.ShippingAddress.ZipPostalCode; } } } #endregion #region Cart items foreach (var sci in cart) { var cartItemModel = new ShoppingCartModel.ShoppingCartItemModel { Id = sci.Id, Sku = sci.Product.FormatSku(sci.AttributesXml, _productAttributeParser), ProductId = sci.Product.Id, ProductName = sci.Product.GetLocalized(x => x.Name), ProductSeName = sci.Product.GetSeName(), Quantity = sci.Quantity, AttributeInfo = _productAttributeFormatter.FormatAttributes(sci.Product, sci.AttributesXml), }; //allow editing? //1. setting enabled? //2. simple product? //3. has attribute or gift card? //4. visible individually? cartItemModel.AllowItemEditing = _shoppingCartSettings.AllowCartItemEditing && sci.Product.ProductType == ProductType.SimpleProduct && (!String.IsNullOrEmpty(cartItemModel.AttributeInfo) || sci.Product.IsGiftCard) && sci.Product.VisibleIndividually; //allowed quantities var allowedQuantities = sci.Product.ParseAllowedQuatities(); foreach (var qty in allowedQuantities) { cartItemModel.AllowedQuantities.Add(new SelectListItem { Text = qty.ToString(), Value = qty.ToString(), Selected = sci.Quantity == qty }); } //recurring info if (sci.Product.IsRecurring) { cartItemModel.RecurringInfo = string.Format(_localizationService.GetResource("ShoppingCart.RecurringPeriod"), sci.Product.RecurringCycleLength, sci.Product.RecurringCyclePeriod.GetLocalizedEnum(_localizationService, _workContext)); } //rental info if (sci.Product.IsRental) { var rentalStartDate = sci.RentalStartDateUtc.HasValue ? sci.Product.FormatRentalDate(sci.RentalStartDateUtc.Value) : ""; var rentalEndDate = sci.RentalEndDateUtc.HasValue ? sci.Product.FormatRentalDate(sci.RentalEndDateUtc.Value) : ""; cartItemModel.RentalInfo = string.Format(_localizationService.GetResource("ShoppingCart.Rental.FormattedDate"), rentalStartDate, rentalEndDate); } //unit prices if (sci.Product.CallForPrice) { cartItemModel.UnitPrice = _localizationService.GetResource("Products.CallForPrice"); } else { decimal taxRate; decimal shoppingCartUnitPriceWithDiscountBase = _taxService.GetProductPrice(sci.Product, _priceCalculationService.GetUnitPrice(sci), out taxRate); decimal shoppingCartUnitPriceWithDiscount = _currencyService.ConvertFromPrimaryStoreCurrency(shoppingCartUnitPriceWithDiscountBase, _workContext.WorkingCurrency); cartItemModel.UnitPrice = _priceFormatter.FormatPrice(shoppingCartUnitPriceWithDiscount); } //subtotal, discount if (sci.Product.CallForPrice) { cartItemModel.SubTotal = _localizationService.GetResource("Products.CallForPrice"); } else { //sub total Discount scDiscount; decimal shoppingCartItemDiscountBase; decimal taxRate; decimal shoppingCartItemSubTotalWithDiscountBase = _taxService.GetProductPrice(sci.Product, _priceCalculationService.GetSubTotal(sci, true, out shoppingCartItemDiscountBase, out scDiscount), out taxRate); decimal shoppingCartItemSubTotalWithDiscount = _currencyService.ConvertFromPrimaryStoreCurrency(shoppingCartItemSubTotalWithDiscountBase, _workContext.WorkingCurrency); cartItemModel.SubTotal = _priceFormatter.FormatPrice(shoppingCartItemSubTotalWithDiscount); //display an applied discount amount if (scDiscount != null) { shoppingCartItemDiscountBase = _taxService.GetProductPrice(sci.Product, shoppingCartItemDiscountBase, out taxRate); if (shoppingCartItemDiscountBase > decimal.Zero) { decimal shoppingCartItemDiscount = _currencyService.ConvertFromPrimaryStoreCurrency(shoppingCartItemDiscountBase, _workContext.WorkingCurrency); cartItemModel.Discount = _priceFormatter.FormatPrice(shoppingCartItemDiscount); } } } //item warnings var itemWarnings = _shoppingCartService.GetShoppingCartItemWarnings( _workContext.CurrentCustomer, sci.ShoppingCartType, sci.Product, sci.StoreId, sci.AttributesXml, sci.CustomerEnteredPrice, sci.RentalStartDateUtc, sci.RentalEndDateUtc, sci.Quantity, false); foreach (var warning in itemWarnings) { cartItemModel.Warnings.Add(warning); } model.Items.Add(cartItemModel); } #endregion #region Button payment methods var paymentMethods = _paymentService .LoadActivePaymentMethods(_workContext.CurrentCustomer.Id, _storeContext.CurrentStore.Id) .Where(pm => pm.PaymentMethodType == PaymentMethodType.Button) .Where(pm => !pm.HidePaymentMethod(cart)) .ToList(); foreach (var pm in paymentMethods) { if (cart.IsRecurring() && pm.RecurringPaymentType == RecurringPaymentType.NotSupported) { continue; } string actionName; string controllerName; RouteValueDictionary routeValues; pm.GetPaymentInfoRoute(out actionName, out controllerName, out routeValues); model.ButtonPaymentMethodActionNames.Add(actionName); model.ButtonPaymentMethodControllerNames.Add(controllerName); model.ButtonPaymentMethodRouteValues.Add(routeValues); } #endregion #region Order review data if (prepareAndDisplayOrderReviewData) { model.OrderReviewData.Display = true; //billing info var billingAddress = _workContext.CurrentCustomer.BillingAddress; if (billingAddress != null) { model.OrderReviewData.BillingAddress.PrepareModel( address: billingAddress, excludeProperties: false, addressSettings: _addressSettings, addressAttributeFormatter: _addressAttributeFormatter); } //shipping info if (cart.RequiresShipping()) { model.OrderReviewData.IsShippable = true; if (_shippingSettings.AllowPickUpInStore) { model.OrderReviewData.SelectedPickUpInStore = _workContext.CurrentCustomer.GetAttribute <bool>(SystemCustomerAttributeNames.SelectedPickUpInStore, _storeContext.CurrentStore.Id); } if (!model.OrderReviewData.SelectedPickUpInStore) { var shippingAddress = _workContext.CurrentCustomer.ShippingAddress; if (shippingAddress != null) { model.OrderReviewData.ShippingAddress.PrepareModel( address: shippingAddress, excludeProperties: false, addressSettings: _addressSettings, addressAttributeFormatter: _addressAttributeFormatter); } } //selected shipping method var shippingOption = _workContext.CurrentCustomer.GetAttribute <ShippingOption>(SystemCustomerAttributeNames.SelectedShippingOption, _storeContext.CurrentStore.Id); if (shippingOption != null) { model.OrderReviewData.ShippingMethod = shippingOption.Name; } } //payment info var selectedPaymentMethodSystemName = _workContext.CurrentCustomer.GetAttribute <string>( SystemCustomerAttributeNames.SelectedPaymentMethod, _storeContext.CurrentStore.Id); var paymentMethod = _paymentService.LoadPaymentMethodBySystemName(selectedPaymentMethodSystemName); model.OrderReviewData.PaymentMethod = paymentMethod != null?paymentMethod.GetLocalizedFriendlyName(_localizationService, _workContext.WorkingLanguage.Id) : ""; } #endregion }
/// <summary> /// Formats attributes /// </summary> /// <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> /// <returns>Attributes</returns> public string FormatAttributes(string attributes, Customer customer, string serapator = "<br />", bool htmlEncode = true, bool renderPrices = true) { var result = new StringBuilder(); var caCollection = _checkoutAttributeParser.ParseCheckoutAttributes(attributes); for (int i = 0; i < caCollection.Count; i++) { var ca = caCollection[i]; var valuesStr = _checkoutAttributeParser.ParseValues(attributes, ca.Id); for (int j = 0; j < valuesStr.Count; j++) { string valueStr = valuesStr[j]; string caAttribute = string.Empty; if (!ca.ShouldHaveValues()) { if (ca.AttributeControlType == AttributeControlType.MultilineTextbox) { caAttribute = string.Format("{0}: {1}", ca.GetLocalized(a => a.Name, _workContext.WorkingLanguage.Id), HtmlHelper.FormatText(valueStr, false, true, true, false, false, false)); } else { caAttribute = string.Format("{0}: {1}", ca.GetLocalized(a => a.Name, _workContext.WorkingLanguage.Id), valueStr); } } else { int caId = 0; if (int.TryParse(valueStr, out caId)) { var caValue = _checkoutAttributeService.GetCheckoutAttributeValueById(caId); if (caValue != null) { caAttribute = string.Format("{0}: {1}", ca.GetLocalized(a => a.Name, _workContext.WorkingLanguage.Id), caValue.GetLocalized(a => a.Name, _workContext.WorkingLanguage.Id)); if (renderPrices) { decimal priceAdjustmentBase = _taxService.GetCheckoutAttributePrice(caValue, customer); decimal priceAdjustment = _currencyService.ConvertFromPrimaryStoreCurrency(priceAdjustmentBase, _workContext.WorkingCurrency); if (priceAdjustmentBase > 0) { string priceAdjustmentStr = _priceFormatter.FormatPrice(priceAdjustment); caAttribute += string.Format(" [+{0}]", priceAdjustmentStr); } } } } } if (!String.IsNullOrEmpty(caAttribute)) { if (i != 0 || j != 0) { result.Append(serapator); } //we don't encode multiline textbox input if (htmlEncode && ca.AttributeControlType != AttributeControlType.MultilineTextbox) { result.Append(HttpUtility.HtmlEncode(caAttribute)); } else { result.Append(caAttribute); } } } } return(result.ToString()); }