Error executing template "/Designs/Swift-v2/Paragraph/Custom_ProductDetailInformation.cshtml"
System.OverflowException: Value was either too large or too small for an Int32.
   at System.Decimal.ToInt32(Decimal d)
   at CompiledRazorTemplates.Dynamic.RazorEngine_59adbe5a9dda4b8d9d5ebad185b48c33.ExecuteAsync()
   at RazorEngine.Templating.TemplateBase.Run(ExecuteContext context, TextWriter reader)
   at RazorEngine.Templating.RazorEngineCore.RunTemplate(ICompiledTemplate template, TextWriter writer, Object model, DynamicViewBag viewBag)
   at RazorEngine.Templating.RazorEngineService.Run(ITemplateKey key, TextWriter writer, Type modelType, Object model, DynamicViewBag viewBag)
   at RazorEngine.Templating.DynamicWrapperService.Run(ITemplateKey key, TextWriter writer, Type modelType, Object model, DynamicViewBag viewBag)
   at RazorEngine.Templating.RazorEngineServiceExtensions.Run(IRazorEngineService service, String name, TextWriter writer, Type modelType, Object model, DynamicViewBag viewBag)
   at RazorEngine.Templating.RazorEngineServiceExtensions.<>c__DisplayClass23_0.<Run>b__0(TextWriter writer)
   at RazorEngine.Templating.RazorEngineServiceExtensions.WithWriter(Action`1 withWriter)
   at RazorEngine.Templating.RazorEngineServiceExtensions.Run(IRazorEngineService service, String name, Type modelType, Object model, DynamicViewBag viewBag)
   at Dynamicweb.Rendering.RazorTemplateRenderingProvider.Render(Template template)
   at Dynamicweb.Rendering.TemplateRenderingService.Render(Template template)
   at Dynamicweb.Rendering.Template.RenderRazorTemplate()

1 @inherits Dynamicweb.Rendering.ViewModelTemplate<Dynamicweb.Frontend.ParagraphViewModel> 2 @using System.Globalization 3 @using Dynamicweb.Ecommerce.ProductCatalog 4 @using Dynamicweb.Core.Encoders 5 @using Dynamicweb.Ecommerce 6 @using Dynamicweb.Ecommerce.Products 7 @using Dynamicweb.Ecommerce.Stocks 8 @using Dynamicweb.Security.UserManagement 9 10 @functions { 11 12 private static bool BackInStockRegisteredForUser(ProductViewModel product, string unitId = "", long stocklocationId = 0) 13 { 14 if (!UserContext.Current.IsLoggedOn) return false; 15 16 Product productObject = Services.Products.GetProductById(product.Id, product.VariantId, product.LanguageId); 17 StockLocation stockLocation = Services.StockService.GetStockLocation(stocklocationId); 18 double unitStock = productObject.GetUnitStock(stockLocation, unitId); 19 return unitStock <= 0d && Dynamicweb.Ecommerce.Services.ProductStockNotifications.NotificationExists(productObject, unitId); 20 } 21 22 public bool IsActiveProduct(string productId, string languageId = null) 23 { 24 var service = new ProductService(); 25 var product = service.GetProductById(productId, productVariantId: null, productLanguageId: languageId, useAssortments: false); 26 // If null → not a product; if not null → check Active flag 27 return product != null && product.Active; 28 } 29 30 } 31 32 33 @{ 34 ProductViewModel product = null; 35 if (Dynamicweb.Context.Current.Items != null && Dynamicweb.Context.Current.Items.Contains("ProductDetails")) 36 { 37 product = Dynamicweb.Context.Current.Items["ProductDetails"] as ProductViewModel; 38 } 39 else if (!string.IsNullOrEmpty(Pageview?.Page?.Item?["DummyProduct"]?.ToString()) && Pageview?.IsVisualEditorMode == true) 40 { 41 var pageViewModel = Dynamicweb.Frontend.ContentViewModelFactory.CreatePageInfoViewModel(Pageview.Page); 42 ProductListViewModel productList = pageViewModel?.Item?.GetValue("DummyProduct") != null ? pageViewModel.Item.GetValue("DummyProduct") as ProductListViewModel : new ProductListViewModel(); 43 44 if (productList?.Products is object && productList.Products.Any()) 45 { 46 product = productList.Products[0]; 47 } 48 } 49 else if (Pageview?.IsVisualEditorMode == true) 50 { 51 product = new ProductViewModel(); 52 product.Name = Translate("My product"); 53 product.Number = "394041"; 54 product.ProductFields = new Dictionary<string, FieldValueViewModel>() 55 { 56 ["Brand"] = new() { Value = "Sample Brand" } 57 }; 58 product.Id = "1"; 59 product.VariantId = "394041"; 60 product.PurchaseMinimumQuantity = 1; 61 product.PurchaseQuantityStep = 1; 62 product.StockLevel = 10; 63 product.DefaultUnitId = "1"; 64 product.ProductType = Dynamicweb.Ecommerce.Products.ProductType.Stock; 65 product.NeverOutOfstock = false; 66 product.Discontinued = false; 67 product.Price = new PriceViewModel() 68 { 69 Price = 99, 70 PriceFormatted = "99 " + (Pageview?.Area?.EcomCurrencyId ?? ""), 71 PriceWithoutVat = 99, 72 PriceWithoutVatFormatted = "99 " + (Pageview?.Area?.EcomCurrencyId ?? ""), 73 PriceWithVat = 99, 74 PriceWithVatFormatted = "99 " + (Pageview?.Area?.EcomCurrencyId ?? "") 75 }; 76 product.PriceInformative = new PriceViewModel() 77 { 78 Price = 49, 79 PriceFormatted = "49 " + (Pageview?.Area?.EcomCurrencyId ?? ""), 80 PriceWithoutVat = 49, 81 PriceWithoutVatFormatted = "49 " + (Pageview?.Area?.EcomCurrencyId ?? ""), 82 PriceWithVat = 49, 83 PriceWithVatFormatted = "49 " + (Pageview?.Area?.EcomCurrencyId ?? "") 84 }; 85 product.PriceBeforeDiscount = new PriceViewModel() 86 { 87 Price = 199, 88 PriceFormatted = "199 " + (Pageview?.Area?.EcomCurrencyId ?? ""), 89 PriceWithoutVat = 199, 90 PriceWithoutVatFormatted = "199 " + (Pageview?.Area?.EcomCurrencyId ?? ""), 91 PriceWithVat = 199, 92 PriceWithVatFormatted = "99 " + (Pageview?.Area?.EcomCurrencyId ?? "") 93 }; 94 } 95 } 96 97 @functions { 98 99 public static string GetContrastColor(string hexString) 100 { 101 if (string.IsNullOrEmpty(hexString)) return "#333"; 102 System.Drawing.Color bg; 103 try 104 { 105 bg = System.Drawing.ColorTranslator.FromHtml(hexString); 106 } 107 catch 108 { 109 return "#333"; 110 } 111 112 int nThreshold = 105; 113 int bgDelta = Convert.ToInt32((bg.R * 0.299) + (bg.G * 0.587) + 114 (bg.B * 0.114)); 115 116 string foreColor = (255 - bgDelta < nThreshold) ? "#333" : "#fff"; 117 return foreColor; 118 } 119 120 public string GetLayoutForVariantGroup(string variantGroupId) 121 { 122 string showVariantGroups = !string.IsNullOrEmpty(Model?.Item?.GetString("ShowVariantGroupOptions")) ? Model.Item.GetString("ShowVariantGroupOptions") : "all"; 123 string defaultVariantGroupLayout = Model?.Item?.GetRawValueString("DefaultVariantGroupLayout", "button"); 124 var selectedVariantGroupsList = !string.IsNullOrEmpty(Model?.Item?.GetRawValueString("VariantGroups")) ? Model.Item.GetItems("VariantGroups") : new List<Dynamicweb.Frontend.ItemViewModel>(); 125 126 if (showVariantGroups == "all" || selectedVariantGroupsList == null || !selectedVariantGroupsList.Any()) return defaultVariantGroupLayout; 127 128 foreach (var selectedVariantGroupListItem in selectedVariantGroupsList) 129 { 130 var variantGroups = (selectedVariantGroupListItem?.GetRawValueString("VariantGroups") ?? "").Split(','); 131 if (variantGroups.Any(s => s.Equals(variantGroupId))) return selectedVariantGroupListItem.GetRawValueString("VariantGroupLayout"); 132 } 133 134 return defaultVariantGroupLayout; 135 } 136 137 //Collect all variant images 138 public static Dictionary<string, string> GetVariantImages(List<VariantInfoViewModel> variantInfo, Dictionary<string, string> list) 139 { 140 if (variantInfo == null) return list ?? new Dictionary<string, string>(); 141 foreach (var variantGroup in variantInfo) 142 { 143 if (variantGroup?.Image?.Value != null && !string.IsNullOrEmpty(variantGroup.OptionID) && !list.ContainsKey(variantGroup.OptionID)) 144 { 145 list.Add(variantGroup.OptionID, variantGroup.Image.Value); 146 } 147 148 if (variantGroup?.VariantInfo != null) 149 { 150 GetVariantImages(variantGroup.VariantInfo, list); 151 } 152 } 153 154 return list; 155 } 156 157 private string GetDefaultOrVariantGroupValue(string variantGroupId, string itemField, string itemFieldDefaultValue, Dictionary<string, string> fieldValueMapping) 158 { 159 if (!string.IsNullOrEmpty(variantGroupId)) 160 { 161 string itemFieldValue = Model?.Item?.GetRawValueString(itemField, itemFieldDefaultValue) != null ? Model.Item.GetRawValueString(itemField, itemFieldDefaultValue) : string.Empty; 162 itemFieldValue = itemFieldValue == string.Empty && GetViewParameterString(itemField) != null ? GetViewParameterString(itemField) : itemFieldValue; 163 164 itemFieldValue = fieldValueMapping != null && fieldValueMapping.ContainsKey(itemFieldValue) ? fieldValueMapping[itemFieldValue] : itemFieldValue; 165 166 // If no variantGroup (i.e. Visual Editor), return default value 167 if (string.IsNullOrEmpty(variantGroupId)) return itemFieldValue; 168 169 string showVariantGroups = Model?.Item?.GetString("ShowVariantGroupOptions", "all"); 170 var selectedVariantGroupsList = !string.IsNullOrEmpty(Model?.Item?.GetRawValueString("VariantGroups")) ? Model.Item.GetItems("VariantGroups") : new List<Dynamicweb.Frontend.ItemViewModel>(); 171 // If no exceptions or settings are all the same, return default value 172 if (showVariantGroups == "all" || selectedVariantGroupsList == null || !selectedVariantGroupsList.Any()) return itemFieldValue; 173 174 // Get specific value for variant group 175 foreach (var selectedVariantGroupListItem in selectedVariantGroupsList) 176 { 177 var variantGroups = (selectedVariantGroupListItem?.GetRawValueString("VariantGroups") ?? "").Split(','); 178 if (!variantGroups.Any(s => s.Equals(variantGroupId))) continue; 179 180 itemFieldValue = selectedVariantGroupListItem.GetRawValueString(itemField, itemFieldDefaultValue); 181 itemFieldValue = fieldValueMapping != null && fieldValueMapping.ContainsKey(itemFieldValue) ? fieldValueMapping[itemFieldValue] : itemFieldValue; 182 } 183 184 return itemFieldValue; 185 } 186 else 187 { 188 return string.Empty; 189 } 190 } 191 192 private bool GetDefaultOrVariantGroupValue(string variantGroupId, string itemField) 193 { 194 if (!string.IsNullOrEmpty(variantGroupId)) 195 { 196 bool itemFieldValue = Model?.Item?.GetBoolean(itemField) != null ? Model.Item.GetBoolean(itemField) : false; 197 198 // If no variantGroup (i.e. Visual Editor), return default value 199 if (string.IsNullOrEmpty(variantGroupId)) return itemFieldValue; 200 201 string showVariantGroups = Model?.Item?.GetString("ShowVariantGroupOptions", "all"); 202 var selectedVariantGroupsList = !string.IsNullOrEmpty(Model?.Item?.GetRawValueString("VariantGroups")) ? Model.Item.GetItems("VariantGroups") : new List<Dynamicweb.Frontend.ItemViewModel>(); 203 // If no exceptions or settings are all the same, return default value 204 if (showVariantGroups == "all" || selectedVariantGroupsList == null || !selectedVariantGroupsList.Any()) return itemFieldValue; 205 206 // Get specific value for variant group 207 foreach (var selectedVariantGroupListItem in selectedVariantGroupsList) 208 { 209 var variantGroups = (selectedVariantGroupListItem?.GetRawValueString("VariantGroups") ?? "").Split(','); 210 if (!variantGroups.Any(s => s.Equals(variantGroupId))) continue; 211 212 itemFieldValue = selectedVariantGroupListItem.GetBoolean(itemField); 213 } 214 215 return itemFieldValue; 216 } 217 else 218 { 219 return false; 220 } 221 } 222 223 } 224 225 @{ 226 if (product is object) 227 { 228 var notifyLabel = Translate("Notify me when available"); 229 string notifiedMessage = Model.Item.GetString("NotifiedMessage"); 230 string notifiedMessageId = $"NotifiedMessage_item_{Model.Item.SystemName.ToLower()}_{product.Id}_{product.VariantId.Replace(".", "_")}"; 231 232 string modalId = $"modal_item_{Model.Item.SystemName.ToLower()}_{product.Id}_{product.VariantId.Replace(".", "_")}"; 233 string formId = $"NotificationForm_item_{Model.Item.SystemName.ToLower()}_{product.Id}_{product.VariantId.Replace(".", "_")}"; 234 string notificationButtonId = $"NotificationButton_item_{Model.Item.SystemName.ToLower()}_{product.Id}_{product.VariantId.Replace(".", "_")}"; 235 string notificationOnClick = !Pageview.IsVisualEditorMode ? $"swift.BackInStockNotification.SubmitNotification('{formId}', '{modalId}', '{notifiedMessageId}', '{notificationButtonId}')" : ""; 236 237 string productPage = $"Default.aspx?ID={GetPageIdByNavigationTag("ProductDetailPage")}"; 238 239 string unitId = !string.IsNullOrEmpty(Dynamicweb.Context.Current.Request?.Form?.Get("UnitId")) ? Dynamicweb.Context.Current.Request.Form.Get("UnitId") : string.Empty; 240 string showPricesWithVat = (Pageview?.Area?.EcomPricesWithVat ?? "").ToLower(); 241 bool neverShowVat = string.IsNullOrEmpty(showPricesWithVat); 242 243 string priceMin = ""; 244 string priceMax = ""; 245 var rawContactValue1 = product?.ProductFields != null && product.ProductFields.ContainsKey("ProductContactStock") ? product.ProductFields["ProductContactStock"]?.Value?.ToString().Replace(",", "") : null; 246 // Try to parse using the current culture (so 6,520 becomes 6.520) 247 bool parsedDecimal2 = decimal.TryParse( 248 rawContactValue1, 249 NumberStyles.Any, 250 CultureInfo.CurrentCulture, 251 out decimal stockDecimal2 252 ); 253 // Convert decimal to integer (you can change this if needed) 254 int stockValue2 = parsedDecimal2? (int)stockDecimal2 : -1; 255 string disableAddToCart = (product?.StockLevel + stockValue2 <= 0) ? "disabled" : ""; 256 bool isNeverOutOfStock = product?.NeverOutOfstock == true; 257 disableAddToCart = isNeverOutOfStock ? "" : disableAddToCart; 258 259 string minQty = product?.PurchaseMinimumQuantity != null && product.PurchaseMinimumQuantity != 1 ? $"min=\"{product.PurchaseMinimumQuantity.ToString()}\"" : "min=\"1\""; 260 string stepQty = product?.PurchaseQuantityStep > 1 ? product.PurchaseQuantityStep.ToString() : "1"; 261 string valueQty = product?.PurchaseMinimumQuantity > product?.PurchaseQuantityStep ? product.PurchaseMinimumQuantity.ToString() : stepQty; 262 disableAddToCart = product?.VariantInfo?.VariantInfo != null && string.IsNullOrEmpty(product?.VariantId) ? "disabled" : disableAddToCart; 263 disableAddToCart = product?.Discontinued == true ? "disabled" : disableAddToCart; 264 265 string iconPath = "/Files/icons/"; 266 string addToCartIcon = Model?.Item?.GetRawValueString("Icon", iconPath + "shopping-cart.svg") ?? (iconPath + "shopping-cart.svg"); 267 string addToCartLabel = !addToCartIcon.Contains("_none") ? $"<span class=\"icon-2\">{ReadFile(addToCartIcon)}</span>" : ""; 268 addToCartLabel += !addToCartIcon.Contains("_none") && !(Model?.Item?.GetBoolean("HideButtonText") ?? false) ? " " : ""; 269 addToCartLabel += !(Model?.Item?.GetBoolean("HideButtonText") ?? false) ? $"<span class=\"d-none d-md-inline\">{Translate("Add to cart")}</span><span class=\"d-inline d-md-none\">{Translate("Add")}</span>" : ""; 270 string url = "/Default.aspx?ID=" + GetPageIdByNavigationTag("CartService"); 271 var signInPageId = Dynamicweb.Content.Services.Pages.GetPageByNavigationTag(Pageview?.Area?.ID ?? 0, "SignInPage")?.ID ?? 0; 272 string signInPageUrl = Dynamicweb.Frontend.SearchEngineFriendlyURLs.GetFriendlyUrl(signInPageId); 273 var contactPageId = Dynamicweb.Content.Services.Pages.GetPageByNavigationTag(Pageview?.Area?.ID ?? 0, "ContactPage")?.ID ?? 0; 274 string contactPageUrl = Dynamicweb.Frontend.SearchEngineFriendlyURLs.GetFriendlyUrl(contactPageId); 275 var productOrVariantId = !string.IsNullOrEmpty(product?.VariantId) ? product.VariantId : (product?.Id ?? ""); 276 277 var recentlyViewedProductsCookie = Dynamicweb.Context.Current?.Request?.GetCookie("recentlyViewedProducts")?.Value ?? ""; 278 var recentlyViewedList = !string.IsNullOrEmpty(recentlyViewedProductsCookie) ? recentlyViewedProductsCookie.Split(',').ToList() : new List<string>(); 279 recentlyViewedList = recentlyViewedList.Where(id => IsActiveProduct(id)).ToList(); 280 var currentProductIdentifier = !string.IsNullOrEmpty(product?.VariantId) ? $"{product.Id}-{product.VariantId}" : $"{product.Id}"; 281 282 // Remove if already exists to avoid duplicates and move it to the end 283 recentlyViewedList.Remove(currentProductIdentifier); 284 recentlyViewedList.Add(currentProductIdentifier); 285 286 if (recentlyViewedList.Count > 10) 287 { 288 recentlyViewedList.RemoveAt(0); // Remove the oldest item 289 } 290 291 var newCookieValue = string.Join(",", recentlyViewedList); 292 var cookie = new Dynamicweb.Environment.Cookie("recentlyViewedProducts", newCookieValue) 293 { 294 Expires = DateTime.Now.AddDays(30) 295 }; 296 Dynamicweb.Context.Current?.Response.SetCookie(cookie); 297 var shopPageId = GetPageIdByNavigationTag("Shop"); 298 var shopUrl = Dynamicweb.Frontend.SearchEngineFriendlyURLs.GetFriendlyUrl(shopPageId) ?? "/"; 299 string groupPathUrl = ""; 300 if (product.GroupPaths != null) 301 { 302 foreach (var cat in product?.GroupPaths) 303 { 304 foreach (var var in cat) 305 { 306 groupPathUrl += "/" + var?.Name?.Replace(" ", "-"); 307 } 308 } 309 } 310 311 var primaryGroup = product?.Groups; 312 313 314 // Last group in the path 315 var lastGroup = product.Groups?.LastOrDefault(); 316 317 var brandPageLink = shopUrl + "?" + "GroupId=" + lastGroup?.Id?.ToString() + "&PageSize=24" + "&Marca=" + product?.Manufacturer?.Name; 318 <input type="hidden" name="ProductId" id="ProductId" value="@productOrVariantId"/> 319 <div class="product-detail-information-wrapper"> 320 <div class="product-detail-information"> 321 @if (!String.IsNullOrEmpty(product.Manufacturer?.Name) && product.Manufacturer?.Name != null) 322 { 323 <a href="@brandPageLink" target="_blank" class="mb-0 fw-bold mb-2 d-inline-block">@product.Manufacturer?.Name</a> 324 } 325 <h3 class="dw-h2 p-0 mb-3" style="text-wrap: pretty;">@(product?.Name ?? "")</h3> 326 <div class="brand-container mb-3"> 327 <div class=" d-flex align-items-start flex-column gap-0"> 328 @if (!string.IsNullOrEmpty(product?.Number)) 329 { 330 <p class="fs-7 p-0 mb-1">@Translate("Cod produs:") 331 <span 332 class="text-primary fw-semibold fs-7 ms-2">@product.Number</span> 333 </p> 334 } 335 @if (!string.IsNullOrEmpty(product?.EAN)) 336 { 337 <p class="fs-7 p-0 mb-0">@Translate("Numărul EAN / GLN:") 338 <span 339 class="text-primary fw-semibold fs-7 ms-2 mb-0">@product.EAN</span> 340 </p> 341 } 342 343 344 @{ 345 var iconsList = new List<string>(); 346 for (int i = 1; i <= 8; i++) 347 { 348 var iconText = "Icon" + i.ToString(); 349 var iconField = product?.ProductFields != null && product.ProductFields.ContainsKey(iconText) ? product.ProductFields[iconText] : null; 350 var iconVal = iconField?.Value?.ToString(); 351 if (!string.IsNullOrEmpty(iconVal)) 352 { 353 iconsList.Add(iconVal); 354 } 355 } 356 } 357 358 @if (iconsList.Any()) 359 { 360 <div class="d-flex gap-2 py-3"> 361 @foreach (var iconVal in iconsList) 362 { 363 if (iconVal.Contains("svg")) 364 { 365 <span class="icon-4">@ReadFile(iconVal)</span> 366 } 367 else 368 { 369 var iconIndex = iconsList.IndexOf(iconVal) + 1; 370 var altText = product?.ProductFields?.ContainsKey($"Icon{iconIndex}AltText") == true ? (product.ProductFields[$"Icon{iconIndex}AltText"]?.Value?.ToString() ?? "") : ""; 371 <span class="icon-4"><img width="32" height="32" src="@iconVal" alt="@altText"></span> 372 } 373 } 374 </div> 375 } 376 377 </div> 378 </div> 379 380 <div class="product-action bg-white rounded-6 p-4 d-flex flex-column gap-3"> 381 @if (Pageview?.User != null) 382 { 383 var location = Dynamicweb.Ecommerce.Services.StockService.GetStockLocation(Pageview?.User?.StockLocationID ?? 0); 384 string locationName = location != null ? location.GetName(Pageview.Area.ID.ToString()) : "HQ1"; 385 var stocUnit = product?.ProductFields != null && product.ProductFields.ContainsKey("SalesUOM") ? product.ProductFields["SalesUOM"]?.Value.ToString().ToLower() : null; 386 var rawContactValue = product?.ProductFields != null && product.ProductFields.ContainsKey("ProductContactStock") ? product.ProductFields["ProductContactStock"]?.Value?.ToString().Replace(",", "") : null; 387 // Try to parse using the current culture (so 6,520 becomes 6.520) 388 bool parsedDecimal = decimal.TryParse( 389 rawContactValue, 390 NumberStyles.Any, 391 CultureInfo.CurrentCulture, 392 out decimal stockDecimal 393 ); 394 // Convert decimal to integer (you can change this if needed) 395 int stockValue = parsedDecimal ? (int)stockDecimal : -1; 396 // Contact Stock Text Color 397 var contactStockTextColor = 398 parsedDecimal 399 ? (stockValue <= 5 ? stockValue <= 0 ? "--bs-red" : "--dw-color-button-secondary" : "") 400 : "--dw-color-button-secondary"; 401 // Product Stock Text Color 402 var productStockTextColor = 403 (product?.StockLevel ?? 0) <= 5 ? product?.StockLevel <= 0 ? "--bs-red" : "--dw-color-button-secondary" : ""; 404 // Contact Stock Icon 405 var contactStockIcon = 406 parsedDecimal 407 ? (stockValue <= 5 408 ? stockValue <= 0 ? "Files/Images/Elbi/Icons/errorStockicon.svg" : "Files/Images/Elbi/Icons/OrangeStockIcon.svg" 409 : "Files/Images/Elbi/Icons/GreenStockCircle.svg") 410 : "Files/Images/Elbi/Icons/OrangeStockIcon.svg"; 411 // Product Stock Icon 412 var stockIcon = 413 (product?.StockLevel ?? 0) <= 10 414 ? product?.StockLevel <= 0 ? "Files/Images/Elbi/Icons/errorStockicon.svg" : "Files/Images/Elbi/Icons/OrangeStockIcon.svg" 415 : "Files/Images/Elbi/Icons/GreenStockCircle.svg"; 416 string ellipseIcon = "Files/Images/Elbi/Icons/OrangeStockIcon.svg"; 417 string greenIcon = "Files/Images/Elbi/Icons/GreenStockCircle.svg"; 418 string redIcon = "Files/Images/Elbi/Icons/errorStockicon.svg"; 419 420 // If one of them is green → final is green 421 var finalIcon = (contactStockIcon == greenIcon || stockIcon == greenIcon) 422 ? greenIcon 423 :(contactStockIcon == redIcon && stockIcon == redIcon) ? redIcon : ellipseIcon; 424 425 // Text based on final icon 426 var finalText = finalIcon == greenIcon 427 ? Translate("In stoc") 428 : Translate("Stoc limitat"); 429 430 431 <div class="d-flex flex-row justify-content-between"> 432 <div class="price-container"> 433 @if (product?.PriceInformative.Price != null && product.PriceInformative.Price != 0) 434 { 435 <div class="opacity-50"> 436 <span>@Translate("RRP") </span> 437 <span 438 class="text-decoration-line-through text-price fs-4 fw-bold">@product.PriceInformative.PriceFormatted</span> 439 </div> 440 } 441 @{ 442 string price = !string.IsNullOrEmpty(unitId) ? (product?.GetPrice(unitId)?.Price.PriceWithVatFormatted ?? product?.Price.PriceWithVatFormatted ?? "") : (product?.Price?.PriceWithVatFormatted ?? ""); 443 444 if (product?.VariantInfo?.VariantInfo != null) 445 { 446 priceMin = product?.VariantInfo?.PriceMin?.PriceWithVatFormatted ?? ""; 447 priceMax = product?.VariantInfo?.PriceMax?.PriceWithVatFormatted ?? ""; 448 } 449 450 if (!string.IsNullOrEmpty(priceMin) && !string.IsNullOrEmpty(priceMax) && priceMin != priceMax) 451 { 452 price = priceMin + " - " + priceMax; 453 } 454 455 <div class="d-sm-inline-flex gap-2"> 456 @if (string.IsNullOrEmpty(product?.Number)) 457 { 458 string price2 = !string.IsNullOrEmpty(unitId) ? (product?.GetPrice(unitId)?.Price?.PriceWithVatFormatted ?? product?.Price?.PriceWithVatFormatted ?? "") : (product?.Price?.PriceWithVatFormatted ?? ""); 459 460 if (product?.VariantInfo?.VariantInfo != null) 461 { 462 priceMin = product?.VariantInfo?.PriceMin?.PriceWithVatFormatted ?? ""; 463 priceMax = product?.VariantInfo?.PriceMax?.PriceWithVatFormatted ?? ""; 464 } 465 466 if (!string.IsNullOrEmpty(priceMin) && !string.IsNullOrEmpty(priceMax) && priceMin != priceMax) 467 { 468 price2 = priceMin + " - " + priceMax; 469 } 470 471 <p 472 class="fw-bold fs-4 text-primary m-0">@Translate("De la") @price2</p> 473 } 474 else 475 { 476 <p 477 class="fw-bold fs-4 text-primary m-0">@product?.Price?.PriceFormatted</p> 478 } 479 <div itemprop="offers" itemscope itemtype="https://schema.org/Offer"> 480 <span itemprop="priceCurrency" content="@product?.Price?.CurrencyCode" 481 class="d-none"></span> 482 @{ 483 string beforePrice = !string.IsNullOrEmpty(unitId) ? (product?.GetPrice(unitId)?.PriceBeforeDiscount?.PriceFormatted ?? product?.PriceBeforeDiscount?.PriceFormatted ?? "") : (product?.PriceBeforeDiscount?.PriceFormatted ?? ""); 484 } 485 <span itemprop="price" content="@(product?.Price?.Price ?? 0)" class="d-none"></span> 486 487 @if ((product?.Price?.Price ?? 0) != (product?.PriceBeforeDiscount?.Price ?? 0)) 488 { 489 <span class="text-decoration-line-through opacity-75 order-1"> 490 <span class="text-price fs-4 fw-bold">@beforePrice</span> 491 </span> 492 } 493 494 495 @{ 496 Uri urlProp = Dynamicweb.Context.Current?.Request?.Url ?? new Uri("http://localhost/"); 497 } 498 499 <link itemprop="url" href="@urlProp"> 500 501 </div> 502 <span 503 class="opacity-75 fs-7 d-flex justify-content-start align-items-end">@Translate("incl. TVA") @product?.Price?.PriceWithVatFormatted</span> 504 </div> 505 } 506 @if (!string.IsNullOrEmpty(product?.Number?.ToString())) 507 { 508 <div class="d-sm-flex align-items-center gap-3 mt-2"> 509 <p class="mb-0 fs-7 p-0"> @Translate("Status: ") 510 <span itemprop="availability" 511 class="fw-semibold" 512 style="color: var(--dw-color-button-primary);">@finalText</span> 513 </p> 514 <p class="mb-0 fs-7 p-0">@Translate("Livrare estimata: ") 515 <span 516 class="text-primary fw-semibold">@(finalIcon != redIcon ? product.ExpectedDelivery.ToString() == "" ? "1-2 zile" : "" : "Indisponibil")</span> 517 </p> 518 </div> 519 } 520 </div> 521 <div>@RenderPartial("Components/ToggleFavorite.cshtml", product) 522 </div> 523 </div> 524 @if (!string.IsNullOrEmpty(product?.Number?.ToString())) 525 { 526 string stockLocationValue = "0" ; 527 <div class="d-flex flex-column"> 528 @if (locationName != "HQ1") 529 { 530 string stockLocationName = location != null ? location.GetDescription(Pageview.Area.ID.ToString() ?? "") : ""; 531 stockLocationValue = product?.ProductFields != null && product.ProductFields.ContainsKey("ProductContactStock") && product.ProductFields["ProductContactStock"]?.Value != null && !string.IsNullOrEmpty(product.ProductFields["ProductContactStock"].Value.ToString()) ? product.ProductFields["ProductContactStock"].Value.ToString().Replace(",", ""): "0"; 532 <div class="d-flex flex-row gap-2 align-items-center"> 533 <span 534 class="icon-1">@((!string.IsNullOrEmpty(contactStockIcon) ? ReadFile(contactStockIcon) : ""))</span> 535 <span>@stockLocationName</span> 536 <span class="fw-semibold" 537 style="color: var(@(contactStockTextColor ?? "--dw-color-button-secondary"));">@stockLocationValue @stocUnit</span> 538 </div> 539 } 540 <div class="d-flex flex-row gap-2 align-items-center"> 541 <span class="icon-1">@((!string.IsNullOrEmpty(stockIcon) ? ReadFile(stockIcon) : ""))</span> 542 <span>@Translate("Depozit Bucuresti:") </span> 543 <span class="fw-semibold" 544 style="color: var(@(productStockTextColor ?? "--dw-color-button-secondary"));">@(product?.StockLevel ?? 0) @(product?.ProductFields != null && product.ProductFields.ContainsKey("SalesUOM") ? product.ProductFields["SalesUOM"]?.Value?.ToString().ToLower() ?? "" : "")</span> 545 </div> 546 @{ 547 bool productInStock = product.StockLevel > 0 || product.NeverOutOfstock || Convert.ToInt32(stockLocationValue) > 0; 548 549 if (!productInStock) 550 { 551 552 string horizontalAlign = Model.Item.GetRawValueString("HorizontalAlignment", ""); 553 horizontalAlign = horizontalAlign == "center" ? "justify-content-center" : horizontalAlign; 554 horizontalAlign = horizontalAlign == "end" ? "justify-content-end" : horizontalAlign; 555 horizontalAlign = horizontalAlign == "full" ? "" : horizontalAlign; 556 557 string flexFill = Model.Item.GetRawValueString("HorizontalAlignment", "") == "full" ? "flex-fill" : ""; 558 string fullWidth = Model.Item.GetRawValueString("HorizontalAlignment", "") == "full" ? "w-100" : ""; 559 560 bool notificationRegisteredForUser = BackInStockRegisteredForUser(product); 561 562 <div 563 class="d-flex flex-row w-100 @horizontalAlign @fullWidth item_@Model.Item.SystemName.ToLower()"> 564 <div class="@horizontalAlign @fullWidth @(notificationRegisteredForUser ? "" : "d-none")" 565 id="@notifiedMessageId"> 566 @notifiedMessage 567 </div> 568 569 @if (!notificationRegisteredForUser) 570 { 571 572 573 <div class="d-flex @horizontalAlign @fullWidth js-input-group mt-2"> 574 <div class="input-group input-primary-button-group flex-nowrap"> 575 <button type="button" class="btn btn-primary @flexFill" data-dw-button="primary" 576 id="@notificationButtonId" data-bs-toggle="modal" data-bs-target="#@modalId"> 577 <span class="text-nowrap d-flex align-items-center justify-content-center gap-2"> 578 @notifyLabel 579 </span> 580 </button> 581 </div> 582 </div> 583 584 585 } 586 587 </div> 588 } 589 } 590 </div> 591 592 <div class="d-flex flex-column js-input-group item_@(Model?.Item?.SystemName?.ToLower() ?? "")"> 593 <p class="mb-2"><span>@Translate("Cantitate minima:")</span> 594 <span 595 class="fw-semibold"> @(product?.PurchaseMinimumQuantity != 0 ? product.PurchaseMinimumQuantity : "1") @stocUnit</span></p> 596 <div class="d-flex gap-2 flex-row flex-nowrap" style="height: 3.5ch"> 597 <form method="post" action="@url" class="d-flex align-items-center gap-2" style="z-index: 1"> 598 <input type="hidden" name="redirect" value="false"> 599 <input type="hidden" name="ProductId" value="@product?.Id"> 600 <input type="hidden" name="ProductName" value="@HtmlEncoder.HtmlEncode(product?.Name ?? "")"> 601 <input type="hidden" name="ProductVariantName" value="@product?.VariantName"> 602 <input type="hidden" name="ProductVariantId" value="@product?.VariantId"> 603 <input type="hidden" name="VariantId" value="@product?.VariantId"> 604 <input type="hidden" name="ProductCurrency" 605 value="@Dynamicweb.Ecommerce.Common.Context.Currency?.Code"> 606 <input type="hidden" name="ProductPrice" value="@(product?.Price?.ToStringInvariant() ?? "0")"> 607 <input type="hidden" name="ProductDiscount" 608 value="@(product?.Discount?.ToStringInvariant() ?? "0")"> 609 <input type="hidden" name="ProductReferer" value="component_ProductAddToCart"> 610 <input type="hidden" name="cartcmd" value="add"> 611 <input type="submit" class="d-none" 612 onclick="event.preventDefault(); swift.Cart.Update(event)"> @* Fix for enterKey should not redirect to minicart page *@ 613 614 @RenderPartial("Components/Elbi_QuantitySelector.cshtml", product) 615 616 <button type="button" onclick="swift.Cart.Update(event)" 617 class="js-add-to-cart-button btn btn-secondary d-flex align-items-center text-center gap-2" 618 data-dw-button="secondary" style="white-space: nowrap;max-height: 3.5ch" @(disableAddToCart) 619 title="@Translate("Add to cart")" 620 id="AddToCartButton@(product?.Id)_@Pageview?.CurrentParagraph?.ID"> 621 <span>@Translate("Adaugă în coș")</span> 622 <span 623 class="d-flex align-items-center justify-content-center icon-2">@ReadFile("Files/Images/Elbi/Icons/cart.svg")</span> 624 </button> 625 </form> 626 </div> 627 </div> 628 } 629 } 630 else 631 { 632 <div class="d-flex flex-column justify-content-between" style=""> 633 <p class="d-flex align-items-start justify-content-start gap-2"> 634 <span 635 class="d-flex align-items-center justify-content-center icon-2 mt-1">@ReadFile("Files/Images/Elbi/Icons/Attention-icon.svg")</span> 636 <span class="fs-7">@Translate("Pentru a vedea mai multe informații trebuie sa te autentifici")</span> 637 </p> 638 <div class="d-flex justify-content-start gap-2 flex-wrap" style=""> 639 <a type="button" href="@signInPageUrl" 640 class=" btn btn-secondary d-flex align-items-center text-center gap-2" data-dw-button="secondary" 641 style="white-space: nowrap;max-height: 3.5ch" title="@Translate("Autentificare")"> 642 <span>@Translate("Autentificare")</span> 643 <span 644 class="d-flex align-items-center justify-content-center icon-2">@ReadFile("Files/Images/Elbi/Icons/Account-icon.svg")</span> 645 </a> 646 <a type="button" href="@contactPageUrl" 647 class=" btn btn-outline-primary btn-primary-outline d-flex align-items-center text-center gap-2" 648 data-dw-button="outline-primary" 649 style="white-space: nowrap;max-height: 3.5ch" title="@Translate("Contacteaza-ne")"> 650 <span>@Translate("Contacteaza-ne")</span> 651 <span 652 class="d-flex align-items-center justify-content-center icon-2">@ReadFile("Files/Images/Elbi/Icons/PhoneIcon.svg")</span> 653 </a> 654 </div> 655 </div> 656 } 657 </div> 658 </div> 659 </div> 660 <div class="modal fade" id="@modalId" tabindex="-1" aria-labelledby="label_@modalId" 661 aria-hidden="true"> 662 <div class="modal-dialog modal-dialog-centered"> 663 <div class="modal-content"> 664 <div class="modal-header"> 665 <h5 class="modal-title" id="label_@modalId">@Translate("Back in stock")</h5> 666 <button type="button" class="btn-close" data-bs-dismiss="modal" 667 aria-label="@Translate("Close")"></button> 668 </div> 669 <div class="modal-body"> 670 <form name="@product.Id" id="@formId" method="post" action="@productPage"> 671 <input type="hidden" name="ProductID" value="@product.Id"/> 672 <input type="hidden" name="VariantID" value="@product.VariantId"/> 673 <input type="hidden" name="LanguageID" value="@product.LanguageId"/> 674 <input type="hidden" name="CartCmd" value="createnotificationforthisproduct"/> 675 <div class="m-2"> 676 @Translate("Send me an email when the product is in stock.") 677 </div> 678 <div class="form-floating m-2"> 679 <input class="form-control" type="text" id="NotificationEmail" 680 value="@(Pageview.User != null ? Pageview.User.Email : "")" 681 name="NotificationEmail" placeholder="@Translate("Email")" 682 required="required" aria-required="aria-required"/> 683 <label for="NotificationEmail" class="form-label">@Translate("Email")</label> 684 </div> 685 </form> 686 </div> 687 <div class="modal-footer"> 688 <button type="button" class="btn btn-primary" data-dw-button="primary" 689 onclick="@notificationOnClick">@Translate("Submit")</button> 690 </div> 691 </div> 692 </div> 693 </div> 694 <div class="modal fade" id="@modalId" tabindex="-1" aria-labelledby="label_@modalId" 695 aria-hidden="true"> 696 <div class="modal-dialog modal-dialog-centered"> 697 <div class="modal-content"> 698 <div class="modal-header"> 699 <h5 class="modal-title" id="label_@modalId">@Translate("Back in stock")</h5> 700 <button type="button" class="btn-close" data-bs-dismiss="modal" 701 aria-label="@Translate("Close")"></button> 702 </div> 703 <div class="modal-body"> 704 <form name="@product.Id" id="@formId" method="post" action="@productPage"> 705 <input type="hidden" name="ProductID" value="@product.Id"/> 706 <input type="hidden" name="VariantID" value="@product.VariantId"/> 707 <input type="hidden" name="LanguageID" value="@product.LanguageId"/> 708 <input type="hidden" name="CartCmd" value="createnotificationforthisproduct"/> 709 <div class="m-2"> 710 @Translate("Send me an email when the product is in stock.") 711 </div> 712 <div class="form-floating m-2"> 713 <input class="form-control" type="text" id="NotificationEmail" 714 value="@(Pageview.User != null ? Pageview.User.Email : "")" 715 name="NotificationEmail" placeholder="@Translate("Email")" 716 required="required" aria-required="aria-required"/> 717 <label for="NotificationEmail" class="form-label">@Translate("Email")</label> 718 </div> 719 </form> 720 </div> 721 <div class="modal-footer"> 722 <button type="button" class="btn btn-primary" data-dw-button="primary" 723 onclick="@notificationOnClick">@Translate("Submit")</button> 724 </div> 725 </div> 726 </div> 727 </div> 728 } 729 730 } 731
Descriere
Gama de protectii marca Spf este atent selectata si produsa pentru a oferi solutii inovative si fiabile pentru problemele dumneavoastra. Orice dificultate ati putea intalni, noi va stam la dispozitie cu produse variate si potrivite atat financiar, cat si calitativ. In acest sens, prezentam banda zincata din imagine cu o dimensiune de 25x4mm, lungimea colacului de 61 ml si greutatea de 0.80 kg/ml.

Specificații
Caracteristici generale
Dimensiune [mm]
25X4mm
Greutate rola [kg]
50Kg
Kg /m
0.8
Lungime rola [m]
61m
Material
Otel zincat