Error compiling template "Designs/Swift/Paragraph/Swift_ProductDetailsInfo.cshtml" Line 39: 'TemplatesHelper.IsWebServiceConnectionAvailable()' is obsolete: 'Use Context.Current.Items["IsWebServiceConnectionAvailable"] instead' Line 139: 'TemplatesHelper.IsLazyLoadingForProductInfoEnabled' is obsolete: 'Use Context.Current.Items["IsLazyLoadingForProductInfoEnabled"] instead' Line 300: The name 'RenderField' does not exist in the current context Line 841: The name 'helper' does not exist in the current context Line 859: The name 'field' does not exist in the current context Line 861: The name 'RenderFieldValue' does not exist in the current context Line 861: The name 'field' does not exist in the current context Line 863: The name 'helper' does not exist in the current context Line 892: The name 'option' does not exist in the current context Line 896: The name 'option' does not exist in the current context Line 899: The name 'option' does not exist in the current context Line 928: The name 'fieldValue' does not exist in the current context Line 932: The name 'fieldValue' does not exist in the current context Line 935: The name 'fieldValue' does not exist in the current context
1 // <auto-generated/> 2 #pragma warning disable 1591 3 namespace CompiledRazorTemplates.Dynamic 4 { 5 #line hidden 6 using System.Threading.Tasks; 7 using System; 8 using System.Collections.Generic; 9 using System.Linq; 10 using Dynamicweb.Ecommerce.ProductCatalog; 11 using Dynamicweb.Ecommerce.CustomerExperienceCenter.Favorites; 12 using Dynamicweb.Ecommerce.Products.FieldDisplayGroups; 13 using Dynamicweb.Frontend; 14 using Dynamicweb.Core; 15 using System.Drawing; 16 using Dynamicweb.Environment; 17 internal class RazorEngine_18c5acafdd184b80bdd3798869244466 : Dynamicweb.Rendering.ViewModelTemplate<Dynamicweb.Frontend.ParagraphViewModel> 18 { 19 #pragma warning disable 1998 20 public async override global::System.Threading.Tasks.Task ExecuteAsync() 21 { 22 WriteLiteral("\n"); 23 WriteLiteral("\n"); 24 string googleAnalyticsTrackingID = Pageview.AreaSettings.GetString("GoogleAnalyticsTrackingID"); string googleAnalyticsMeasurementID = Pageview.AreaSettings.GetString("GoogleAnalyticsMeasurementID"); var cookieOptInLevel = CookieManager.GetCookieOptInLevel(); bool allowTracking = cookieOptInLevel == CookieOptInLevel.All || (cookieOptInLevel == CookieOptInLevel.Functional && CookieManager.GetCookieOptInCategories().Contains("Statistical")); ProductViewModel product = new ProductViewModel(); if (Dynamicweb.Context.Current.Items.Contains("ProductDetails")) { product = (ProductViewModel)Dynamicweb.Context.Current.Items["ProductDetails"]; } string anonymousUsersLimitations = Pageview.AreaSettings.GetRawValueString("AnonymousUsers", ""); bool anonymousUser = Pageview.User == null; bool isErpConnectionDown = !Dynamicweb.Ecommerce.DynamicwebLiveIntegration.TemplatesHelper.IsWebServiceConnectionAvailable(); bool hideAddToCart = anonymousUsersLimitations.Contains("cart") && anonymousUser || Pageview.AreaSettings.GetBoolean("ErpDownHideAddToCart") && isErpConnectionDown; hideAddToCart = product?.VariantInfo?.VariantInfo != null && Model.Item.GetBoolean("HideVariantSelector") ? true : hideAddToCart; bool hideStock = Model.Item.GetBoolean("HideStockState") || (Pageview.AreaSettings.GetBoolean("ErpDownHideStock") && isErpConnectionDown); bool hidePrice = anonymousUsersLimitations.Contains("price") && anonymousUser || Pageview.AreaSettings.GetBoolean("ErpDownHidePrices") && isErpConnectionDown; bool hideFavoritesSelector = !string.IsNullOrEmpty(Model.Item.GetString("HideFavoritesSelector")) ? Model.Item.GetBoolean("HideFavoritesSelector") : false; bool showFavoritesSelectorMasterProduct = !string.IsNullOrEmpty(Model.Item.GetString("ShowFavoritesSelectorMasterProduct")) ? Model.Item.GetBoolean("ShowFavoritesSelectorMasterProduct") : false; bool isDiscontinued = product.Discontinued; bool IsNeverOutOfStock = product.NeverOutOfstock; string[] variantId = { }; if (product?.VariantId != null) { variantId = product.VariantId.Split('.'); } string disableAddToCart = (product.StockLevel <= 0) ? "disabled" : ""; disableAddToCart = isDiscontinued ? "disabled" : disableAddToCart; disableAddToCart = IsNeverOutOfStock ? "" : disableAddToCart; // Does product has a expected delivery data bool hasExpectedDelivery = product.ExpectedDelivery != null && product.ExpectedDelivery > DateTime.Now; string expectedDeliveryDate = product.ExpectedDelivery?.ToShortDateString() ?? ""; string url = "/Default.aspx?ID=" + (GetPageIdByNavigationTag("CartService")); if (!url.Contains("LayoutTemplate")) { url += url.Contains("?") ? "&LayoutTemplate=Swift_MiniCart.cshtml" : "?LayoutTemplate=Swift_MiniCart.cshtml"; } IEnumerable<string> selectedDisplayGroups = Model.Item.GetRawValueString("MainFeatures").Split(',').ToList(); List<CategoryFieldViewModel> mainFeatures = new List<CategoryFieldViewModel>(); foreach (var selection in selectedDisplayGroups) { foreach (CategoryFieldViewModel group in product.FieldDisplayGroups.Values) { if (selection == group.Id) { mainFeatures.Add(group); } } } string theme = !string.IsNullOrWhiteSpace(Model.Item.GetRawValueString("Theme")) ? " theme " + Model.Item.GetRawValueString("Theme").Replace(" ", "").Trim().ToLower() : ""; string titleFontSize = Model.Item.GetRawValueString("TitleFontSize", "display-6"); string contentPadding = Model.Item.GetRawValueString("ContentPadding", ""); contentPadding = contentPadding == "small" ? "p-2 p-md-3" : contentPadding; contentPadding = contentPadding == "large" ? "p-4 p-md-5" : contentPadding; string quantityPricesLayout = Model.Item.GetRawValueString("QuantityPricesLayout", "list"); string minQty = product.PurchaseMinimumQuantity != 1 ? "min=\"" + product.PurchaseMinimumQuantity.ToString() + "\"" : "min=\"1\""; string stepQty = product.PurchaseQuantityStep > 1 ? product.PurchaseQuantityStep.ToString() : "1"; string valueQty = product.PurchaseMinimumQuantity > product.PurchaseQuantityStep ? product.PurchaseMinimumQuantity.ToString() : stepQty; string qtyValidCheck = stepQty != "1" ? "onkeyup=\"swift.Cart.QuantityValidate(event)\"" : ""; string showPricesWithVat = Pageview.Area.EcomPricesWithVat.ToLower(); bool neverShowVat = string.IsNullOrEmpty(showPricesWithVat); string priceMin = ""; string priceMax = ""; var favoriteParameters = new Dictionary<string, object>(); if (!anonymousUser && !hideFavoritesSelector) { IEnumerable<FavoriteList> favoreiteLists = Pageview.User.GetFavoriteLists(); int defaultFavoriteListId = 0; if (favoreiteLists.Count() == 1) { foreach (FavoriteList list in favoreiteLists) { defaultFavoriteListId = list.ListId; } } favoriteParameters.Add("ListId", defaultFavoriteListId); } var priceParms = new Dictionary<string, object>(); priceParms.Add("theme", ""); var badgeParms = new Dictionary<string, object>(); badgeParms.Add("size", "h7"); badgeParms.Add("saleBadgeType", Model.Item.GetRawValue("SaleBadgeType")); badgeParms.Add("saleBadgeCssClassName", Model.Item.GetRawValue("SaleBadgeDesign")); badgeParms.Add("newBadgeCssClassName", Model.Item.GetRawValue("NewBadgeDesign")); badgeParms.Add("newPublicationDays", Model.Item.GetInt32("NewPublicationDays")); badgeParms.Add("campaignBadgesValues", Model.Item.GetRawValueString("CampaignBadges")); bool saleBadgeEnabled = !string.IsNullOrWhiteSpace(Model.Item.GetRawValueString("SaleBadgeDesign")) && Model.Item.GetRawValueString("SaleBadgeDesign") != "none" ? true : false; bool newBadgeEnabled = !string.IsNullOrWhiteSpace(Model.Item.GetRawValueString("NewBadgeDesign")) && Model.Item.GetRawValueString("NewBadgeDesign") != "none" ? true : false; DateTime createdDate = product.Created.Value; bool showBadges = saleBadgeEnabled && product.Discount.Price != 0 ? true : false; showBadges = (newBadgeEnabled && Model.Item.GetInt32("NewPublicationDays") == 0) || (newBadgeEnabled && (createdDate.AddDays(Model.Item.GetInt32("NewPublicationDays")) > DateTime.Now)) ? true : showBadges; showBadges = !string.IsNullOrEmpty(Model.Item.GetRawValueString("CampaignBadges")) ? true : showBadges; string liveInfoClass = ""; string productInfoFeed = ""; bool isLazyLoadingForProductInfoEnabled = Dynamicweb.Ecommerce.DynamicwebLiveIntegration.TemplatesHelper.IsLazyLoadingForProductInfoEnabled; if (isLazyLoadingForProductInfoEnabled) { if (Dynamicweb.Context.Current.Items.Contains("ProductInfoFeed")) { productInfoFeed = Dynamicweb.Context.Current.Items["ProductInfoFeed"]?.ToString(); if (!string.IsNullOrEmpty(productInfoFeed)) { productInfoFeed = $"data-product-info-feed=\"{productInfoFeed}\""; } } liveInfoClass = "js-live-info"; } WriteLiteral("\n"); 25 if (!string.IsNullOrWhiteSpace(googleAnalyticsMeasurementID) && allowTracking) { WriteLiteral("\t<script>\n\t\tgtag(\"event\", \"view_item\", {\n\t\t\tcurrency: \""); 26 Write(product.Price.CurrencyCode); 27 WriteLiteral("\",\n\t\t\tvalue: "); 28 Write(product.Price.Price); 29 WriteLiteral(",\n\t\t\titems: [\n\t\t\t{\n\t\t\t\titem_id: \""); 30 Write(product.Number); 31 WriteLiteral("\",\n\t\t\t\titem_name: \""); 32 Write(product.Name); 33 WriteLiteral("\",\n\t\t\t\tcurrency: \""); 34 Write(product.Price.CurrencyCode); 35 WriteLiteral("\",\n\t\t\t\tprice: "); 36 Write(product.Price.Price); 37 WriteLiteral("\n\t\t\t}\n\t\t\t]\n\t\t});\n\t</script>\n"); 38 } WriteLiteral("\n<div"); 39 BeginWriteAttribute("class", " class=\"", 7930, "\"", 8008, 5); 40 WriteAttributeValue("", 7938, "h-100", 7938, 5, true); 41 WriteAttributeValue(" ", 7943, contentPadding, 7944, 17, false); 42 WriteAttributeValue(" ", 7961, theme, 7962, 8, false); 43 WriteAttributeValue(" ", 7970, "item_", 7971, 6, true); 44 WriteAttributeValue("", 7976, Model.Item.SystemName.ToLower(), 7976, 32, false); 45 EndWriteAttribute(); 46 WriteLiteral(" "); 47 Write(productInfoFeed); 48 WriteLiteral(">\n\t<div class=\"d-flex flex-column gap-4 js-product\" data-product-id=\""); 49 Write(product.Id); 50 WriteLiteral("\">\n"); 51 if (showBadges) { WriteLiteral("\t\t\t<div class=\"swift_badge-collection\">\n\t\t\t\t"); 52 Write(RenderPartial("Components/EcommerceBadge.cshtml", product, badgeParms)); 53 WriteLiteral("\n\t\t\t</div>\n"); 54 } WriteLiteral("\n\t\t<div class=\"d-flex flex-column gap-2\">\n\t\t\t<h1"); 55 BeginWriteAttribute("class", " class=\"", 8308, "\"", 8334, 2); 56 WriteAttributeValue("", 8316, titleFontSize, 8316, 14, false); 57 WriteAttributeValue(" ", 8330, "m-0", 8331, 4, true); 58 EndWriteAttribute(); 59 WriteLiteral(" itemprop=\"name\">"); 60 Write(product.Name); 61 WriteLiteral("</h1>\n"); 62 if (!Model.Item.GetBoolean("HideProductNumber")) { Write(RenderPartial("Paragraph/Swift_ProductNumber.cshtml", Model)); 63 } WriteLiteral("\t\t</div>\n\n"); 64 if (!hidePrice && !isDiscontinued) { Write(RenderPartial("Paragraph/Swift_ProductPrice.cshtml", Model, priceParms)); 65 if (isLazyLoadingForProductInfoEnabled) { WriteLiteral("\t\t\t\t<div"); 66 BeginWriteAttribute("class", " class=\"", 8688, "\"", 8742, 3); 67 WriteAttributeValue("", 8696, "product-prices-container", 8696, 24, true); 68 WriteAttributeValue(" ", 8720, liveInfoClass, 8721, 14, false); 69 WriteAttributeValue(" ", 8735, "d-none", 8736, 7, true); 70 EndWriteAttribute(); 71 WriteLiteral(" data-show-if=\"LiveProductInfo.product.Prices.length > 0\">\n"); 72 if (quantityPricesLayout == "list") { WriteLiteral("\t\t\t\t\t\t<div class=\"mt-3 product-prices\">\n\t\t\t\t\t\t\t<small class=\"d-block opacity-75 product-prices-template\"><span><span class=\"js-text-price-quantity\"></span> "); 73 Write(Translate("PCS")); 74 WriteLiteral("</span> - <span class=\"fw-bold\"><span class=\"js-text-price-price\"></span> <span class=\"d-none\" data-show-if=\"LiveProductInfo.productPrice.Quantity > 1\">"); 75 Write(Translate("pr. PCS")); 76 WriteLiteral("</span></span></small>\n\t\t\t\t\t\t</div>\n"); 77 } else if (quantityPricesLayout == "table") { WriteLiteral("\t\t\t\t\t\t<div class=\"grid\">\n\t\t\t\t\t\t\t<table class=\"table table-sm mt-3 g-col-12 g-col-lg-6\">\n\t\t\t\t\t\t\t\t<thead>\n\t\t\t\t\t\t\t\t<tr>\n\t\t\t\t\t\t\t\t\t<td>"); 78 Write(Translate("QTY")); 79 WriteLiteral("</td>\n\t\t\t\t\t\t\t\t\t<td>"); 80 Write(Translate("pr. PCS")); 81 WriteLiteral(@"</td> </tr> </thead> <tbody class=""product-prices""> <tr class=""product-prices-template""> <td class=""js-text-price-quantity""></td> <td class=""js-text-price-price""></td> </tr> </tbody> </table> </div> "); 82 } WriteLiteral("\t\t\t\t</div>\n"); 83 } else { if (product.Prices.Count > 0) { WriteLiteral("\t\t\t\t\t<div>\n"); 84 if (quantityPricesLayout == "list") { WriteLiteral("\t\t\t\t\t\t\t<div class=\"mt-3\">\n"); 85 foreach (PriceListViewModel quantityPrice in product.Prices) { string quantityLabel = Translate("PCS"); string quantityPriceSuffix = quantityPrice.Quantity > 1 ? Translate("pr. PCS") : ""; WriteLiteral("\t\t\t\t\t\t\t\t\t<small class=\"d-block opacity-75\"><span>"); 86 Write(quantityPrice.Quantity); 87 WriteLiteral(" "); 88 Write(quantityLabel); 89 WriteLiteral("</span> - <span class=\"fw-bold\">"); 90 Write(quantityPrice.Price.PriceFormatted); 91 WriteLiteral(" "); 92 Write(quantityPriceSuffix); 93 WriteLiteral("</span></small>\n"); 94 } WriteLiteral("\t\t\t\t\t\t\t</div>\n"); 95 } else if (quantityPricesLayout == "table") { WriteLiteral("\t\t\t\t\t\t\t<div class=\"grid\">\n\t\t\t\t\t\t\t\t<table class=\"table table-sm mt-3 g-col-12 g-col-lg-6\">\n\t\t\t\t\t\t\t\t\t<thead>\n\t\t\t\t\t\t\t\t\t<tr>\n\t\t\t\t\t\t\t\t\t\t<td>"); 96 Write(Translate("QTY")); 97 WriteLiteral("</td>\n\t\t\t\t\t\t\t\t\t\t<td>"); 98 Write(Translate("pr. PCS")); 99 WriteLiteral("</td>\n\t\t\t\t\t\t\t\t\t</tr>\n\t\t\t\t\t\t\t\t\t</thead>\n\t\t\t\t\t\t\t\t\t<tbody>\n"); 100 foreach (PriceListViewModel quantityPrice in product.Prices) { WriteLiteral("\t\t\t\t\t\t\t\t\t\t<tr>\n\t\t\t\t\t\t\t\t\t\t\t<td>"); 101 Write(quantityPrice.Quantity); 102 WriteLiteral("</td>\n\t\t\t\t\t\t\t\t\t\t\t<td>"); 103 Write(quantityPrice.Price.PriceFormatted); 104 WriteLiteral("</td>\n\t\t\t\t\t\t\t\t\t\t</tr>\n"); 105 } WriteLiteral("\t\t\t\t\t\t\t\t\t</tbody>\n\t\t\t\t\t\t\t\t</table>\n\t\t\t\t\t\t\t</div>\n"); 106 } WriteLiteral("\t\t\t\t\t</div>\n"); 107 } } } WriteLiteral("\n\t\t"); 108 Write(RenderPartial("Paragraph/Swift_ProductShortDescription.cshtml", Model)); 109 WriteLiteral("\n\n"); 110 if (mainFeatures.Count > 0) { foreach (CategoryFieldViewModel mainFeatureGroup in mainFeatures) { WriteLiteral("\t\t\t\t<dl class=\"grid gap-0\">\n"); 111 foreach (var field in mainFeatureGroup.Fields) { Write(RenderField(field.Value)); 112 } WriteLiteral("\t\t\t\t</dl>\n"); 113 } } WriteLiteral("\n"); 114 if (product.VariantInfo.VariantInfo != null && !Model.Item.GetBoolean("HideVariantSelector")) { int groupNumber = 1; string baseUrl = $"Default.aspx?ID={GetPageIdByNavigationTag("Shop")}&GroupID={product.PrimaryOrDefaultGroup.Id}&ProductID={product.Id}"; string variantUrl = ""; if (!string.IsNullOrEmpty(product.VariantId)) { variantUrl = Dynamicweb.Frontend.SearchEngineFriendlyURLs.GetFriendlyUrl($"Default.aspx?ID={GetPageIdByNavigationTag("Shop")}&GroupID={product.PrimaryOrDefaultGroup.Id}&ProductID={product.Id}&VariantID={product.VariantId}"); } WriteLiteral("\t\t\t<form class=\"js-variant-selector\" data-combinations=\""); 115 Write(string.Join(",", product.VariantCombinations())); 116 WriteLiteral("\" data-base-url=\""); 117 Write(baseUrl); 118 WriteLiteral("\" data-friendly-url=\""); 119 Write(variantUrl); 120 WriteLiteral("\">\n\t\t\t\t<input type=\"hidden\" name=\"variantid\">\n\n"); 121 foreach (var variantGroup in product.VariantGroups()) { VariantGroupViewModel group = variantGroup; WriteLiteral("\t\t\t\t\t<h3 class=\"h6\">"); 122 Write(group.Name); 123 WriteLiteral("</h3>\n\t\t\t\t\t<div class=\"d-flex gap-2 flex-wrap js-variant-group\" data-group-id=\""); 124 Write(groupNumber); 125 WriteLiteral("\">\n"); 126 foreach (var option in group.Options) { string active = variantId.Contains(option.Id) ? "active" : ""; if (!string.IsNullOrEmpty(option.Color)) { string contrastColor = GetContrastColor(option.Color); WriteLiteral("\t\t\t\t\t\t\t\t<button type=\"button\""); 127 BeginWriteAttribute("class", " class=\"", 12624, "\"", 12722, 8); 128 WriteAttributeValue("", 12632, "btn", 12632, 3, true); 129 WriteAttributeValue(" ", 12635, "colorbox", 12636, 9, true); 130 WriteAttributeValue(" ", 12644, "rounded-circle", 12645, 15, true); 131 WriteAttributeValue(" ", 12659, "d-inline-block", 12660, 15, true); 132 WriteAttributeValue(" ", 12674, "variant-option", 12675, 15, true); 133 WriteAttributeValue(" ", 12689, "border", 12690, 7, true); 134 WriteAttributeValue(" ", 12696, "js-variant-option", 12697, 18, true); 135 WriteAttributeValue(" ", 12714, active, 12715, 7, false); 136 EndWriteAttribute(); 137 BeginWriteAttribute("style", " style=\"", 12723, "\"", 12808, 5); 138 WriteAttributeValue("", 12731, "background-color:", 12731, 17, true); 139 WriteAttributeValue(" ", 12748, option.Color, 12749, 13, false); 140 WriteAttributeValue("", 12762, ";", 12762, 1, true); 141 WriteAttributeValue(" ", 12763, "--variantoption-check-color:", 12765, 30, true); 142 WriteAttributeValue(" ", 12793, contrastColor, 12794, 14, false); 143 EndWriteAttribute(); 144 WriteLiteral(" onclick=\"swift.VariantSelector.OptionClick(event)\" data-variant-id=\""); 145 Write(option.Id); 146 WriteLiteral("\""); 147 BeginWriteAttribute("id", " id=\"", 12889, "\"", 12950, 5); 148 WriteAttributeValue("", 12894, product.Id, 12894, 13, false); 149 WriteAttributeValue("", 12907, "_", 12907, 1, true); 150 WriteAttributeValue("", 12908, option.Id, 12908, 12, false); 151 WriteAttributeValue("", 12920, "_", 12920, 1, true); 152 WriteAttributeValue("", 12921, Pageview.CurrentParagraph.ID, 12921, 29, false); 153 EndWriteAttribute(); 154 WriteLiteral(">\n\t\t\t\t\t\t\t\t\t<span class=\"visually-hidden\">"); 155 Write(option.Name); 156 WriteLiteral("</span>\n\t\t\t\t\t\t\t\t</button>\n"); 157 } else if (!string.IsNullOrEmpty(option.Color) && !string.IsNullOrEmpty(option.Image.Value)) { WriteLiteral("\t\t\t\t\t\t\t\t<button type=\"button\""); 158 BeginWriteAttribute("class", " class=\"", 13175, "\"", 13253, 7); 159 WriteAttributeValue("", 13183, "btn", 13183, 3, true); 160 WriteAttributeValue(" ", 13186, "p-0", 13187, 4, true); 161 WriteAttributeValue(" ", 13190, "d-inline-block", 13191, 15, true); 162 WriteAttributeValue(" ", 13205, "variant-option", 13206, 15, true); 163 WriteAttributeValue(" ", 13220, "border", 13221, 7, true); 164 WriteAttributeValue(" ", 13227, "js-variant-option", 13228, 18, true); 165 WriteAttributeValue(" ", 13245, active, 13246, 7, false); 166 EndWriteAttribute(); 167 WriteLiteral(" onclick=\"swift.VariantSelector.OptionClick(event)\" data-variant-id=\""); 168 Write(option.Id); 169 WriteLiteral("\">\n\t\t\t\t\t\t\t\t\t<img"); 170 BeginWriteAttribute("src", " src=\"", 13349, "\"", 13442, 3); 171 WriteAttributeValue("", 13355, "/Admin/Public/GetImage.ashx?image=", 13355, 34, true); 172 WriteAttributeValue("", 13389, option.Image.Value, 13389, 21, false); 173 WriteAttributeValue("", 13410, "&width=42&Format=WebP&Quality=70", 13410, 32, true); 174 EndWriteAttribute(); 175 WriteLiteral(">\n\t\t\t\t\t\t\t\t</button>\n"); 176 } else { WriteLiteral("\t\t\t\t\t\t\t\t<button type=\"button\""); 177 BeginWriteAttribute("class", " class=\"", 13522, "\"", 13603, 6); 178 WriteAttributeValue("", 13530, "btn", 13530, 3, true); 179 WriteAttributeValue(" ", 13533, "btn-secondary", 13534, 14, true); 180 WriteAttributeValue(" ", 13547, "d-inline-block", 13548, 15, true); 181 WriteAttributeValue(" ", 13562, "variant-option", 13563, 15, true); 182 WriteAttributeValue(" ", 13577, "js-variant-option", 13578, 18, true); 183 WriteAttributeValue(" ", 13595, active, 13596, 7, false); 184 EndWriteAttribute(); 185 WriteLiteral(" onclick=\"swift.VariantSelector.OptionClick(event)\" data-variant-id=\""); 186 Write(option.Id); 187 WriteLiteral("\">\n\t\t\t\t\t\t\t\t\t"); 188 Write(option.Name); 189 WriteLiteral("\n\t\t\t\t\t\t\t\t</button>\n"); 190 } } WriteLiteral("\t\t\t\t\t</div>\n"); 191 groupNumber++; } WriteLiteral("\t\t\t</form>\n"); 192 } WriteLiteral("\n\t<div class=\"d-flex flex-row flex-nowrap gap-2\">\n"); 193 if (!hideAddToCart) { WriteLiteral("\t\t\t<form method=\"post\""); 194 BeginWriteAttribute("action", " action=\"", 13896, "\"", 13909, 1); 195 WriteAttributeValue("", 13905, url, 13905, 4, false); 196 EndWriteAttribute(); 197 WriteLiteral(" class=\"flex-fill\">\n\t\t\t\t<input type=\"hidden\" name=\"redirect\" value=\"false\">\n\t\t\t\t<input type=\"hidden\" name=\"ProductId\""); 198 BeginWriteAttribute("value", " value=\"", 14027, "\"", 14046, 1); 199 WriteAttributeValue("", 14035, product.Id, 14035, 11, false); 200 EndWriteAttribute(); 201 WriteLiteral(">\n\t\t\t\t<input type=\"hidden\" name=\"ProductName\""); 202 BeginWriteAttribute("value", " value=\"", 14092, "\"", 14113, 1); 203 WriteAttributeValue("", 14100, product.Name, 14100, 13, false); 204 EndWriteAttribute(); 205 WriteLiteral(">\n\t\t\t\t<input type=\"hidden\" name=\"ProductPrice\""); 206 BeginWriteAttribute("value", " value=\"", 14160, "\"", 14188, 1); 207 WriteAttributeValue("", 14168, product.Price.Price, 14168, 20, false); 208 EndWriteAttribute(); 209 WriteLiteral(">\n\t\t\t\t<input type=\"hidden\" name=\"ProductCurrency\""); 210 BeginWriteAttribute("value", " value=\"", 14238, "\"", 14273, 1); 211 WriteAttributeValue("", 14246, product.Price.CurrencyCode, 14246, 27, false); 212 EndWriteAttribute(); 213 WriteLiteral(">\n\t\t\t\t<input type=\"hidden\" name=\"ProductReferer\" value=\"product_details_info\">\n\t\t\t\t<input type=\"hidden\" name=\"cartcmd\" value=\"add\">\n\n"); 214 if (!string.IsNullOrEmpty(product.VariantId)) { WriteLiteral("\t\t\t\t\t<input type=\"hidden\" name=\"VariantId\""); 215 BeginWriteAttribute("value", " value=\"", 14506, "\"", 14532, 1); 216 WriteAttributeValue("", 14514, product.VariantId, 14514, 18, false); 217 EndWriteAttribute(); 218 WriteLiteral(">\n"); 219 } if (!Model.Item.GetBoolean("QuantitySelector")) { WriteLiteral("\t\t\t\t\t<input"); 220 BeginWriteAttribute("id", " id=\"", 14611, "\"", 14636, 2); 221 WriteAttributeValue("", 14616, "Quantity_", 14616, 9, true); 222 WriteAttributeValue("", 14625, product.Id, 14625, 11, false); 223 EndWriteAttribute(); 224 WriteLiteral(" name=\"Quantity\""); 225 BeginWriteAttribute("value", " value=\"", 14653, "\"", 14670, 1); 226 WriteAttributeValue("", 14661, valueQty, 14661, 9, false); 227 EndWriteAttribute(); 228 WriteLiteral(" type=\"hidden\" "); 229 Write(disableAddToCart); 230 WriteLiteral(">\n\t\t\t\t\t<button type=\"button\" onclick=\"swift.Cart.Update(event)\""); 231 BeginWriteAttribute("class", " class=\"", 14766, "\"", 14835, 5); 232 WriteAttributeValue("", 14774, "btn", 14774, 3, true); 233 WriteAttributeValue(" ", 14777, "btn-primary", 14778, 12, true); 234 WriteAttributeValue(" ", 14789, "w-100", 14790, 6, true); 235 WriteAttributeValue(" ", 14795, "js-add-to-cart-button", 14796, 22, true); 236 WriteAttributeValue(" ", 14817, disableAddToCart, 14818, 17, false); 237 EndWriteAttribute(); 238 WriteLiteral(" "); 239 Write(disableAddToCart); 240 WriteLiteral(" title=\""); 241 Write(Translate("Add to cart")); 242 WriteLiteral("\" id=\"AddToCartButton"); 243 Write(product.Id); 244 WriteLiteral("_"); 245 Write(Pageview.CurrentParagraph.ID); 246 WriteLiteral("\">"); 247 Write(Translate("Add to cart")); 248 WriteLiteral("</button>\n"); 249 } else { WriteLiteral("\t\t\t\t\t<div class=\"input-group input-primary-button-group js-input-group d-flex flex-row flex-nowrap\">\n\t\t\t\t\t\t<input"); 250 BeginWriteAttribute("id", " id=\"", 15115, "\"", 15140, 2); 251 WriteAttributeValue("", 15120, "Quantity_", 15120, 9, true); 252 WriteAttributeValue("", 15129, product.Id, 15129, 11, false); 253 EndWriteAttribute(); 254 WriteLiteral(" name=\"Quantity\""); 255 BeginWriteAttribute("value", " value=\"", 15157, "\"", 15174, 1); 256 WriteAttributeValue("", 15165, valueQty, 15165, 9, false); 257 EndWriteAttribute(); 258 BeginWriteAttribute("step", " step=\"", 15175, "\"", 15190, 1); 259 WriteAttributeValue("", 15182, stepQty, 15182, 8, false); 260 EndWriteAttribute(); 261 WriteLiteral(" "); 262 Write(minQty); 263 WriteLiteral(" class=\"form-control\" style=\"min-width: 60px; max-width: 100px;\" type=\"number\" onkeydown=\"swift.Cart.UpdateOnEnterKey(event)\" "); 264 Write(disableAddToCart); 265 WriteLiteral(">\n\t\t\t\t\t\t<button type=\"button\" onclick=\"swift.Cart.Update(event)\""); 266 BeginWriteAttribute("class", " class=\"", 15406, "\"", 15479, 5); 267 WriteAttributeValue("", 15414, "btn", 15414, 3, true); 268 WriteAttributeValue(" ", 15417, "btn-primary", 15418, 12, true); 269 WriteAttributeValue(" ", 15429, "flex-fill", 15430, 10, true); 270 WriteAttributeValue(" ", 15439, "js-add-to-cart-button", 15440, 22, true); 271 WriteAttributeValue(" ", 15461, disableAddToCart, 15462, 17, false); 272 EndWriteAttribute(); 273 WriteLiteral(" "); 274 Write(disableAddToCart); 275 WriteLiteral(" title=\""); 276 Write(Translate("Add to cart")); 277 WriteLiteral("\" id=\"AddToCartButton"); 278 Write(product.Id); 279 WriteLiteral("_"); 280 Write(Pageview.CurrentParagraph.ID); 281 WriteLiteral("\">"); 282 Write(Translate("Add to cart")); 283 WriteLiteral("</button>\n\t\t\t\t\t</div>\n\t\t\t\t\t<label"); 284 BeginWriteAttribute("for", " for=\"", 15655, "\"", 15683, 2); 285 WriteAttributeValue("", 15661, "Quantity_", 15661, 9, true); 286 WriteAttributeValue("", 15670, product.Id, 15670, 13, false); 287 EndWriteAttribute(); 288 WriteLiteral(" class=\"visually-hidden\">"); 289 Write(Translate("Quantity")); 290 WriteLiteral("</label>\n"); 291 if (stepQty != "1") { WriteLiteral("\t\t\t\t\t\t<div class=\"invalid-feedback d-none\">\n\t\t\t\t\t\t\t"); 292 Write(Translate("Please select a quantity that is dividable by")); 293 WriteLiteral(" "); 294 Write(stepQty); 295 WriteLiteral("\n\t\t\t\t\t\t</div>\n"); 296 } } WriteLiteral("\t\t\t</form>\n"); 297 if (!anonymousUser) { if (!hideFavoritesSelector && product.VariantInfo.VariantInfo == null) { Write(RenderPartial("Components/ToggleFavorite.cshtml", product, favoriteParameters)); 298 } else if (showFavoritesSelectorMasterProduct) { Write(RenderPartial("Components/ToggleFavorite.cshtml", product, favoriteParameters)); 299 } } } else if (!anonymousUser && !isDiscontinued) { if (!hideFavoritesSelector && product.VariantInfo.VariantInfo == null) { WriteLiteral("\t\t\t\t<div class=\"flex-fill\""); 300 BeginWriteAttribute("id", " id=\"", 16444, "\"", 16473, 2); 301 WriteAttributeValue("", 16449, "AddToFavorites_", 16449, 15, true); 302 WriteAttributeValue("", 16464, Model.ID, 16464, 9, false); 303 EndWriteAttribute(); 304 WriteLiteral(">\n\t\t\t\t\t"); 305 Write(Translate("Add to favorites")); 306 WriteLiteral(" "); 307 Write(RenderPartial("Components/ToggleFavorite.cshtml", product, favoriteParameters)); 308 WriteLiteral("\n\t\t\t\t</div>\n"); 309 } else if (showFavoritesSelectorMasterProduct) { WriteLiteral("\t\t\t\t<div class=\"flex-fill\""); 310 BeginWriteAttribute("id", " id=\"", 16687, "\"", 16716, 2); 311 WriteAttributeValue("", 16692, "AddToFavorites_", 16692, 15, true); 312 WriteAttributeValue("", 16707, Model.ID, 16707, 9, false); 313 EndWriteAttribute(); 314 WriteLiteral(">\n\t\t\t\t\t"); 315 Write(Translate("Add to favorites")); 316 WriteLiteral(" "); 317 Write(RenderPartial("Components/ToggleFavorite.cshtml", product, favoriteParameters)); 318 WriteLiteral("\n\t\t\t\t</div>\n"); 319 } } WriteLiteral("\n"); 320 if (isDiscontinued && product.ReplacementProduct != null) { List<ProductInfoViewModel> replacementProductList = new List<ProductInfoViewModel>(); replacementProductList.Add(product.ReplacementProduct); var replacementProduct = replacementProductList.GetProducts().FirstOrDefault(); if ((product.DiscontinuedAction == 0 || product.DiscontinuedAction == 1) && product?.ReplacementProduct.ProductId != null) { var parms = new Dictionary<string, object>(); parms.Add("cssClass", "d-block mw-100 mh-100 m-auto"); parms.Add("fullwidth", true); parms.Add("columns", Model.GridRowColumnCount); string imagePath = replacementProduct?.DefaultImage?.Value != null ? replacementProduct.DefaultImage.Value : ""; string link = "Default.aspx?ID=" + GetPageIdByNavigationTag("Shop"); link += $"&GroupID={replacementProduct.PrimaryOrDefaultGroup.Id}"; link += $"&ProductID={replacementProduct.Id}"; link += !string.IsNullOrEmpty(replacementProduct.VariantId) ? $"&VariantID={replacementProduct.VariantId}" : ""; link = Dynamicweb.Frontend.SearchEngineFriendlyURLs.GetFriendlyUrl(link); WriteLiteral("\t\t\t\t<div class=\"w-100\">\n\t\t\t\t\t<div class=\"fw-bold w-100\">"); 321 Write(Translate("Sorry, this product is no longer available")); 322 WriteLiteral(".</div>\n\t\t\t\t\t<div>"); 323 Write(Translate("We recommend this replacement product instead")); 324 WriteLiteral(":</div>\n\n\t\t\t\t\t<a"); 325 BeginWriteAttribute("href", " href=\"", 18189, "\"", 18201, 1); 326 WriteAttributeValue("", 18196, link, 18196, 5, false); 327 EndWriteAttribute(); 328 WriteLiteral(">\n\t\t\t\t\t\t"); 329 Write(RenderPartial("Components/Image.cshtml", new FileViewModel { Path = imagePath }, parms)); 330 WriteLiteral("\n\t\t\t\t\t</a>\n\n\t\t\t\t\t<div>"); 331 Write(replacementProduct.Name); 332 WriteLiteral("</div>\n\n"); 333 if (!hidePrice) { WriteLiteral("\t\t\t\t\t\t<div class=\"mb-3\">\n\t\t\t\t\t\t\t<div class=\"h4\" itemprop=\"offers\" itemscope itemtype=\"https://schema.org/Offer\">\n"); 334 if (showPricesWithVat == "false" && !neverShowVat) { if (isLazyLoadingForProductInfoEnabled) { WriteLiteral("\t\t\t\t\t\t\t\t\t\t<span itemprop=\"price\""); 335 BeginWriteAttribute("content", " content=\"", 18656, "\"", 18666, 0); 336 EndWriteAttribute(); 337 WriteLiteral(@" class=""d-none""></span> <span class=""text-decoration-line-through js-text-decoration-line-through opacity-75 me-3 text-price js-text-price d-none"" data-show-if=""LiveProductInfo.product.Price.Price != LiveProductInfo.product.PriceBeforeDiscount.Price""></span> "); 338 } else { string beforePrice = product.PriceBeforeDiscount.PriceWithoutVatFormatted; WriteLiteral("\t\t\t\t\t\t\t\t\t\t<span itemprop=\"price\""); 339 BeginWriteAttribute("content", " content=\"", 19090, "\"", 19130, 1); 340 WriteAttributeValue("", 19100, product.Price.PriceWithoutVat, 19100, 30, false); 341 EndWriteAttribute(); 342 WriteLiteral(" class=\"d-none\"></span>\n"); 343 if (product.Price.Price != product.PriceBeforeDiscount.Price) { WriteLiteral("\t\t\t\t\t\t\t\t\t\t\t<span class=\"text-decoration-line-through opacity-75 me-3\">"); 344 Write(beforePrice); 345 WriteLiteral("</span>\n"); 346 } } } else { if (isLazyLoadingForProductInfoEnabled) { WriteLiteral("\t\t\t\t\t\t\t\t\t\t<span itemprop=\"price\""); 347 BeginWriteAttribute("content", " content=\"", 19477, "\"", 19487, 0); 348 EndWriteAttribute(); 349 WriteLiteral(@" class=""d-none""></span> <span class=""text-decoration-line-through js-text-decoration-line-through opacity-75 me-3 text-price js-text-price d-none"" data-show-if=""LiveProductInfo.product.Price.Price != LiveProductInfo.product.PriceBeforeDiscount.Price""></span> "); 350 } else { string beforePrice = product.PriceBeforeDiscount.PriceFormatted; WriteLiteral("\t\t\t\t\t\t\t\t\t\t<span itemprop=\"price\""); 351 BeginWriteAttribute("content", " content=\"", 19901, "\"", 19931, 1); 352 WriteAttributeValue("", 19911, product.Price.Price, 19911, 20, false); 353 EndWriteAttribute(); 354 WriteLiteral(" class=\"d-none\"></span>\n"); 355 if (product.Price.Price != product.PriceBeforeDiscount.Price) { WriteLiteral("\t\t\t\t\t\t\t\t\t\t\t<span class=\"text-decoration-line-through opacity-75 me-3\">"); 356 Write(beforePrice); 357 WriteLiteral("</span>\n"); 358 } } } WriteLiteral("\n"); 359 if (showPricesWithVat == "false" && !neverShowVat) { if (isLazyLoadingForProductInfoEnabled) { WriteLiteral("\t\t\t\t\t\t\t\t\t\t<span class=\"text-price js-text-price\"><div class=\"spinner-border\" role=\"status\"></div></span>\n"); 360 } else { string price = product.Price.PriceWithoutVatFormatted; if (product?.VariantInfo?.VariantInfo != null) { priceMin = product?.VariantInfo?.PriceMin?.PriceWithoutVatFormatted != null ? product.VariantInfo.PriceMin.PriceWithoutVatFormatted : ""; priceMax = product?.VariantInfo?.PriceMax?.PriceWithoutVatFormatted != null ? product.VariantInfo.PriceMax.PriceWithoutVatFormatted : ""; } if (priceMin != priceMax) { price = priceMin + " - " + priceMax; } WriteLiteral("\t\t\t\t\t\t\t\t\t\t<span class=\"text-price\">"); 361 Write(price); 362 WriteLiteral("</span>\n"); 363 } } else { if (isLazyLoadingForProductInfoEnabled) { WriteLiteral("\t\t\t\t\t\t\t\t\t\t<span class=\"text-price js-text-price\"><div class=\"spinner-border\" role=\"status\"></div></span>\n"); 364 } else { string price = product.Price.PriceFormatted; if (product?.VariantInfo?.VariantInfo != null) { priceMin = product?.VariantInfo?.PriceMin?.PriceFormatted != null ? product.VariantInfo.PriceMin.PriceFormatted : ""; priceMax = product?.VariantInfo?.PriceMax?.PriceFormatted != null ? product.VariantInfo.PriceMax.PriceFormatted : ""; } if (priceMin != priceMax) { price = priceMin + " - " + priceMax; } WriteLiteral("\t\t\t\t\t\t\t\t\t\t<span class=\"text-price\">"); 365 Write(price); 366 WriteLiteral("</span>\n"); 367 } } WriteLiteral("\t\t\t\t\t\t\t</div>\n\n"); 368 if (showPricesWithVat == "false" && !neverShowVat) { if (isLazyLoadingForProductInfoEnabled) { WriteLiteral("\t\t\t\t\t\t\t\t\t<small class=\"opacity-85 fst-normal js-text-price-with-vat d-none\" data-suffix=\""); 369 Write(Translate("Incl. VAT")); 370 WriteLiteral("\"></small>\n"); 371 } else { string price = product.Price.PriceWithVatFormatted; if (product?.VariantInfo?.VariantInfo != null) { priceMin = product?.VariantInfo?.PriceMin?.PriceWithVatFormatted != null ? product.VariantInfo.PriceMin.PriceWithVatFormatted : ""; priceMax = product?.VariantInfo?.PriceMax?.PriceWithVatFormatted != null ? product.VariantInfo.PriceMax.PriceWithVatFormatted : ""; } if (priceMin != priceMax) { price = priceMin + " - " + priceMax; } WriteLiteral("\t\t\t\t\t\t\t\t\t<small class=\"opacity-85 fst-normal\">"); 372 Write(price); 373 WriteLiteral(" "); 374 Write(Translate("Incl. VAT")); 375 WriteLiteral("</small>\n"); 376 } } WriteLiteral("\t\t\t\t\t\t</div>\n"); 377 } WriteLiteral("\n\t\t\t\t\t<a"); 378 BeginWriteAttribute("href", " href=\"", 22809, "\"", 22821, 1); 379 WriteAttributeValue("", 22816, link, 22816, 5, false); 380 EndWriteAttribute(); 381 WriteLiteral(" class=\"btn btn-primary w-100\">"); 382 Write(Translate("Go to the replacement")); 383 WriteLiteral("</a>\n\t\t\t\t</div>\n"); 384 } } WriteLiteral("\t\t</div>\n\t</div>\n"); 385 if (!hideStock) { if (!IsNeverOutOfStock) { if (isLazyLoadingForProductInfoEnabled) { string hideStockState = string.IsNullOrEmpty(product.VariantId) && product.VariantInfo.VariantInfo != null ? "d-none" : ""; WriteLiteral("\t\t\t\t<div"); 386 BeginWriteAttribute("class", " class=\"", 23165, "\"", 23198, 2); 387 WriteAttributeValue("", 23173, "js-product", 23173, 10, true); 388 WriteAttributeValue(" ", 23183, liveInfoClass, 23184, 14, false); 389 EndWriteAttribute(); 390 WriteLiteral(" data-product-id=\""); 391 Write(product.Id); 392 WriteLiteral("\">\n\t\t\t\t\t<div"); 393 BeginWriteAttribute("class", " class=\"", 23240, "\"", 23298, 4); 394 WriteAttributeValue("", 23248, "mt-3", 23248, 4, true); 395 WriteAttributeValue(" ", 23252, "js-stock-state", 23253, 15, true); 396 WriteAttributeValue(" ", 23267, "spinner-border", 23268, 15, true); 397 WriteAttributeValue(" ", 23282, hideStockState, 23283, 15, false); 398 EndWriteAttribute(); 399 WriteLiteral(">\n"); 400 if (!Model.Item.GetBoolean("HideInventory")) { WriteLiteral("\t\t\t\t\t\t\t<div class=\"small text-success d-none\" data-show-if=\"LiveProductInfo.product.StockLevel > 0\">\n\t\t\t\t\t\t\t\t<span class=\"js-text-stock\"></span>\n\t\t\t\t\t\t\t\t"); 401 Write(Translate("Products available in stock")); 402 WriteLiteral("\n\t\t\t\t\t\t\t</div>\n"); 403 } else { WriteLiteral("\t\t\t\t\t\t\t<div class=\"small text-success d-none\" data-show-if=\"LiveProductInfo.product.StockLevel > 0\">"); 404 Write(Translate("Available in stock")); 405 WriteLiteral("</div>\n"); 406 } WriteLiteral("\t\t\t\t\t\t<div class=\"small text-danger d-none\" data-show-if=\"LiveProductInfo.product.StockLevel <= 0\">"); 407 Write(Translate("Out of Stock")); 408 WriteLiteral("</div>\n\t\t\t\t\t\t\n\t\t\t\t\t\t<div class=\"d-none\" data-show-if=\"LiveProductInfo.product.ExpectedDelivery != null && new Date(LiveProductInfo.product.ExpectedDelivery) > new Date()\">\n\t\t\t\t\t\t\t<span>"); 409 Write(Translate("Expected back in stock:")); 410 WriteLiteral("</span>\n\t\t\t\t\t\t\t<span class=\"js-text-expected-delivery\"></span>\n\t\t\t\t\t\t</div>\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n"); 411 } else { WriteLiteral("\t\t\t\t<div class=\"mt-3 js-stock-state\">\n\n"); 412 if (product.StockLevel > 0) { if (!Model.Item.GetBoolean("HideInventory")) { WriteLiteral("\t\t\t\t\t\t\t<div class=\"small text-success\">"); 413 Write(product.StockLevel); 414 WriteLiteral(" "); 415 Write(Translate("Products available in stock")); 416 WriteLiteral("</div>\n"); 417 } else { WriteLiteral("\t\t\t\t\t\t\t<div class=\"small text-success\">"); 418 Write(Translate("Available in stock")); 419 WriteLiteral("</div>\n"); 420 } } else { WriteLiteral("\t\t\t\t\t\t<div class=\"small text-danger\">"); 421 Write(Translate("Out of Stock")); 422 WriteLiteral("</div>\n"); 423 } WriteLiteral("\n"); 424 if (hasExpectedDelivery) { WriteLiteral("\t\t\t\t\t\t<div>\n\t\t\t\t\t\t\t<span>"); 425 Write(Translate("Expected back in stock:")); 426 WriteLiteral("</span>\n\t\t\t\t\t\t\t<span>"); 427 Write(expectedDeliveryDate); 428 WriteLiteral("</span>\n\t\t\t\t\t\t</div>\n"); 429 } WriteLiteral("\n\t\t\t\t</div>\n"); 430 } } } WriteLiteral("</div>\n\n"); 431 Write(helper); 432 WriteLiteral(@" RenderField(FieldValueViewModel field) { string fieldValue = field?.Value != null ? field.Value.ToString() : """"; bool noValues = false; if (!string.IsNullOrEmpty(fieldValue)) { if (field.Value.GetType() == typeof(System.Collections.Generic.List<FieldOptionValueViewModel>)) { System.Collections.Generic.List<FieldOptionValueViewModel> values = field.Value as System.Collections.Generic.List<FieldOptionValueViewModel>; noValues = values.Count > 0 ? false : true; } } if (!string.IsNullOrEmpty(fieldValue) && noValues == false) { <dt class=""g-col-12 g-col-sm-4 g-col-lg-12 fw-bold m-0"">"); 433 Write(field.Name); 434 WriteLiteral("</dt>\n\t\t<dd class=\"g-col-12 g-col-sm-8 g-col-lg-12 mb-3\">\n\t\t\t"); 435 Write(RenderFieldValue(field)); 436 WriteLiteral("\n\t\t</dd>\n\t}\n}\n\n"); 437 Write(helper); 438 WriteLiteral(@" RenderFieldValue(FieldValueViewModel field) { string fieldValue = field?.Value != null ? field.Value.ToString() : """"; fieldValue = fieldValue == ""False"" ? Translate(""No"") : fieldValue; fieldValue = fieldValue == ""True"" ? Translate(""Yes"") : fieldValue; bool isColor = false; if (field.Value.GetType() == typeof(System.Collections.Generic.List<Dynamicweb.Ecommerce.ProductCatalog.FieldOptionValueViewModel>)) { int valueCount = 0; System.Collections.Generic.List<FieldOptionValueViewModel> values = field.Value as System.Collections.Generic.List<FieldOptionValueViewModel>; int totalValues = values.Count; foreach (FieldOptionValueViewModel option in values) { if (!string.IsNullOrEmpty(option.Value)) { if (option.Value.Substring(0, 1) == ""#"") { isColor = true; } } if (!isColor) { "); 439 Write(option.Name); 440 WriteLiteral("\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\t<span class=\"colorbox-sm\""); 441 BeginWriteAttribute("style", " style=\"", 26505, "\"", 26544, 2); 442 WriteAttributeValue("", 26513, "background-color:", 26513, 17, true); 443 WriteAttributeValue(" ", 26530, option.Value, 26531, 13, false); 444 EndWriteAttribute(); 445 BeginWriteAttribute("title", " title=\"", 26545, "\"", 26566, 1); 446 WriteAttributeValue("", 26553, option.Value, 26553, 13, false); 447 EndWriteAttribute(); 448 WriteLiteral(@"></span> } if (valueCount != totalValues && valueCount < (totalValues - 1)) { if (isColor) { <text> </text> } else { <text>, </text> } } valueCount++; } } else { if (fieldValue.Substring(0, 1) == ""#"") { isColor = true; } if (!isColor) { "); 449 Write(fieldValue); 450 WriteLiteral("\n\t\t}\n\t\telse\n\t\t{\n\t\t\t<span class=\"colorbox-sm\""); 451 BeginWriteAttribute("style", " style=\"", 26931, "\"", 26968, 2); 452 WriteAttributeValue("", 26939, "background-color:", 26939, 17, true); 453 WriteAttributeValue(" ", 26956, fieldValue, 26957, 11, false); 454 EndWriteAttribute(); 455 BeginWriteAttribute("title", " title=\"", 26969, "\"", 26988, 1); 456 WriteAttributeValue("", 26977, fieldValue, 26977, 11, false); 457 EndWriteAttribute(); 458 WriteLiteral("></span>\n\t\t}\n\t}\n}\n"); 459 } 460 #pragma warning restore 1998 461 //Find contrast color (white, black) public static string GetContrastColor(string hexString) { System.Drawing.Color bg = System.Drawing.ColorTranslator.FromHtml(hexString); int nThreshold = 105; int bgDelta = Convert.ToInt32((bg.R * 0.299) + (bg.G * 0.587) + (bg.B * 0.114)); string foreColor = (255 - bgDelta < nThreshold) ? "#333" : "#fff"; return foreColor; } } 462 } 463 #pragma warning restore 1591 464
1 @inherits Dynamicweb.Rendering.ViewModelTemplate<Dynamicweb.Frontend.ParagraphViewModel> @using Dynamicweb.Ecommerce.ProductCatalog @using Dynamicweb.Ecommerce.CustomerExperienceCenter.Favorites @using Dynamicweb.Ecommerce.Products.FieldDisplayGroups @using Dynamicweb.Frontend @using Dynamicweb.Core @using System.Drawing @using Dynamicweb.Environment @functions { //Find contrast color (white, black) public static string GetContrastColor(string hexString) { System.Drawing.Color bg = System.Drawing.ColorTranslator.FromHtml(hexString); int nThreshold = 105; int bgDelta = Convert.ToInt32((bg.R * 0.299) + (bg.G * 0.587) + (bg.B * 0.114)); string foreColor = (255 - bgDelta < nThreshold) ? "#333" : "#fff"; return foreColor; } } @{ string googleAnalyticsTrackingID = Pageview.AreaSettings.GetString("GoogleAnalyticsTrackingID"); string googleAnalyticsMeasurementID = Pageview.AreaSettings.GetString("GoogleAnalyticsMeasurementID"); var cookieOptInLevel = CookieManager.GetCookieOptInLevel(); bool allowTracking = cookieOptInLevel == CookieOptInLevel.All || (cookieOptInLevel == CookieOptInLevel.Functional && CookieManager.GetCookieOptInCategories().Contains("Statistical")); ProductViewModel product = new ProductViewModel(); if (Dynamicweb.Context.Current.Items.Contains("ProductDetails")) { product = (ProductViewModel)Dynamicweb.Context.Current.Items["ProductDetails"]; } string anonymousUsersLimitations = Pageview.AreaSettings.GetRawValueString("AnonymousUsers", ""); bool anonymousUser = Pageview.User == null; bool isErpConnectionDown = !Dynamicweb.Ecommerce.DynamicwebLiveIntegration.TemplatesHelper.IsWebServiceConnectionAvailable(); bool hideAddToCart = anonymousUsersLimitations.Contains("cart") && anonymousUser || Pageview.AreaSettings.GetBoolean("ErpDownHideAddToCart") && isErpConnectionDown; hideAddToCart = product?.VariantInfo?.VariantInfo != null && Model.Item.GetBoolean("HideVariantSelector") ? true : hideAddToCart; bool hideStock = Model.Item.GetBoolean("HideStockState") || (Pageview.AreaSettings.GetBoolean("ErpDownHideStock") && isErpConnectionDown); bool hidePrice = anonymousUsersLimitations.Contains("price") && anonymousUser || Pageview.AreaSettings.GetBoolean("ErpDownHidePrices") && isErpConnectionDown; bool hideFavoritesSelector = !string.IsNullOrEmpty(Model.Item.GetString("HideFavoritesSelector")) ? Model.Item.GetBoolean("HideFavoritesSelector") : false; bool showFavoritesSelectorMasterProduct = !string.IsNullOrEmpty(Model.Item.GetString("ShowFavoritesSelectorMasterProduct")) ? Model.Item.GetBoolean("ShowFavoritesSelectorMasterProduct") : false; bool isDiscontinued = product.Discontinued; bool IsNeverOutOfStock = product.NeverOutOfstock; string[] variantId = { }; if (product?.VariantId != null) { variantId = product.VariantId.Split('.'); } string disableAddToCart = (product.StockLevel <= 0) ? "disabled" : ""; disableAddToCart = isDiscontinued ? "disabled" : disableAddToCart; disableAddToCart = IsNeverOutOfStock ? "" : disableAddToCart; // Does product has a expected delivery data bool hasExpectedDelivery = product.ExpectedDelivery != null && product.ExpectedDelivery > DateTime.Now; string expectedDeliveryDate = product.ExpectedDelivery?.ToShortDateString() ?? ""; string url = "/Default.aspx?ID=" + (GetPageIdByNavigationTag("CartService")); if (!url.Contains("LayoutTemplate")) { url += url.Contains("?") ? "&LayoutTemplate=Swift_MiniCart.cshtml" : "?LayoutTemplate=Swift_MiniCart.cshtml"; } IEnumerable<string> selectedDisplayGroups = Model.Item.GetRawValueString("MainFeatures").Split(',').ToList(); List<CategoryFieldViewModel> mainFeatures = new List<CategoryFieldViewModel>(); foreach (var selection in selectedDisplayGroups) { foreach (CategoryFieldViewModel group in product.FieldDisplayGroups.Values) { if (selection == group.Id) { mainFeatures.Add(group); } } } string theme = !string.IsNullOrWhiteSpace(Model.Item.GetRawValueString("Theme")) ? " theme " + Model.Item.GetRawValueString("Theme").Replace(" ", "").Trim().ToLower() : ""; string titleFontSize = Model.Item.GetRawValueString("TitleFontSize", "display-6"); string contentPadding = Model.Item.GetRawValueString("ContentPadding", ""); contentPadding = contentPadding == "small" ? "p-2 p-md-3" : contentPadding; contentPadding = contentPadding == "large" ? "p-4 p-md-5" : contentPadding; string quantityPricesLayout = Model.Item.GetRawValueString("QuantityPricesLayout", "list"); string minQty = product.PurchaseMinimumQuantity != 1 ? "min=\"" + product.PurchaseMinimumQuantity.ToString() + "\"" : "min=\"1\""; string stepQty = product.PurchaseQuantityStep > 1 ? product.PurchaseQuantityStep.ToString() : "1"; string valueQty = product.PurchaseMinimumQuantity > product.PurchaseQuantityStep ? product.PurchaseMinimumQuantity.ToString() : stepQty; string qtyValidCheck = stepQty != "1" ? "onkeyup=\"swift.Cart.QuantityValidate(event)\"" : ""; string showPricesWithVat = Pageview.Area.EcomPricesWithVat.ToLower(); bool neverShowVat = string.IsNullOrEmpty(showPricesWithVat); string priceMin = ""; string priceMax = ""; var favoriteParameters = new Dictionary<string, object>(); if (!anonymousUser && !hideFavoritesSelector) { IEnumerable<FavoriteList> favoreiteLists = Pageview.User.GetFavoriteLists(); int defaultFavoriteListId = 0; if (favoreiteLists.Count() == 1) { foreach (FavoriteList list in favoreiteLists) { defaultFavoriteListId = list.ListId; } } favoriteParameters.Add("ListId", defaultFavoriteListId); } var priceParms = new Dictionary<string, object>(); priceParms.Add("theme", ""); var badgeParms = new Dictionary<string, object>(); badgeParms.Add("size", "h7"); badgeParms.Add("saleBadgeType", Model.Item.GetRawValue("SaleBadgeType")); badgeParms.Add("saleBadgeCssClassName", Model.Item.GetRawValue("SaleBadgeDesign")); badgeParms.Add("newBadgeCssClassName", Model.Item.GetRawValue("NewBadgeDesign")); badgeParms.Add("newPublicationDays", Model.Item.GetInt32("NewPublicationDays")); badgeParms.Add("campaignBadgesValues", Model.Item.GetRawValueString("CampaignBadges")); bool saleBadgeEnabled = !string.IsNullOrWhiteSpace(Model.Item.GetRawValueString("SaleBadgeDesign")) && Model.Item.GetRawValueString("SaleBadgeDesign") != "none" ? true : false; bool newBadgeEnabled = !string.IsNullOrWhiteSpace(Model.Item.GetRawValueString("NewBadgeDesign")) && Model.Item.GetRawValueString("NewBadgeDesign") != "none" ? true : false; DateTime createdDate = product.Created.Value; bool showBadges = saleBadgeEnabled && product.Discount.Price != 0 ? true : false; showBadges = (newBadgeEnabled && Model.Item.GetInt32("NewPublicationDays") == 0) || (newBadgeEnabled && (createdDate.AddDays(Model.Item.GetInt32("NewPublicationDays")) > DateTime.Now)) ? true : showBadges; showBadges = !string.IsNullOrEmpty(Model.Item.GetRawValueString("CampaignBadges")) ? true : showBadges; string liveInfoClass = ""; string productInfoFeed = ""; bool isLazyLoadingForProductInfoEnabled = Dynamicweb.Ecommerce.DynamicwebLiveIntegration.TemplatesHelper.IsLazyLoadingForProductInfoEnabled; if (isLazyLoadingForProductInfoEnabled) { if (Dynamicweb.Context.Current.Items.Contains("ProductInfoFeed")) { productInfoFeed = Dynamicweb.Context.Current.Items["ProductInfoFeed"]?.ToString(); if (!string.IsNullOrEmpty(productInfoFeed)) { productInfoFeed = $"data-product-info-feed=\"{productInfoFeed}\""; } } liveInfoClass = "js-live-info"; } } @if (!string.IsNullOrWhiteSpace(googleAnalyticsMeasurementID) && allowTracking) { <script> gtag("event", "view_item", { currency: "@product.Price.CurrencyCode", value: @product.Price.Price, items: [ { item_id: "@product.Number", item_name: "@product.Name", currency: "@product.Price.CurrencyCode", price: @product.Price.Price } ] }); </script> } <div class="h-100 @(contentPadding) @(theme) item_@Model.Item.SystemName.ToLower()" @productInfoFeed> <div class="d-flex flex-column gap-4 js-product" data-product-id="@product.Id"> @if (showBadges) { <div class="swift_badge-collection"> @RenderPartial("Components/EcommerceBadge.cshtml", product, badgeParms) </div> } <div class="d-flex flex-column gap-2"> <h1 class="@titleFontSize m-0" itemprop="name">@product.Name</h1> @if (!Model.Item.GetBoolean("HideProductNumber")) { @RenderPartial("Paragraph/Swift_ProductNumber.cshtml", Model) } </div> @if (!hidePrice && !isDiscontinued) { @RenderPartial("Paragraph/Swift_ProductPrice.cshtml", Model, priceParms) if (isLazyLoadingForProductInfoEnabled) { <div class="product-prices-container @liveInfoClass d-none" data-show-if="LiveProductInfo.product.Prices.length > 0"> @if (quantityPricesLayout == "list") { <div class="mt-3 product-prices"> <small class="d-block opacity-75 product-prices-template"><span><span class="js-text-price-quantity"></span> @Translate("PCS")</span> - <span class="fw-bold"><span class="js-text-price-price"></span> <span class="d-none" data-show-if="LiveProductInfo.productPrice.Quantity > 1">@Translate("pr. PCS")</span></span></small> </div> } else if (quantityPricesLayout == "table") { <div class="grid"> <table class="table table-sm mt-3 g-col-12 g-col-lg-6"> <thead> <tr> <td>@Translate("QTY")</td> <td>@Translate("pr. PCS")</td> </tr> </thead> <tbody class="product-prices"> <tr class="product-prices-template"> <td class="js-text-price-quantity"></td> <td class="js-text-price-price"></td> </tr> </tbody> </table> </div> } </div> } else { if (product.Prices.Count > 0) { <div> @if (quantityPricesLayout == "list") { <div class="mt-3"> @foreach (PriceListViewModel quantityPrice in product.Prices) { string quantityLabel = Translate("PCS"); string quantityPriceSuffix = quantityPrice.Quantity > 1 ? Translate("pr. PCS") : ""; <small class="d-block opacity-75"><span>@quantityPrice.Quantity @quantityLabel</span> - <span class="fw-bold">@quantityPrice.Price.PriceFormatted @quantityPriceSuffix</span></small> } </div> } else if (quantityPricesLayout == "table") { <div class="grid"> <table class="table table-sm mt-3 g-col-12 g-col-lg-6"> <thead> <tr> <td>@Translate("QTY")</td> <td>@Translate("pr. PCS")</td> </tr> </thead> <tbody> @foreach (PriceListViewModel quantityPrice in product.Prices) { <tr> <td>@quantityPrice.Quantity</td> <td>@quantityPrice.Price.PriceFormatted</td> </tr> } </tbody> </table> </div> } </div> } } } @RenderPartial("Paragraph/Swift_ProductShortDescription.cshtml", Model) @if (mainFeatures.Count > 0) { foreach (CategoryFieldViewModel mainFeatureGroup in mainFeatures) { <dl class="grid gap-0"> @foreach (var field in mainFeatureGroup.Fields) { @RenderField(field.Value) } </dl> } } @if (product.VariantInfo.VariantInfo != null && !Model.Item.GetBoolean("HideVariantSelector")) { int groupNumber = 1; string baseUrl = $"Default.aspx?ID={GetPageIdByNavigationTag("Shop")}&GroupID={product.PrimaryOrDefaultGroup.Id}&ProductID={product.Id}"; string variantUrl = ""; if (!string.IsNullOrEmpty(product.VariantId)) { variantUrl = Dynamicweb.Frontend.SearchEngineFriendlyURLs.GetFriendlyUrl($"Default.aspx?ID={GetPageIdByNavigationTag("Shop")}&GroupID={product.PrimaryOrDefaultGroup.Id}&ProductID={product.Id}&VariantID={product.VariantId}"); } <form class="js-variant-selector" data-combinations="@string.Join(",", product.VariantCombinations())" data-base-url="@baseUrl" data-friendly-url="@variantUrl"> <input type="hidden" name="variantid"> @foreach (var variantGroup in product.VariantGroups()) { VariantGroupViewModel group = variantGroup; <h3 class="h6">@group.Name</h3> <div class="d-flex gap-2 flex-wrap js-variant-group" data-group-id="@groupNumber"> @foreach (var option in group.Options) { string active = variantId.Contains(option.Id) ? "active" : ""; if (!string.IsNullOrEmpty(option.Color)) { string contrastColor = GetContrastColor(option.Color); <button type="button" class="btn colorbox rounded-circle d-inline-block variant-option border js-variant-option @active" style="background-color: @option.Color; --variantoption-check-color: @contrastColor" onclick="swift.VariantSelector.OptionClick(event)" data-variant-id="@option.Id" id="@(product.Id)_@(option.Id)_@Pageview.CurrentParagraph.ID"> <span class="visually-hidden">@option.Name</span> </button> } else if (!string.IsNullOrEmpty(option.Color) && !string.IsNullOrEmpty(option.Image.Value)) { <button type="button" class="btn p-0 d-inline-block variant-option border js-variant-option @active" onclick="swift.VariantSelector.OptionClick(event)" data-variant-id="@option.Id"> <img src="/Admin/Public/GetImage.ashx?image=@(option.Image.Value)&width=42&Format=WebP&Quality=70"> </button> } else { <button type="button" class="btn btn-secondary d-inline-block variant-option js-variant-option @active" onclick="swift.VariantSelector.OptionClick(event)" data-variant-id="@option.Id"> @option.Name </button> } } </div> groupNumber++; } </form> } <div class="d-flex flex-row flex-nowrap gap-2"> @if (!hideAddToCart) { <form method="post" action="@url" class="flex-fill"> <input type="hidden" name="redirect" value="false"> <input type="hidden" name="ProductId" value="@product.Id"> <input type="hidden" name="ProductName" value="@product.Name"> <input type="hidden" name="ProductPrice" value="@product.Price.Price"> <input type="hidden" name="ProductCurrency" value="@product.Price.CurrencyCode"> <input type="hidden" name="ProductReferer" value="product_details_info"> <input type="hidden" name="cartcmd" value="add"> @if (!string.IsNullOrEmpty(product.VariantId)) { <input type="hidden" name="VariantId" value="@product.VariantId"> } @if (!Model.Item.GetBoolean("QuantitySelector")) { <input id="Quantity_@product.Id" name="Quantity" value="@valueQty" type="hidden" @disableAddToCart> <button type="button" onclick="swift.Cart.Update(event)" class="btn btn-primary w-100 js-add-to-cart-button @disableAddToCart" @disableAddToCart title="@Translate("Add to cart")" id="AddToCartButton@(product.Id)_@Pageview.CurrentParagraph.ID">@Translate("Add to cart")</button> } else { <div class="input-group input-primary-button-group js-input-group d-flex flex-row flex-nowrap"> <input id="Quantity_@product.Id" name="Quantity" value="@valueQty" step="@stepQty" @minQty class="form-control" style="min-width: 60px; max-width: 100px;" type="number" onkeydown="swift.Cart.UpdateOnEnterKey(event)" @disableAddToCart> <button type="button" onclick="swift.Cart.Update(event)" class="btn btn-primary flex-fill js-add-to-cart-button @disableAddToCart" @disableAddToCart title="@Translate("Add to cart")" id="AddToCartButton@(product.Id)_@Pageview.CurrentParagraph.ID">@Translate("Add to cart")</button> </div> <label for="Quantity_@(product.Id)" class="visually-hidden">@Translate("Quantity")</label> if (stepQty != "1") { <div class="invalid-feedback d-none"> @Translate("Please select a quantity that is dividable by") @stepQty </div> } } </form> if (!anonymousUser) { if (!hideFavoritesSelector && product.VariantInfo.VariantInfo == null) { @RenderPartial("Components/ToggleFavorite.cshtml", product, favoriteParameters) } else if (showFavoritesSelectorMasterProduct) { @RenderPartial("Components/ToggleFavorite.cshtml", product, favoriteParameters) } } } else if (!anonymousUser && !isDiscontinued) { if (!hideFavoritesSelector && product.VariantInfo.VariantInfo == null) { <div class="flex-fill" id="AddToFavorites_@Model.ID"> @Translate("Add to favorites") @RenderPartial("Components/ToggleFavorite.cshtml", product, favoriteParameters) </div> } else if (showFavoritesSelectorMasterProduct) { <div class="flex-fill" id="AddToFavorites_@Model.ID"> @Translate("Add to favorites") @RenderPartial("Components/ToggleFavorite.cshtml", product, favoriteParameters) </div> } } @if (isDiscontinued && product.ReplacementProduct != null) { List<ProductInfoViewModel> replacementProductList = new List<ProductInfoViewModel>(); replacementProductList.Add(product.ReplacementProduct); var replacementProduct = replacementProductList.GetProducts().FirstOrDefault(); if ((product.DiscontinuedAction == 0 || product.DiscontinuedAction == 1) && product?.ReplacementProduct.ProductId != null) { var parms = new Dictionary<string, object>(); parms.Add("cssClass", "d-block mw-100 mh-100 m-auto"); parms.Add("fullwidth", true); parms.Add("columns", Model.GridRowColumnCount); string imagePath = replacementProduct?.DefaultImage?.Value != null ? replacementProduct.DefaultImage.Value : ""; string link = "Default.aspx?ID=" + GetPageIdByNavigationTag("Shop"); link += $"&GroupID={replacementProduct.PrimaryOrDefaultGroup.Id}"; link += $"&ProductID={replacementProduct.Id}"; link += !string.IsNullOrEmpty(replacementProduct.VariantId) ? $"&VariantID={replacementProduct.VariantId}" : ""; link = Dynamicweb.Frontend.SearchEngineFriendlyURLs.GetFriendlyUrl(link); <div class="w-100"> <div class="fw-bold w-100">@Translate("Sorry, this product is no longer available").</div> <div>@Translate("We recommend this replacement product instead"):</div> <a href="@link"> @RenderPartial("Components/Image.cshtml", new FileViewModel { Path = imagePath }, parms) </a> <div>@replacementProduct.Name</div> @if (!hidePrice) { <div class="mb-3"> <div class="h4" itemprop="offers" itemscope itemtype="https://schema.org/Offer"> @if (showPricesWithVat == "false" && !neverShowVat) { if (isLazyLoadingForProductInfoEnabled) { <span itemprop="price" content="" class="d-none"></span> <span class="text-decoration-line-through js-text-decoration-line-through opacity-75 me-3 text-price js-text-price d-none" data-show-if="LiveProductInfo.product.Price.Price != LiveProductInfo.product.PriceBeforeDiscount.Price"></span> } else { string beforePrice = product.PriceBeforeDiscount.PriceWithoutVatFormatted; <span itemprop="price" content="@product.Price.PriceWithoutVat" class="d-none"></span> if (product.Price.Price != product.PriceBeforeDiscount.Price) { <span class="text-decoration-line-through opacity-75 me-3">@beforePrice</span> } } } else { if (isLazyLoadingForProductInfoEnabled) { <span itemprop="price" content="" class="d-none"></span> <span class="text-decoration-line-through js-text-decoration-line-through opacity-75 me-3 text-price js-text-price d-none" data-show-if="LiveProductInfo.product.Price.Price != LiveProductInfo.product.PriceBeforeDiscount.Price"></span> } else { string beforePrice = product.PriceBeforeDiscount.PriceFormatted; <span itemprop="price" content="@product.Price.Price" class="d-none"></span> if (product.Price.Price != product.PriceBeforeDiscount.Price) { <span class="text-decoration-line-through opacity-75 me-3">@beforePrice</span> } } } @if (showPricesWithVat == "false" && !neverShowVat) { if (isLazyLoadingForProductInfoEnabled) { <span class="text-price js-text-price"><div class="spinner-border" role="status"></div></span> } else { string price = product.Price.PriceWithoutVatFormatted; if (product?.VariantInfo?.VariantInfo != null) { priceMin = product?.VariantInfo?.PriceMin?.PriceWithoutVatFormatted != null ? product.VariantInfo.PriceMin.PriceWithoutVatFormatted : ""; priceMax = product?.VariantInfo?.PriceMax?.PriceWithoutVatFormatted != null ? product.VariantInfo.PriceMax.PriceWithoutVatFormatted : ""; } if (priceMin != priceMax) { price = priceMin + " - " + priceMax; } <span class="text-price">@price</span> } } else { if (isLazyLoadingForProductInfoEnabled) { <span class="text-price js-text-price"><div class="spinner-border" role="status"></div></span> } else { string price = product.Price.PriceFormatted; if (product?.VariantInfo?.VariantInfo != null) { priceMin = product?.VariantInfo?.PriceMin?.PriceFormatted != null ? product.VariantInfo.PriceMin.PriceFormatted : ""; priceMax = product?.VariantInfo?.PriceMax?.PriceFormatted != null ? product.VariantInfo.PriceMax.PriceFormatted : ""; } if (priceMin != priceMax) { price = priceMin + " - " + priceMax; } <span class="text-price">@price</span> } } </div> @if (showPricesWithVat == "false" && !neverShowVat) { if (isLazyLoadingForProductInfoEnabled) { <small class="opacity-85 fst-normal js-text-price-with-vat d-none" data-suffix="@Translate("Incl. VAT")"></small> } else { string price = product.Price.PriceWithVatFormatted; if (product?.VariantInfo?.VariantInfo != null) { priceMin = product?.VariantInfo?.PriceMin?.PriceWithVatFormatted != null ? product.VariantInfo.PriceMin.PriceWithVatFormatted : ""; priceMax = product?.VariantInfo?.PriceMax?.PriceWithVatFormatted != null ? product.VariantInfo.PriceMax.PriceWithVatFormatted : ""; } if (priceMin != priceMax) { price = priceMin + " - " + priceMax; } <small class="opacity-85 fst-normal">@price @Translate("Incl. VAT")</small> } } </div> } <a href="@link" class="btn btn-primary w-100">@Translate("Go to the replacement")</a> </div> } } </div> </div> @if (!hideStock) { if (!IsNeverOutOfStock) { if (isLazyLoadingForProductInfoEnabled) { string hideStockState = string.IsNullOrEmpty(product.VariantId) && product.VariantInfo.VariantInfo != null ? "d-none" : ""; <div class="js-product @liveInfoClass" data-product-id="@product.Id"> <div class="mt-3 js-stock-state spinner-border @hideStockState"> @if (!Model.Item.GetBoolean("HideInventory")) { <div class="small text-success d-none" data-show-if="LiveProductInfo.product.StockLevel > 0"> <span class="js-text-stock"></span> @Translate("Products available in stock") </div> } else { <div class="small text-success d-none" data-show-if="LiveProductInfo.product.StockLevel > 0">@Translate("Available in stock")</div> } <div class="small text-danger d-none" data-show-if="LiveProductInfo.product.StockLevel <= 0">@Translate("Out of Stock")</div> <div class="d-none" data-show-if="LiveProductInfo.product.ExpectedDelivery != null && new Date(LiveProductInfo.product.ExpectedDelivery) > new Date()"> <span>@Translate("Expected back in stock:")</span> <span class="js-text-expected-delivery"></span> </div> </div> </div> } else { <div class="mt-3 js-stock-state"> @if (product.StockLevel > 0) { if (!Model.Item.GetBoolean("HideInventory")) { <div class="small text-success">@product.StockLevel @Translate("Products available in stock")</div> } else { <div class="small text-success">@Translate("Available in stock")</div> } } else { <div class="small text-danger">@Translate("Out of Stock")</div> } @if (hasExpectedDelivery) { <div> <span>@Translate("Expected back in stock:")</span> <span>@expectedDeliveryDate</span> </div> } </div> } } } </div> @helper RenderField(FieldValueViewModel field) { string fieldValue = field?.Value != null ? field.Value.ToString() : ""; bool noValues = false; if (!string.IsNullOrEmpty(fieldValue)) { if (field.Value.GetType() == typeof(System.Collections.Generic.List<FieldOptionValueViewModel>)) { System.Collections.Generic.List<FieldOptionValueViewModel> values = field.Value as System.Collections.Generic.List<FieldOptionValueViewModel>; noValues = values.Count > 0 ? false : true; } } if (!string.IsNullOrEmpty(fieldValue) && noValues == false) { <dt class="g-col-12 g-col-sm-4 g-col-lg-12 fw-bold m-0">@field.Name</dt> <dd class="g-col-12 g-col-sm-8 g-col-lg-12 mb-3"> @RenderFieldValue(field) </dd> } } @helper RenderFieldValue(FieldValueViewModel field) { string fieldValue = field?.Value != null ? field.Value.ToString() : ""; fieldValue = fieldValue == "False" ? Translate("No") : fieldValue; fieldValue = fieldValue == "True" ? Translate("Yes") : fieldValue; bool isColor = false; if (field.Value.GetType() == typeof(System.Collections.Generic.List<Dynamicweb.Ecommerce.ProductCatalog.FieldOptionValueViewModel>)) { int valueCount = 0; System.Collections.Generic.List<FieldOptionValueViewModel> values = field.Value as System.Collections.Generic.List<FieldOptionValueViewModel>; int totalValues = values.Count; foreach (FieldOptionValueViewModel option in values) { if (!string.IsNullOrEmpty(option.Value)) { if (option.Value.Substring(0, 1) == "#") { isColor = true; } } if (!isColor) { @option.Name } else { <span class="colorbox-sm" style="background-color: @option.Value" title="@option.Value"></span> } if (valueCount != totalValues && valueCount < (totalValues - 1)) { if (isColor) { <text> </text> } else { <text>, </text> } } valueCount++; } } else { if (fieldValue.Substring(0, 1) == "#") { isColor = true; } if (!isColor) { @fieldValue } else { <span class="colorbox-sm" style="background-color: @fieldValue" title="@fieldValue"></span> } } }