Tischlampe 1L orbit
Error executing template "Designs/Swift/Paragraph/CustomProductSlider.cshtml"
System.NullReferenceException: Object reference not set to an instance of an object.
   at CompiledRazorTemplates.Dynamic.RazorEngine_3562354021b44d5c892fe73dc2806e4f.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 Dynamicweb.Ecommerce.ProductCatalog 3 @using Dynamicweb.Ecommerce.CustomerExperienceCenter.Favorites 4 @using Dynamicweb.Files 5 @using System.IO 6 @using System.Net 7 @using Dynamicweb.Security.UserManagement 8 9 10 @{ 11 ProductViewModel product = null; 12 if (Dynamicweb.Context.Current.Items.Contains("ProductDetails")) 13 { 14 product = (ProductViewModel)Dynamicweb.Context.Current.Items["ProductDetails"]; 15 } 16 else if (Pageview.Page.Item["DummyProduct"] != null && Pageview.IsVisualEditorMode) 17 { 18 var pageViewModel = Dynamicweb.Frontend.ContentViewModelFactory.CreatePageInfoViewModel(Pageview.Page); 19 ProductListViewModel productList = pageViewModel.Item.GetValue("DummyProduct") != null ? pageViewModel.Item.GetValue("DummyProduct") as ProductListViewModel : new ProductListViewModel(); 20 21 if (productList?.Products is object) 22 { 23 product = productList.Products[0]; 24 } 25 } 26 } 27 28 @{ 29 var currentUser = Pageview?.User; 30 var customerNumber = !string.IsNullOrEmpty(currentUser?.CustomerNumber) 31 ? currentUser.CustomerNumber 32 : ""; 33 } 34 @if (product is object) 35 { 36 string imagePath = product?.DefaultImage?.Value ?? ""; 37 string imagePathUrlEncoded = Dynamicweb.Context.Current.Server.UrlEncode(imagePath); 38 39 string ratio = Model.Item.GetRawValueString("ImageAspectRatio", ""); 40 ratio = ratio != "0" ? ratio : ""; 41 string ratioCssClass = ratio != "" ? " ratio" : ""; 42 string ratioVariable = ratio != "" ? "--bs-aspect-ratio: " + ratio + ";" : ""; 43 44 string width = Model.Item.GetRawValueString("Width", "auto"); 45 int smallImageSize = 640; 46 int largeImageSize = width == "auto" ? 1280 : Convert.ToInt32(width); 47 48 string ImageObjectFit = Model.Item.GetRawValueString("ImageObjectFit", "contain"); 49 50 string imagePathXs = "/Admin/Public/GetImage.ashx?width=" + smallImageSize + "&image=" + imagePathUrlEncoded + "&format=webp"; 51 string imagePathS = "/Admin/Public/GetImage.ashx?width=" + largeImageSize + "&image=" + imagePathUrlEncoded + "&format=webp"; 52 string imagePathFallBack = "/Admin/Public/GetImage.ashx?width=" + largeImageSize + "&image=" + imagePathUrlEncoded + "&format=webp"; 53 54 var badgeParms = new Dictionary<string, object>(); 55 badgeParms.Add("size", "h7"); 56 badgeParms.Add("saleBadgeType", Model.Item.GetRawValue("SaleBadgeType")); 57 badgeParms.Add("saleBadgeCssClassName", Model.Item.GetRawValue("SaleBadgeDesign")); 58 badgeParms.Add("newBadgeCssClassName", Model.Item.GetRawValue("NewBadgeDesign")); 59 badgeParms.Add("newPublicationDays", Model.Item.GetInt32("NewPublicationDays")); 60 badgeParms.Add("campaignBadgesValues", Model.Item.GetList("CampaignBadges")?.GetRawValue().OfType<string>().ToList()); 61 62 string badgeSize = Model.Item.GetRawValueString("BadgeSize", "fs-2"); 63 bool saleBadgeEnabled = !string.IsNullOrWhiteSpace(Model.Item.GetRawValueString("SaleBadgeDesign")) && Model.Item.GetRawValueString("SaleBadgeDesign") != "none" ? true : false; 64 bool newBadgeEnabled = !string.IsNullOrWhiteSpace(Model.Item.GetRawValueString("NewBadgeDesign")) && Model.Item.GetRawValueString("NewBadgeDesign") != "none" ? true : false; 65 66 /*Custom badge*/ 67 var productService = new Dynamicweb.Ecommerce.Products.ProductService(); 68 var currency = Dynamicweb.Ecommerce.Common.Context.Currency.Code; 69 var formatProvider = new System.Globalization.NumberFormatInfo(); 70 formatProvider.NumberDecimalSeparator = "."; 71 formatProvider.NumberGroupSeparator = ","; 72 var MainVariant = productService.GetProductById(product.Id, product.VariantId, false); 73 var fieldValueBlocked = MainVariant?.ProductFieldValues?.GetProductFieldValue("BlockedCustomerList")?.Value; 74 75 76 string isNewProduct = MainVariant?.ProductFieldValues?.GetProductFieldValue("New")?.Value?.ToString().ToLower() ?? ""; 77 string MainisSale = MainVariant?.ProductFieldValues?.GetProductFieldValue("Sale")?.Value?.ToString().ToLower() ?? ""; 78 bool showNewBadge = isNewProduct == "true" ? true : false; 79 bool showSaleBadge = MainisSale == "true" ? true : false; 80 string showNewSaleBadge = "d-none"; 81 if (showSaleBadge) 82 { 83 badgeParms.Add("isSale", "true"); 84 85 } 86 else 87 { 88 badgeParms.Add("isSale", "false"); 89 } 90 if (showNewBadge) 91 { 92 badgeParms.Add("isNew", "true"); 93 } 94 else 95 { 96 badgeParms.Add("isNew", "false"); 97 } 98 /*End Custom badge*/ 99 if (showSaleBadge || showNewBadge) 100 { 101 showNewSaleBadge = ""; 102 } 103 DateTime createdDate = product.Created.Value; 104 bool showBadges = saleBadgeEnabled && product.Discount.Price != 0 ? true : false; 105 106 bool showFavoritesSelector = !string.IsNullOrEmpty(Model.Item.GetString("ShowAddToFavorites")) ? Model.Item.GetBoolean("ShowAddToFavorites") : false; 107 string anonymousUsersLimitations = Pageview.AreaSettings.GetRawValueString("AnonymousUsers", ""); 108 bool anonymousUser = Pageview.User == null; 109 110 var favoriteParameters = new Dictionary<string, object>(); 111 if (!anonymousUser && showFavoritesSelector) 112 { 113 int defaultFavoriteListId = 0; 114 115 IEnumerable<FavoriteList> favoreiteLists = Pageview.User.GetFavoriteLists(); 116 if (favoreiteLists.Count() == 1) 117 { 118 foreach (FavoriteList list in favoreiteLists) 119 { 120 defaultFavoriteListId = list.ListId; 121 } 122 } 123 124 favoriteParameters.Add("ListId", defaultFavoriteListId); 125 } 126 127 MediaViewModel alternativeImage = new MediaViewModel(); 128 if (Model.Item.GetBoolean("ShowAlternativeImageOnHover")) 129 { 130 var selectedImageCategories = Model.Item.GetList("GetAlternativeImageFrom")?.GetRawValue().OfType<string>().ToList(); 131 List<MediaViewModel> allAssetsImages = product.AssetCategories.Where(x => selectedImageCategories.Contains(x.SystemName)).SelectMany(x => x.Assets).ToList(); 132 allAssetsImages.RemoveAll(x => x.Value == product.DefaultImage.Value); 133 alternativeImage = allAssetsImages.FirstOrDefault(); 134 } 135 136 string altImagePathXs = string.Empty; 137 string altImagePathS = string.Empty; 138 139 if (!string.IsNullOrEmpty(alternativeImage?.Value)) 140 { 141 altImagePathXs = "/Admin/Public/GetImage.ashx?width=" + smallImageSize + "&image=" + Dynamicweb.Context.Current.Server.UrlEncode(alternativeImage.Value) + "&format=webp"; 142 altImagePathS = "/Admin/Public/GetImage.ashx?width=" + largeImageSize + "&image=" + Dynamicweb.Context.Current.Server.UrlEncode(alternativeImage.Value) + "&format=webp"; 143 } 144 145 @* Theme settings *@ 146 string theme = !string.IsNullOrWhiteSpace(Model.Item.GetRawValueString("Theme")) ? " theme " + Model.Item.GetRawValueString("Theme").Replace(" ", "").Trim().ToLower() : ""; 147 string themeBorder = !string.IsNullOrWhiteSpace(theme) ? "border: 1px solid rgba(0,0,0,0)" : ""; 148 string themePadding = !string.IsNullOrWhiteSpace(theme) ? "p-2 p-lg-3" : ""; 149 150 string imageId = "ProductImage_" + product.Id; 151 152 153 154 string fullWidth = width == "auto" ? "w-100" : ""; 155 string customWidth = width != "auto" ? "style=\"width: " + width + "px\"" : "style=\"min-width: 60px\""; 156 157 string altImageZindex = Model.Item.GetBoolean("ShowAlternativeImageOnHover") && !string.IsNullOrEmpty(alternativeImage?.Value) ? " z-index: 1" : string.Empty; 158 string groupid = !string.IsNullOrEmpty(Dynamicweb.Context.Current.Request.QueryString.Get("GroupID")) ? Dynamicweb.Context.Current.Request.QueryString.Get("GroupID"):"" ; 159 string link = product.GetProductLink(GetPageIdByNavigationTag("Shop"), false); 160 var productVariantGroups = product.VariantGroups(); 161 string MainOutStock = "<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"25\" height=\"25\" fill=\"#CA0D0D\" class=\"bi bi-x-lg\" viewBox=\"0 0 16 16\"><path d=\"M4.646 4.646a.5.5 0 0 1 .708 0L8 7.293l2.646-2.647a.5.5 0 0 1 .708.708L8.707 8l2.647 2.646a.5.5 0 0 1-.708.708L8 8.707l-2.646 2.647a.5.5 0 0 1-.708-.708L7.293 8 4.646 5.354a.5.5 0 0 1 0-.708\"/></svg>"; 162 163 @if (!string.IsNullOrEmpty(imagePath)) 164 { 165 <div class="@fullWidth @theme position-relative item_@Model.Item.SystemName.ToLower() main-image-container" @customWidth> 166 <div class="" style="@(ratioVariable)@(altImageZindex)"> 167 <div class="d-flex justify-content-center align-items-center"> 168 <a class="main-link-link" href="@link"> 169 @if (imagePath.StartsWith("/Files/", StringComparison.OrdinalIgnoreCase)) 170 { 171 <img id="@imageId" 172 srcset=" 173 @imagePathXs @(smallImageSize)w, 174 @imagePathS @(largeImageSize)w" 175 sizes="(max-width: 992px) 50vw, 25vw" 176 src="@imagePathFallBack" 177 loading="lazy" 178 decoding="async" 179 class="h-100 w-100 @themePadding main-image" 180 style="object-fit: @ImageObjectFit; @themeBorder " 181 alt="@product.Name" 182 itemprop="image"> 183 } 184 else 185 { 186 <img src="@product.DefaultImage.Value" 187 loading="lazy" 188 class="h-100 w-100 @themePadding main-image" 189 style="object-fit: contain; @themeBorder" 190 alt="@product.Name" 191 itemprop="image"> 192 } 193 </a> 194 </div> 195 </div> 196 197 <div class="position-absolute top-0 left-0 p-2 pb-0 custom-badge-product-list @showNewSaleBadge"> 198 @{ 199 @RenderPartial("Components/Custom_EcommerceBadge.cshtml", product, badgeParms) 200 } 201 </div> 202 203 204 </div> 205 } 206 207 <div class="product-info h-100"> 208 <div class="fs-7 pt-1 opacity-85 start item_@Model.Item.SystemName.ToLower() product-number" itemprop="sku">@product.Id / @product.VariantId - @product.VariantName</div> 209 <div class="py-2" data-col-size="12"> 210 <h2 class="h6 start m-0 item_swift_productheader product-name" itemprop="name"><b>@product.Name</b></h2> 211 </div> 212 </div> 213 var sliderId = $"thumb-scroll-{product.Id}"; 214 if (productVariantGroups.Any() && product?.VariantInfo?.VariantInfo != null) 215 216 { 217 @using Dynamicweb.Ecommerce.Prices 218 @{ 219 string[] variantId = product.VariantId.Split('.'); 220 string showPricesWithVat = Pageview.Area.EcomPricesWithVat.ToLower(); 221 bool neverShowVat = string.IsNullOrEmpty(showPricesWithVat); 222 bool showInformativePrice = Model.Item.GetBoolean("ShowInformativePrice"); 223 string productInfoFeed = ""; 224 bool isLazyLoadingForProductInfoEnabled = Dynamicweb.Core.Converter.ToBoolean(Dynamicweb.Context.Current.Items["IsLazyLoadingForProductInfoEnabled"]); 225 if (isLazyLoadingForProductInfoEnabled) 226 { 227 if (Dynamicweb.Context.Current.Items.Contains("ProductInfoFeed")) 228 { 229 productInfoFeed = Dynamicweb.Context.Current.Items["ProductInfoFeed"]?.ToString(); 230 if (!string.IsNullOrEmpty(productInfoFeed)) 231 { 232 productInfoFeed =productInfoFeed; 233 } 234 } 235 236 } 237 string priceMin = ""; 238 string priceMax = ""; 239 int groupNumber = 1; 240 241 242 243 244 string baseUrl = $"Default.aspx?ID={GetPageIdByNavigationTag("Shop")}&GroupID={product.PrimaryOrDefaultGroup.Id}&ProductID={product.Id}"; 245 if (!string.IsNullOrEmpty(baseUrl)) 246 { 247 baseUrl = $"/{baseUrl.TrimStart('/')}"; 248 } 249 string variantUrl = string.Empty; 250 251 252 Dictionary<string, string> 253 variantImages = new Dictionary<string, string> 254 (); 255 <div class="last-row mt-auto"> 256 257 @foreach (var variantGroup in productVariantGroups) 258 { 259 <div class="thumbnail-wrapper"> 260 <button class="thumb-nav prev" onclick="scrollThumbs('@sliderId', -1)"> 261 <svg width="20px" height="20px" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" fill="#1D98A5"> 262 263 <g stroke="none" stroke-width="1" fill="none" fill-rule="evenodd"> 264 <g transform="translate(-336.000000, 0.000000)"> 265 <g id="left_line" transform="translate(336.000000, 0.000000)"> 266 <path d="M24,0 L24,24 L0,24 L0,0 L24,0 Z M12.5934901,23.257841 L12.5819402,23.2595131 L12.5108777,23.2950439 L12.4918791,23.2987469 L12.4918791,23.2987469 L12.4767152,23.2950439 L12.4056548,23.2595131 C12.3958229,23.2563662 12.3870493,23.2590235 12.3821421,23.2649074 L12.3780323,23.275831 L12.360941,23.7031097 L12.3658947,23.7234994 L12.3769048,23.7357139 L12.4804777,23.8096931 L12.4953491,23.8136134 L12.4953491,23.8136134 L12.5071152,23.8096931 L12.6106902,23.7357139 L12.6232938,23.7196733 L12.6232938,23.7196733 L12.6266527,23.7031097 L12.609561,23.275831 C12.6075724,23.2657013 12.6010112,23.2592993 12.5934901,23.257841 L12.5934901,23.257841 Z M12.8583906,23.1452862 L12.8445485,23.1473072 L12.6598443,23.2396597 L12.6498822,23.2499052 L12.6498822,23.2499052 L12.6471943,23.2611114 L12.6650943,23.6906389 L12.6699349,23.7034178 L12.6699349,23.7034178 L12.678386,23.7104931 L12.8793402,23.8032389 C12.8914285,23.8068999 12.9022333,23.8029875 12.9078286,23.7952264 L12.9118235,23.7811639 L12.8776777,23.1665331 C12.8752882,23.1545897 12.8674102,23.1470016 12.8583906,23.1452862 L12.8583906,23.1452862 Z M12.1430473,23.1473072 C12.1332178,23.1423925 12.1221763,23.1452606 12.1156365,23.1525954 L12.1099173,23.1665331 L12.0757714,23.7811639 C12.0751323,23.7926639 12.0828099,23.8018602 12.0926481,23.8045676 L12.108256,23.8032389 L12.3092106,23.7104931 L12.3186497,23.7024347 L12.3186497,23.7024347 L12.3225043,23.6906389 L12.340401,23.2611114 L12.337245,23.2485176 L12.337245,23.2485176 L12.3277531,23.2396597 L12.1430473,23.1473072 Z" id="MingCute" fill-rule="nonzero"> </path> 267 <path d="M8.29292,12.7071 C7.9024,12.3166 7.9024,11.6834 8.29292,11.2929 L13.9498,5.63604 C14.3403,5.24551 14.9735,5.24551 15.364,5.63604 C15.7545,6.02656 15.7545,6.65973 15.364,7.05025 L10.4142,12 L15.364,16.9497 C15.7545,17.3403 15.7545,17.9734 15.364,18.364 C14.9735,18.7545 14.3403,18.7545 13.9498,18.364 L8.29292,12.7071 Z" id="路径" fill="#1D98A5"> </path> 268 </g> 269 </g> 270 </g> 271 </svg> 272 273 </button> 274 <div class="thumbnail-scroll" id="@sliderId"> 275 @{ 276 VariantGroupViewModel group = variantGroup; 277 foreach (var option in group.Options.OrderBy(o => o.Id)) 278 { 279 var productVariant = productService.GetProductById(product.Id, option.Id, false); 280 281 var productSelection = new PriceProductSelection(productVariant, null, 0); 282 283 var currencyCode = string.IsNullOrWhiteSpace(Pageview.User.Currency) ? Pageview.Area.EcomCurrencyId : Pageview.User.Currency; 284 var countryCode = string.IsNullOrWhiteSpace(Pageview.User.CountryCode) ? Pageview.Area.EcomCountryCode : Pageview.User.CountryCode; 285 286 var userCurrency = Dynamicweb.Ecommerce.Services.Currencies.GetCurrency(currencyCode); 287 var userCountry = Dynamicweb.Ecommerce.Services.Countries.GetCountry(countryCode); 288 289 var priceContext = new PriceContext(userCurrency, userCountry, null, Pageview.User, false, null); 290 var productPrice = Dynamicweb.Ecommerce.Services.Prices.FindPrices(priceContext, productSelection, false); 291 292 //throw new Exception(System.Text.Json.JsonSerializer.Serialize(productPrice)); 293 294 var fieldValue = productVariant?.ProductFieldValues?.GetProductFieldValue("BlockedCustomerList")?.Value; 295 296 if ((fieldValue != null && !fieldValue.ToString().Contains(customerNumber)) || String.IsNullOrWhiteSpace(customerNumber)) 297 { 298 299 300 string active = variantId != null && variantId.Contains(option.Id) ? "active" : string.Empty; 301 string buttonId = $"{product.Id}_{option.Id}_{Pageview.CurrentParagraph.ID}"; 302 string contrastColor = string.Empty; 303 304 string searchKey = $"{product.Id}_{option.Id}_"; 305 /*Images*/ 306 var imagePathVariant = option.Image?.Value ?? ""; 307 308 309 var folderPath = Path.GetDirectoryName(imagePathVariant); 310 311 string physicalFolderPath = Dynamicweb.Context.Current.Server.MapPath(folderPath); 312 313 string lastImage = null; 314 315 if (Directory.Exists(physicalFolderPath)) 316 { 317 318 var fileWith15 = Directory.GetFiles(physicalFolderPath) 319 .FirstOrDefault(f => Path.GetFileName(f).Contains($"{product.Id}_{option.Id}_9")); 320 321 if (fileWith15 != null) 322 { 323 lastImage = fileWith15; 324 } 325 else 326 { 327 var files = Directory.GetFiles(physicalFolderPath) 328 .Where(f => Path.GetFileName(f).StartsWith($"{product.Id}_{option.Id}_")) 329 .OrderByDescending(f => 330 { 331 var filename = Path.GetFileNameWithoutExtension(f); 332 var match = System.Text.RegularExpressions.Regex.Match(filename, @"_(\d+)$"); 333 if (match.Success && int.TryParse(match.Groups[1].Value, out int index)) 334 { 335 return index; 336 } 337 return 0; 338 }) 339 .ToList(); 340 341 if (files.Any()) 342 { 343 lastImage = files.First(); 344 } 345 } 346 } 347 348 var lastImageUrl = lastImage != null ? lastImage : "/Files/Images/zijlstra/Afbeeldingen_overig/Coming_Soon.jpg"; 349 int index = lastImageUrl.IndexOf("Files"); 350 string relativePath = index >= 0 ? lastImageUrl.Substring(index).Replace("\\", "/") : lastImageUrl.Replace("\\", "/"); 351 lastImageUrl = "/" + relativePath; 352 lastImageUrl = Dynamicweb.Context.Current.Server.UrlEncode(lastImageUrl); 353 var variantImg = option.Image is object ? Dynamicweb.Context.Current.Server.UrlEncode(option.Image.Value) : null; 354 var variantLink = "/Default.aspx?ID=" + GetPageIdByNavigationTag("Shop") + "&GroupID=" + product.PrimaryOrDefaultGroup.Id + "&ProductID=" + product.Id + "&VariantID=" + option.Id; 355 356 string variantImage = string.Empty; 357 variantImages.TryGetValue(option.Id, out variantImage); 358 /*End Images*/ 359 360 /*stock state*/ 361 double variantStock = productVariant.Stock; 362 string svgInStock = "<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"16\" height=\"16\" fill=\"#44B11A\" class=\"bi bi-check-lg\" viewBox=\"0 0 16 16\"><path d=\"M12.736 3.97a.733.733 0 0 1 1.047 0c.286.289.29.756.01 1.05L7.88 12.01a.733.733 0 0 1-1.065.02L3.217 8.384a.757.757 0 0 1 0-1.06.733.733 0 0 1 1.047 0l3.052 3.093 5.4-6.425z\"/></svg>"; 363 string svgOutStock = "<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"25\" height=\"25\" fill=\"#CA0D0D\" class=\"bi bi-x-lg\" viewBox=\"0 0 16 16\"><path d=\"M4.646 4.646a.5.5 0 0 1 .708 0L8 7.293l2.646-2.647a.5.5 0 0 1 .708.708L8.707 8l2.647 2.646a.5.5 0 0 1-.708.708L8 8.707l-2.646 2.647a.5.5 0 0 1-.708-.708L7.293 8 4.646 5.354a.5.5 0 0 1 0-.708\"/></svg>"; 364 365 string infoStock = "<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"16\" height=\"16\" fill=\"currentColor\" class=\"bi bi-info-circle-fill\" viewBox=\"0 0 16 16\"><path d=\"M8 16A8 8 0 1 0 8 0a8 8 0 0 0 0 16m.93-9.412-1 4.705c-.07.34.029.533.304.533.194 0 .487-.07.686-.246l-.088.416c-.287.346-.92.598-1.465.598-.703 0-1.002-.422-.808-1.319l.738-3.468c.064-.293.006-.399-.287-.47l-.451-.081.082-.381 2.29-.287zM8 5.5a1 1 0 1 1 0-2 1 1 0 0 1 0 2\" /></svg>"; 366 string isNew = productVariant?.ProductFieldValues?.GetProductFieldValue("New")?.Value?.ToString().ToLower() ?? ""; 367 string isNewSvg = "<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"16\" height=\"16\" fill=\"#F2C400\" class=\"bi bi-star-fill\" viewBox=\"0 0 16 16\"><path d = \"M3.612 15.443c-.386.198-.824-.149-.746-.592l.83-4.73L.173 6.765c-.329-.314-.158-.888.283-.95l4.898-.696L7.538.792c.197-.39.73-.39.927 0l2.184 4.327 4.898.696c.441.062.612.636.282.95l-3.522 3.356.83 4.73c.078.443-.36.79-.746.592L8 13.187l-4.389 2.256z\" /></svg> "; 368 string stockState = ""; 369 370 string isSale = productVariant?.ProductFieldValues?.GetProductFieldValue("Sale")?.Value?.ToString().ToLower() ?? ""; 371 string isSaleSvg = "<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"16\" height=\"16\" fill=\"#F03232\" class=\"bi bi-star-fill\" viewBox=\"0 0 16 16\"><path d = \"M3.612 15.443c-.386.198-.824-.149-.746-.592l.83-4.73L.173 6.765c-.329-.314-.158-.888.283-.95l4.898-.696L7.538.792c.197-.39.73-.39.927 0l2.184 4.327 4.898.696c.441.062.612.636.282.95l-3.522 3.356.83 4.73c.078.443-.36.79-.746.592L8 13.187l-4.389 2.256z\" /></svg> "; 372 373 string expectedDeliveryDate = ""; 374 375 if (DateTime.Compare(productVariant.ExpectedDelivery, new DateTime(1900, 1, 1)) != 0) //In DW, if the Date is not set, it is defaulted 01-01-1900 and not null.. 376 { 377 expectedDeliveryDate = productVariant.ExpectedDelivery.ToShortDateString(); 378 } 379 380 string expectedDeliveryDateText = !String.IsNullOrWhiteSpace(expectedDeliveryDate) ? Translate("Verwacht:") + "&nbsp;" + expectedDeliveryDate : ""; 381 382 @if (!(bool?)productVariant.ProductFieldValues.Where(o => o.ProductField.SystemName == "ProductToBeDiscontinued").SingleOrDefault()?.Value ?? false) 383 { 384 if (variantStock > 0) 385 { 386 if (isNew == "true" || isSale == "true") 387 { 388 if (isSale == "true") 389 { 390 stockState += isSaleSvg + "&nbsp; &nbsp;" + Translate("Sale!") + "<br/>"; 391 } 392 393 if (isNew == "true") 394 { 395 stockState += isNewSvg + "&nbsp; &nbsp;" + Translate("New!") + "<br/>"; 396 } 397 398 stockState += "&nbsp;" + Translate("Nu leverbaar"); 399 } 400 else 401 { 402 stockState = svgInStock + "&nbsp; " + Translate("Op voorraad"); 403 404 } 405 } 406 else 407 { 408 stockState = svgOutStock + "&nbsp;" + Translate("Geen voorraad") + "<br/>" + expectedDeliveryDateText; 409 410 } 411 } 412 else 413 { 414 415 stockState = svgOutStock + "&nbsp;" + Translate("Discontinued:") + "<br/>" + variantStock + "&nbsp;" + @Translate("left in stock"); 416 417 } 418 /*End stock state*/ 419 /*Price variants*/ 420 double price = productVariant.DefaultPrice; 421 double cost = productVariant.Cost; 422 423 string priceFormated = Dynamicweb.Ecommerce.Services.Currencies.Format(Dynamicweb.Ecommerce.Services.Currencies.GetCurrency(currency), Convert.ToDouble(productPrice.ToList()[0].Amount, formatProvider)); 424 //string priceFormated = Dynamicweb.Ecommerce.Services.Currencies.Format(Dynamicweb.Ecommerce.Services.Currencies.GetCurrency(currency), Convert.ToDouble(price, formatProvider)); 425 426 427 428 /*End Price variants*/ 429 430 <img class="theme thumbnail" data-stockstate="@WebUtility.HtmlEncode(stockState)" src="/Admin/Public/GetImage.ashx?image=@(lastImageUrl)&width=64&format=webp" onclick="selectVariant('@(product.Id)','/Admin/Public/GetImage.ashx?image=@(variantImg)&format=webp','@variantLink','@product.Id','@option.Id','@option.Name',this.dataset.stockstate,'@isNew','@isSale','@priceFormated','@cost')" /> 431 432 433 } 434 } 435 436 } 437 </div> 438 <button class="thumb-nav next" onclick="scrollThumbs('@sliderId', 1)"> 439 <svg width="20px" height="20px" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" fill="#1D98A5"> 440 441 <g stroke="none" stroke-width="1" fill="none" fill-rule="evenodd"> 442 <g transform="translate(-384.000000, 0.000000)"> 443 <g id="right_line" transform="translate(384.000000, 0.000000)"> 444 <path d="M24,0 L24,24 L0,24 L0,0 L24,0 Z M12.5934901,23.257841 L12.5819402,23.2595131 L12.5108777,23.2950439 L12.4918791,23.2987469 L12.4918791,23.2987469 L12.4767152,23.2950439 L12.4056548,23.2595131 C12.3958229,23.2563662 12.3870493,23.2590235 12.3821421,23.2649074 L12.3780323,23.275831 L12.360941,23.7031097 L12.3658947,23.7234994 L12.3769048,23.7357139 L12.4804777,23.8096931 L12.4953491,23.8136134 L12.4953491,23.8136134 L12.5071152,23.8096931 L12.6106902,23.7357139 L12.6232938,23.7196733 L12.6232938,23.7196733 L12.6266527,23.7031097 L12.609561,23.275831 C12.6075724,23.2657013 12.6010112,23.2592993 12.5934901,23.257841 L12.5934901,23.257841 Z M12.8583906,23.1452862 L12.8445485,23.1473072 L12.6598443,23.2396597 L12.6498822,23.2499052 L12.6498822,23.2499052 L12.6471943,23.2611114 L12.6650943,23.6906389 L12.6699349,23.7034178 L12.6699349,23.7034178 L12.678386,23.7104931 L12.8793402,23.8032389 C12.8914285,23.8068999 12.9022333,23.8029875 12.9078286,23.7952264 L12.9118235,23.7811639 L12.8776777,23.1665331 C12.8752882,23.1545897 12.8674102,23.1470016 12.8583906,23.1452862 L12.8583906,23.1452862 Z M12.1430473,23.1473072 C12.1332178,23.1423925 12.1221763,23.1452606 12.1156365,23.1525954 L12.1099173,23.1665331 L12.0757714,23.7811639 C12.0751323,23.7926639 12.0828099,23.8018602 12.0926481,23.8045676 L12.108256,23.8032389 L12.3092106,23.7104931 L12.3186497,23.7024347 L12.3186497,23.7024347 L12.3225043,23.6906389 L12.340401,23.2611114 L12.337245,23.2485176 L12.337245,23.2485176 L12.3277531,23.2396597 L12.1430473,23.1473072 Z" id="MingCute" fill-rule="nonzero"> </path> 445 <path d="M15.7072,11.2929 C16.0977,11.6834 16.0977,12.3166 15.7072,12.7071 L10.0503,18.364 C9.65982,18.7545 9.02666,18.7545 8.63613,18.364 C8.24561,17.9734 8.24561,17.3403 8.63613,16.9497 L13.5859,12 L8.63613,7.05025 C8.24561,6.65973 8.24561,6.02656 8.63613,5.63604 C9.02666,5.24551 9.65982,5.24551 10.0503,5.63604 L15.7072,11.2929 Z" id="路径" fill="#1D98A5"> </path> 446 </g> 447 </g> 448 449 </svg> 450 451 </button> 452 </div> 453 } 454 455 456 </div> 457 458 } 459 if ((fieldValueBlocked != null && !fieldValueBlocked.ToString().Contains(customerNumber)) || String.IsNullOrWhiteSpace(customerNumber)) 460 { 461 <div class="stock-state pt-2 mt-auto"> 462 @{ 463 464 /*stock state*/ 465 double MainvariantStock = MainVariant.Stock; 466 string MainsvgInStock = "<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"16\" height=\"16\" fill=\"#44B11A\" class=\"bi bi-check-lg\" viewBox=\"0 0 16 16\"><path d=\"M12.736 3.97a.733.733 0 0 1 1.047 0c.286.289.29.756.01 1.05L7.88 12.01a.733.733 0 0 1-1.065.02L3.217 8.384a.757.757 0 0 1 0-1.06.733.733 0 0 1 1.047 0l3.052 3.093 5.4-6.425z\"/></svg>"; 467 string MainsvgOutStock = "<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"25\" height=\"25\" fill=\"#CA0D0D\" class=\"bi bi-x-lg\" viewBox=\"0 0 16 16\"><path d=\"M4.646 4.646a.5.5 0 0 1 .708 0L8 7.293l2.646-2.647a.5.5 0 0 1 .708.708L8.707 8l2.647 2.646a.5.5 0 0 1-.708.708L8 8.707l-2.646 2.647a.5.5 0 0 1-.708-.708L7.293 8 4.646 5.354a.5.5 0 0 1 0-.708\"/></svg>"; 468 469 string MaininfoStock = "<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"16\" height=\"16\" fill=\"currentColor\" class=\"bi bi-info-circle-fill\" viewBox=\"0 0 16 16\"><path d=\"M8 16A8 8 0 1 0 8 0a8 8 0 0 0 0 16m.93-9.412-1 4.705c-.07.34.029.533.304.533.194 0 .487-.07.686-.246l-.088.416c-.287.346-.92.598-1.465.598-.703 0-1.002-.422-.808-1.319l.738-3.468c.064-.293.006-.399-.287-.47l-.451-.081.082-.381 2.29-.287zM8 5.5a1 1 0 1 1 0-2 1 1 0 0 1 0 2\" /></svg>"; 470 string MainisNew = MainVariant?.ProductFieldValues?.GetProductFieldValue("New")?.Value?.ToString().ToLower() ?? ""; 471 string MainisNewSvg = "<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"16\" height=\"16\" fill=\"#F2C400\" class=\"bi bi-star-fill\" viewBox=\"0 0 16 16\"><path d = \"M3.612 15.443c-.386.198-.824-.149-.746-.592l.83-4.73L.173 6.765c-.329-.314-.158-.888.283-.95l4.898-.696L7.538.792c.197-.39.73-.39.927 0l2.184 4.327 4.898.696c.441.062.612.636.282.95l-3.522 3.356.83 4.73c.078.443-.36.79-.746.592L8 13.187l-4.389 2.256z\" /></svg> "; 472 string MainstockState = ""; 473 string MainIsSale = MainVariant?.ProductFieldValues?.GetProductFieldValue("Sale")?.Value?.ToString().ToLower() ?? ""; 474 string MainIsSaleSvg = "<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"16\" height=\"16\" fill=\"#F03232\" class=\"bi bi-star-fill\" viewBox=\"0 0 16 16\"><path d = \"M3.612 15.443c-.386.198-.824-.149-.746-.592l.83-4.73L.173 6.765c-.329-.314-.158-.888.283-.95l4.898-.696L7.538.792c.197-.39.73-.39.927 0l2.184 4.327 4.898.696c.441.062.612.636.282.95l-3.522 3.356.83 4.73c.078.443-.36.79-.746.592L8 13.187l-4.389 2.256z\" /></svg> "; 475 string MainexpectedDeliveryDate = ""; 476 477 if (DateTime.Compare(MainVariant.ExpectedDelivery, new DateTime(1900, 1, 1)) != 0) //In DW, if the Date is not set, it is defaulted 01-01-1900 and not null.. 478 { 479 MainexpectedDeliveryDate = MainVariant.ExpectedDelivery.ToShortDateString(); 480 } 481 482 string MainexpectedDeliveryDateText = !String.IsNullOrWhiteSpace(MainexpectedDeliveryDate) ? Translate("Verwacht:") + "&nbsp;" + MainexpectedDeliveryDate : ""; 483 484 @if (!(bool?)MainVariant.ProductFieldValues.Where(o => o.ProductField.SystemName == "ProductToBeDiscontinued").SingleOrDefault()?.Value ?? false) 485 { 486 if (MainvariantStock > 0) 487 { 488 if (MainisNew == "true" || MainIsSale == "true") 489 { 490 if (MainIsSale == "true") 491 { 492 MainstockState += MainIsSaleSvg + "&nbsp; &nbsp;" + Translate("Sale!") + "<br/>"; 493 } 494 495 if (MainisNew == "true") 496 { 497 MainstockState += MainisNewSvg + "&nbsp; &nbsp;" + Translate("New!") + "<br/>"; 498 } 499 500 MainstockState += "&nbsp;" + Translate("Nu leverbaar"); 501 } 502 else 503 { 504 MainstockState = MainsvgInStock + "&nbsp; " + Translate("Op voorraad"); 505 506 } 507 } 508 else 509 { 510 MainstockState = MainsvgOutStock + "&nbsp;" + Translate("Geen voorraad") + "<br/>" + MainexpectedDeliveryDateText; 511 512 } 513 } 514 else 515 { 516 517 MainstockState = MainsvgOutStock + "&nbsp;" + Translate("Discontinued:") + "<br/>" + MainvariantStock + "&nbsp;" + @Translate("left in stock"); 518 519 } 520 /*End stock state*/ 521 522 523 @MainstockState 524 525 526 } 527 </div> 528 } 529 else 530 { 531 <div class="stock-state pt-2 mt-auto"> 532 @MainOutStock @Translate("Discontinued") 533 </div> 534 } 535 <div class="custom-price mt-auto"> 536 @{ 537 538 539 540 541 bool isErpConnectionDown = !Dynamicweb.Core.Converter.ToBoolean(Dynamicweb.Context.Current.Items["IsWebServiceConnectionAvailable"]); 542 bool hidePrice = anonymousUsersLimitations.Contains("price") && anonymousUser || Pageview.AreaSettings.GetBoolean("ErpDownHidePrices") && isErpConnectionDown; 543 544 bool productIsDiscontinued = product is object && product.Discontinued; 545 bool doNotShowPriceIfProductIsDiscontinued = Model.Item.GetBoolean("DoNotShowPriceIfProductIsDiscontinued"); 546 var isDiscontinued = productIsDiscontinued && doNotShowPriceIfProductIsDiscontinued; 547 } 548 549 @if (product is object && !hidePrice && !isDiscontinued) 550 { 551 string unitId = !string.IsNullOrEmpty(Dynamicweb.Context.Current.Request.Form.Get("UnitId")) ? Dynamicweb.Context.Current.Request.Form.Get("UnitId") : string.Empty; 552 553 string priceFontSize = Model.Item.GetRawValueString("PriceSize", "fs-4"); 554 string horizontalAlign = Model.Item.GetRawValueString("HorizontalAlignment", ""); 555 string layout = Model.Item.GetRawValueString("Layout", "horizontal"); 556 string textAlign = horizontalAlign == "center" ? "text-center" : string.Empty; 557 textAlign = horizontalAlign == "end" ? "text-end" : textAlign; 558 559 horizontalAlign = horizontalAlign == "center" && layout == "horizontal" ? "justify-content-center" : horizontalAlign; 560 horizontalAlign = horizontalAlign == "end" && layout == "horizontal" ? "justify-content-end" : horizontalAlign; 561 horizontalAlign = horizontalAlign == "center" && layout == "vertical" ? "align-items-center" : horizontalAlign; 562 horizontalAlign = horizontalAlign == "end" && layout == "vertical" ? "align-items-end" : horizontalAlign; 563 564 string flexDirection = layout == "horizontal" ? string.Empty : "flex-column"; 565 string flexGap = layout == "horizontal" ? "gap-3" : string.Empty; 566 string order = layout == "horizontal" ? string.Empty : "order-2"; 567 568 569 string contentPadding = Model.Item.GetRawValueString("ContentPadding", ""); 570 contentPadding = contentPadding == "none" ? "p-0" : contentPadding; 571 contentPadding = contentPadding == "small" ? "p-1 px-md-2 py-md-1" : contentPadding; 572 contentPadding = contentPadding == "large" ? "p-2 px-md-3 py-md-2" : contentPadding; 573 string liveInfoClass = ""; 574 575 576 577 578 579 580 if (isLazyLoadingForProductInfoEnabled) 581 { 582 if (Dynamicweb.Context.Current.Items.Contains("ProductInfoFeed")) 583 { 584 productInfoFeed = Dynamicweb.Context.Current.Items["ProductInfoFeed"]?.ToString(); 585 if (!string.IsNullOrEmpty(productInfoFeed)) 586 { 587 productInfoFeed = $"data-product-info-feed=\"{productInfoFeed}\""; 588 } 589 } 590 liveInfoClass = "js-live-info"; 591 } 592 593 <div class="@textAlign @liveInfoClass item_@Model.Item.SystemName.ToLower()" data-product-id="@product.Id" data-variant-id="@product.VariantId" @productInfoFeed> 594 @if (showInformativePrice && product.PriceInformative.Price != 0) 595 { 596 <div class="opacity-50"> 597 <span>@Translate("RRP") </span> 598 <span class="text-decoration-line-through text-price">@product.PriceInformative.PriceFormatted</span> 599 </div> 600 } 601 <div class="@priceFontSize m-0 d-flex flex-wrap @flexDirection @flexGap @horizontalAlign" style="row-gap: 0 !important" itemprop="offers" itemscope itemtype="https://schema.org/Offer"> 602 <span itemprop="priceCurrency" content="@product.Price.CurrencyCode" class="d-none"></span> 603 604 605 @if (showPricesWithVat == "false" && !neverShowVat) 606 { 607 if (isLazyLoadingForProductInfoEnabled && !Pageview.IsVisualEditorMode) 608 { 609 <span itemprop="price" content="" class="d-none"></span> 610 <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> 611 } 612 else 613 { 614 string beforePrice = !string.IsNullOrEmpty(unitId) ? product.GetPrice(unitId).PriceBeforeDiscount.PriceWithoutVatFormatted : product.PriceBeforeDiscount.PriceWithoutVatFormatted; 615 616 <span itemprop="price" content="@product.Price.PriceWithoutVat.ToString("0.00", System.Globalization.CultureInfo.InvariantCulture)" class="d-none"></span> 617 if (product.Price.Price != product.PriceBeforeDiscount.Price) 618 { 619 <span class="text-decoration-line-through opacity-75 @order">@beforePrice</span> 620 } 621 } 622 } 623 else 624 { 625 if (isLazyLoadingForProductInfoEnabled && !Pageview.IsVisualEditorMode) 626 { 627 <span itemprop="price" content="" class="d-none"></span> 628 <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> 629 } 630 else 631 { 632 string beforePrice = !string.IsNullOrEmpty(unitId) ? product.GetPrice(unitId).PriceBeforeDiscount.PriceFormatted : product.PriceBeforeDiscount.PriceFormatted; 633 634 <span itemprop="price" content="@product.Price.Price.ToString("0.00", System.Globalization.CultureInfo.InvariantCulture)" class="d-none"></span> 635 636 if (product.Price.Price != product.PriceBeforeDiscount.Price) 637 { 638 <span class="text-decoration-line-through opacity-75 @order"> 639 <span class="text-price">@beforePrice</span> 640 </span> 641 } 642 } 643 } 644 645 @if (showPricesWithVat == "false" && !neverShowVat) 646 { 647 if (isLazyLoadingForProductInfoEnabled && !Pageview.IsVisualEditorMode) 648 { 649 <span class="text-price js-text-price"> 650 <span class="spinner-border" role="status"></span> 651 </span> 652 } 653 else 654 { 655 string price = !string.IsNullOrEmpty(unitId) ? product.GetPrice(unitId).Price.PriceWithoutVatFormatted : product.Price.PriceWithoutVatFormatted; 656 657 if (product?.VariantInfo?.VariantInfo != null) 658 { 659 priceMin = product?.VariantInfo?.PriceMin?.PriceWithoutVatFormatted != null ? product.VariantInfo.PriceMin.PriceWithoutVatFormatted : ""; 660 priceMax = product?.VariantInfo?.PriceMax?.PriceWithoutVatFormatted != null ? product.VariantInfo.PriceMax.PriceWithoutVatFormatted : ""; 661 } 662 if (priceMin != priceMax) 663 { 664 price = priceMin + " - " + priceMax; 665 } 666 <span class="@theme @contentPadding"> 667 <span class="text-price">@price</span> 668 </span> 669 } 670 } 671 else 672 { 673 if (isLazyLoadingForProductInfoEnabled && !Pageview.IsVisualEditorMode) 674 { 675 <span class="text-price js-text-price"> 676 <span class="spinner-border" role="status"></span> 677 </span> 678 } 679 else 680 { 681 string price = !string.IsNullOrEmpty(unitId) ? product.GetPrice(unitId).Price.PriceFormatted : product.Price.PriceFormatted; 682 683 if (product?.VariantInfo?.VariantInfo != null) 684 { 685 priceMin = product?.VariantInfo?.PriceMin?.PriceFormatted != null ? product.VariantInfo.PriceMin.PriceFormatted : ""; 686 priceMax = product?.VariantInfo?.PriceMax?.PriceFormatted != null ? product.VariantInfo.PriceMax.PriceFormatted : ""; 687 } 688 if (priceMin != priceMax) 689 { 690 price = priceMin + " - " + priceMax; 691 } 692 <span class="@theme @contentPadding"> 693 <span class="text-price">@price</span> 694 </span> 695 } 696 } 697 698 @* Stock state for Schema.org, start *@ 699 @{ 700 Uri url = Dynamicweb.Context.Current.Request.Url; 701 } 702 703 <link itemprop="url" href="@url"> 704 705 @{ 706 bool IsNeverOutOfStock = product.NeverOutOfstock; 707 } 708 709 @if (IsNeverOutOfStock) 710 { 711 <span itemprop="availability" class="d-none">@Translate("Available in stock")</span> 712 } 713 else 714 { 715 if (product.StockLevel > 0) 716 { 717 <span itemprop="availability" class="d-none">InStock</span> 718 } 719 else 720 { 721 <span itemprop="availability" class="d-none">OutOfStock</span> 722 } 723 } 724 @* Stock state for Schema.org, stop *@ 725 726 </div> 727 728 @if (showPricesWithVat == "false" && !neverShowVat) 729 { 730 if (isLazyLoadingForProductInfoEnabled && !Pageview.IsVisualEditorMode) 731 { 732 <small class="opacity-85 fst-normal js-text-price-with-vat d-none" data-suffix="@Translate("Incl. VAT")"></small> 733 } 734 else 735 { 736 string price = !string.IsNullOrEmpty(unitId) ? product.GetPrice(unitId).Price.PriceWithVatFormatted : product.Price.PriceWithVatFormatted; 737 738 if (product?.VariantInfo?.VariantInfo != null) 739 { 740 priceMin = product?.VariantInfo?.PriceMin?.PriceWithVatFormatted != null ? product.VariantInfo.PriceMin.PriceWithVatFormatted : ""; 741 priceMax = product?.VariantInfo?.PriceMax?.PriceWithVatFormatted != null ? product.VariantInfo.PriceMax.PriceWithVatFormatted : ""; 742 } 743 if (priceMin != priceMax) 744 { 745 price = priceMin + " - " + priceMax; 746 } 747 <!-- <small class="opacity-85 fst-normal">@price @Translate("Incl. VAT")</small> --> 748 } 749 } 750 </div> 751 } 752 else if (Pageview.IsVisualEditorMode) 753 { 754 <div class="alert alert-dark m-0" role="alert"> 755 <span>@Translate("No products available")</span> 756 </div> 757 } 758 759 </div> 760 } 761 } 762
Tischlampe H-Form
Error executing template "Designs/Swift/Paragraph/CustomProductSlider.cshtml"
System.NullReferenceException: Object reference not set to an instance of an object.
   at CompiledRazorTemplates.Dynamic.RazorEngine_3562354021b44d5c892fe73dc2806e4f.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 Dynamicweb.Ecommerce.ProductCatalog 3 @using Dynamicweb.Ecommerce.CustomerExperienceCenter.Favorites 4 @using Dynamicweb.Files 5 @using System.IO 6 @using System.Net 7 @using Dynamicweb.Security.UserManagement 8 9 10 @{ 11 ProductViewModel product = null; 12 if (Dynamicweb.Context.Current.Items.Contains("ProductDetails")) 13 { 14 product = (ProductViewModel)Dynamicweb.Context.Current.Items["ProductDetails"]; 15 } 16 else if (Pageview.Page.Item["DummyProduct"] != null && Pageview.IsVisualEditorMode) 17 { 18 var pageViewModel = Dynamicweb.Frontend.ContentViewModelFactory.CreatePageInfoViewModel(Pageview.Page); 19 ProductListViewModel productList = pageViewModel.Item.GetValue("DummyProduct") != null ? pageViewModel.Item.GetValue("DummyProduct") as ProductListViewModel : new ProductListViewModel(); 20 21 if (productList?.Products is object) 22 { 23 product = productList.Products[0]; 24 } 25 } 26 } 27 28 @{ 29 var currentUser = Pageview?.User; 30 var customerNumber = !string.IsNullOrEmpty(currentUser?.CustomerNumber) 31 ? currentUser.CustomerNumber 32 : ""; 33 } 34 @if (product is object) 35 { 36 string imagePath = product?.DefaultImage?.Value ?? ""; 37 string imagePathUrlEncoded = Dynamicweb.Context.Current.Server.UrlEncode(imagePath); 38 39 string ratio = Model.Item.GetRawValueString("ImageAspectRatio", ""); 40 ratio = ratio != "0" ? ratio : ""; 41 string ratioCssClass = ratio != "" ? " ratio" : ""; 42 string ratioVariable = ratio != "" ? "--bs-aspect-ratio: " + ratio + ";" : ""; 43 44 string width = Model.Item.GetRawValueString("Width", "auto"); 45 int smallImageSize = 640; 46 int largeImageSize = width == "auto" ? 1280 : Convert.ToInt32(width); 47 48 string ImageObjectFit = Model.Item.GetRawValueString("ImageObjectFit", "contain"); 49 50 string imagePathXs = "/Admin/Public/GetImage.ashx?width=" + smallImageSize + "&image=" + imagePathUrlEncoded + "&format=webp"; 51 string imagePathS = "/Admin/Public/GetImage.ashx?width=" + largeImageSize + "&image=" + imagePathUrlEncoded + "&format=webp"; 52 string imagePathFallBack = "/Admin/Public/GetImage.ashx?width=" + largeImageSize + "&image=" + imagePathUrlEncoded + "&format=webp"; 53 54 var badgeParms = new Dictionary<string, object>(); 55 badgeParms.Add("size", "h7"); 56 badgeParms.Add("saleBadgeType", Model.Item.GetRawValue("SaleBadgeType")); 57 badgeParms.Add("saleBadgeCssClassName", Model.Item.GetRawValue("SaleBadgeDesign")); 58 badgeParms.Add("newBadgeCssClassName", Model.Item.GetRawValue("NewBadgeDesign")); 59 badgeParms.Add("newPublicationDays", Model.Item.GetInt32("NewPublicationDays")); 60 badgeParms.Add("campaignBadgesValues", Model.Item.GetList("CampaignBadges")?.GetRawValue().OfType<string>().ToList()); 61 62 string badgeSize = Model.Item.GetRawValueString("BadgeSize", "fs-2"); 63 bool saleBadgeEnabled = !string.IsNullOrWhiteSpace(Model.Item.GetRawValueString("SaleBadgeDesign")) && Model.Item.GetRawValueString("SaleBadgeDesign") != "none" ? true : false; 64 bool newBadgeEnabled = !string.IsNullOrWhiteSpace(Model.Item.GetRawValueString("NewBadgeDesign")) && Model.Item.GetRawValueString("NewBadgeDesign") != "none" ? true : false; 65 66 /*Custom badge*/ 67 var productService = new Dynamicweb.Ecommerce.Products.ProductService(); 68 var currency = Dynamicweb.Ecommerce.Common.Context.Currency.Code; 69 var formatProvider = new System.Globalization.NumberFormatInfo(); 70 formatProvider.NumberDecimalSeparator = "."; 71 formatProvider.NumberGroupSeparator = ","; 72 var MainVariant = productService.GetProductById(product.Id, product.VariantId, false); 73 var fieldValueBlocked = MainVariant?.ProductFieldValues?.GetProductFieldValue("BlockedCustomerList")?.Value; 74 75 76 string isNewProduct = MainVariant?.ProductFieldValues?.GetProductFieldValue("New")?.Value?.ToString().ToLower() ?? ""; 77 string MainisSale = MainVariant?.ProductFieldValues?.GetProductFieldValue("Sale")?.Value?.ToString().ToLower() ?? ""; 78 bool showNewBadge = isNewProduct == "true" ? true : false; 79 bool showSaleBadge = MainisSale == "true" ? true : false; 80 string showNewSaleBadge = "d-none"; 81 if (showSaleBadge) 82 { 83 badgeParms.Add("isSale", "true"); 84 85 } 86 else 87 { 88 badgeParms.Add("isSale", "false"); 89 } 90 if (showNewBadge) 91 { 92 badgeParms.Add("isNew", "true"); 93 } 94 else 95 { 96 badgeParms.Add("isNew", "false"); 97 } 98 /*End Custom badge*/ 99 if (showSaleBadge || showNewBadge) 100 { 101 showNewSaleBadge = ""; 102 } 103 DateTime createdDate = product.Created.Value; 104 bool showBadges = saleBadgeEnabled && product.Discount.Price != 0 ? true : false; 105 106 bool showFavoritesSelector = !string.IsNullOrEmpty(Model.Item.GetString("ShowAddToFavorites")) ? Model.Item.GetBoolean("ShowAddToFavorites") : false; 107 string anonymousUsersLimitations = Pageview.AreaSettings.GetRawValueString("AnonymousUsers", ""); 108 bool anonymousUser = Pageview.User == null; 109 110 var favoriteParameters = new Dictionary<string, object>(); 111 if (!anonymousUser && showFavoritesSelector) 112 { 113 int defaultFavoriteListId = 0; 114 115 IEnumerable<FavoriteList> favoreiteLists = Pageview.User.GetFavoriteLists(); 116 if (favoreiteLists.Count() == 1) 117 { 118 foreach (FavoriteList list in favoreiteLists) 119 { 120 defaultFavoriteListId = list.ListId; 121 } 122 } 123 124 favoriteParameters.Add("ListId", defaultFavoriteListId); 125 } 126 127 MediaViewModel alternativeImage = new MediaViewModel(); 128 if (Model.Item.GetBoolean("ShowAlternativeImageOnHover")) 129 { 130 var selectedImageCategories = Model.Item.GetList("GetAlternativeImageFrom")?.GetRawValue().OfType<string>().ToList(); 131 List<MediaViewModel> allAssetsImages = product.AssetCategories.Where(x => selectedImageCategories.Contains(x.SystemName)).SelectMany(x => x.Assets).ToList(); 132 allAssetsImages.RemoveAll(x => x.Value == product.DefaultImage.Value); 133 alternativeImage = allAssetsImages.FirstOrDefault(); 134 } 135 136 string altImagePathXs = string.Empty; 137 string altImagePathS = string.Empty; 138 139 if (!string.IsNullOrEmpty(alternativeImage?.Value)) 140 { 141 altImagePathXs = "/Admin/Public/GetImage.ashx?width=" + smallImageSize + "&image=" + Dynamicweb.Context.Current.Server.UrlEncode(alternativeImage.Value) + "&format=webp"; 142 altImagePathS = "/Admin/Public/GetImage.ashx?width=" + largeImageSize + "&image=" + Dynamicweb.Context.Current.Server.UrlEncode(alternativeImage.Value) + "&format=webp"; 143 } 144 145 @* Theme settings *@ 146 string theme = !string.IsNullOrWhiteSpace(Model.Item.GetRawValueString("Theme")) ? " theme " + Model.Item.GetRawValueString("Theme").Replace(" ", "").Trim().ToLower() : ""; 147 string themeBorder = !string.IsNullOrWhiteSpace(theme) ? "border: 1px solid rgba(0,0,0,0)" : ""; 148 string themePadding = !string.IsNullOrWhiteSpace(theme) ? "p-2 p-lg-3" : ""; 149 150 string imageId = "ProductImage_" + product.Id; 151 152 153 154 string fullWidth = width == "auto" ? "w-100" : ""; 155 string customWidth = width != "auto" ? "style=\"width: " + width + "px\"" : "style=\"min-width: 60px\""; 156 157 string altImageZindex = Model.Item.GetBoolean("ShowAlternativeImageOnHover") && !string.IsNullOrEmpty(alternativeImage?.Value) ? " z-index: 1" : string.Empty; 158 string groupid = !string.IsNullOrEmpty(Dynamicweb.Context.Current.Request.QueryString.Get("GroupID")) ? Dynamicweb.Context.Current.Request.QueryString.Get("GroupID"):"" ; 159 string link = product.GetProductLink(GetPageIdByNavigationTag("Shop"), false); 160 var productVariantGroups = product.VariantGroups(); 161 string MainOutStock = "<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"25\" height=\"25\" fill=\"#CA0D0D\" class=\"bi bi-x-lg\" viewBox=\"0 0 16 16\"><path d=\"M4.646 4.646a.5.5 0 0 1 .708 0L8 7.293l2.646-2.647a.5.5 0 0 1 .708.708L8.707 8l2.647 2.646a.5.5 0 0 1-.708.708L8 8.707l-2.646 2.647a.5.5 0 0 1-.708-.708L7.293 8 4.646 5.354a.5.5 0 0 1 0-.708\"/></svg>"; 162 163 @if (!string.IsNullOrEmpty(imagePath)) 164 { 165 <div class="@fullWidth @theme position-relative item_@Model.Item.SystemName.ToLower() main-image-container" @customWidth> 166 <div class="" style="@(ratioVariable)@(altImageZindex)"> 167 <div class="d-flex justify-content-center align-items-center"> 168 <a class="main-link-link" href="@link"> 169 @if (imagePath.StartsWith("/Files/", StringComparison.OrdinalIgnoreCase)) 170 { 171 <img id="@imageId" 172 srcset=" 173 @imagePathXs @(smallImageSize)w, 174 @imagePathS @(largeImageSize)w" 175 sizes="(max-width: 992px) 50vw, 25vw" 176 src="@imagePathFallBack" 177 loading="lazy" 178 decoding="async" 179 class="h-100 w-100 @themePadding main-image" 180 style="object-fit: @ImageObjectFit; @themeBorder " 181 alt="@product.Name" 182 itemprop="image"> 183 } 184 else 185 { 186 <img src="@product.DefaultImage.Value" 187 loading="lazy" 188 class="h-100 w-100 @themePadding main-image" 189 style="object-fit: contain; @themeBorder" 190 alt="@product.Name" 191 itemprop="image"> 192 } 193 </a> 194 </div> 195 </div> 196 197 <div class="position-absolute top-0 left-0 p-2 pb-0 custom-badge-product-list @showNewSaleBadge"> 198 @{ 199 @RenderPartial("Components/Custom_EcommerceBadge.cshtml", product, badgeParms) 200 } 201 </div> 202 203 204 </div> 205 } 206 207 <div class="product-info h-100"> 208 <div class="fs-7 pt-1 opacity-85 start item_@Model.Item.SystemName.ToLower() product-number" itemprop="sku">@product.Id / @product.VariantId - @product.VariantName</div> 209 <div class="py-2" data-col-size="12"> 210 <h2 class="h6 start m-0 item_swift_productheader product-name" itemprop="name"><b>@product.Name</b></h2> 211 </div> 212 </div> 213 var sliderId = $"thumb-scroll-{product.Id}"; 214 if (productVariantGroups.Any() && product?.VariantInfo?.VariantInfo != null) 215 216 { 217 @using Dynamicweb.Ecommerce.Prices 218 @{ 219 string[] variantId = product.VariantId.Split('.'); 220 string showPricesWithVat = Pageview.Area.EcomPricesWithVat.ToLower(); 221 bool neverShowVat = string.IsNullOrEmpty(showPricesWithVat); 222 bool showInformativePrice = Model.Item.GetBoolean("ShowInformativePrice"); 223 string productInfoFeed = ""; 224 bool isLazyLoadingForProductInfoEnabled = Dynamicweb.Core.Converter.ToBoolean(Dynamicweb.Context.Current.Items["IsLazyLoadingForProductInfoEnabled"]); 225 if (isLazyLoadingForProductInfoEnabled) 226 { 227 if (Dynamicweb.Context.Current.Items.Contains("ProductInfoFeed")) 228 { 229 productInfoFeed = Dynamicweb.Context.Current.Items["ProductInfoFeed"]?.ToString(); 230 if (!string.IsNullOrEmpty(productInfoFeed)) 231 { 232 productInfoFeed =productInfoFeed; 233 } 234 } 235 236 } 237 string priceMin = ""; 238 string priceMax = ""; 239 int groupNumber = 1; 240 241 242 243 244 string baseUrl = $"Default.aspx?ID={GetPageIdByNavigationTag("Shop")}&GroupID={product.PrimaryOrDefaultGroup.Id}&ProductID={product.Id}"; 245 if (!string.IsNullOrEmpty(baseUrl)) 246 { 247 baseUrl = $"/{baseUrl.TrimStart('/')}"; 248 } 249 string variantUrl = string.Empty; 250 251 252 Dictionary<string, string> 253 variantImages = new Dictionary<string, string> 254 (); 255 <div class="last-row mt-auto"> 256 257 @foreach (var variantGroup in productVariantGroups) 258 { 259 <div class="thumbnail-wrapper"> 260 <button class="thumb-nav prev" onclick="scrollThumbs('@sliderId', -1)"> 261 <svg width="20px" height="20px" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" fill="#1D98A5"> 262 263 <g stroke="none" stroke-width="1" fill="none" fill-rule="evenodd"> 264 <g transform="translate(-336.000000, 0.000000)"> 265 <g id="left_line" transform="translate(336.000000, 0.000000)"> 266 <path d="M24,0 L24,24 L0,24 L0,0 L24,0 Z M12.5934901,23.257841 L12.5819402,23.2595131 L12.5108777,23.2950439 L12.4918791,23.2987469 L12.4918791,23.2987469 L12.4767152,23.2950439 L12.4056548,23.2595131 C12.3958229,23.2563662 12.3870493,23.2590235 12.3821421,23.2649074 L12.3780323,23.275831 L12.360941,23.7031097 L12.3658947,23.7234994 L12.3769048,23.7357139 L12.4804777,23.8096931 L12.4953491,23.8136134 L12.4953491,23.8136134 L12.5071152,23.8096931 L12.6106902,23.7357139 L12.6232938,23.7196733 L12.6232938,23.7196733 L12.6266527,23.7031097 L12.609561,23.275831 C12.6075724,23.2657013 12.6010112,23.2592993 12.5934901,23.257841 L12.5934901,23.257841 Z M12.8583906,23.1452862 L12.8445485,23.1473072 L12.6598443,23.2396597 L12.6498822,23.2499052 L12.6498822,23.2499052 L12.6471943,23.2611114 L12.6650943,23.6906389 L12.6699349,23.7034178 L12.6699349,23.7034178 L12.678386,23.7104931 L12.8793402,23.8032389 C12.8914285,23.8068999 12.9022333,23.8029875 12.9078286,23.7952264 L12.9118235,23.7811639 L12.8776777,23.1665331 C12.8752882,23.1545897 12.8674102,23.1470016 12.8583906,23.1452862 L12.8583906,23.1452862 Z M12.1430473,23.1473072 C12.1332178,23.1423925 12.1221763,23.1452606 12.1156365,23.1525954 L12.1099173,23.1665331 L12.0757714,23.7811639 C12.0751323,23.7926639 12.0828099,23.8018602 12.0926481,23.8045676 L12.108256,23.8032389 L12.3092106,23.7104931 L12.3186497,23.7024347 L12.3186497,23.7024347 L12.3225043,23.6906389 L12.340401,23.2611114 L12.337245,23.2485176 L12.337245,23.2485176 L12.3277531,23.2396597 L12.1430473,23.1473072 Z" id="MingCute" fill-rule="nonzero"> </path> 267 <path d="M8.29292,12.7071 C7.9024,12.3166 7.9024,11.6834 8.29292,11.2929 L13.9498,5.63604 C14.3403,5.24551 14.9735,5.24551 15.364,5.63604 C15.7545,6.02656 15.7545,6.65973 15.364,7.05025 L10.4142,12 L15.364,16.9497 C15.7545,17.3403 15.7545,17.9734 15.364,18.364 C14.9735,18.7545 14.3403,18.7545 13.9498,18.364 L8.29292,12.7071 Z" id="路径" fill="#1D98A5"> </path> 268 </g> 269 </g> 270 </g> 271 </svg> 272 273 </button> 274 <div class="thumbnail-scroll" id="@sliderId"> 275 @{ 276 VariantGroupViewModel group = variantGroup; 277 foreach (var option in group.Options.OrderBy(o => o.Id)) 278 { 279 var productVariant = productService.GetProductById(product.Id, option.Id, false); 280 281 var productSelection = new PriceProductSelection(productVariant, null, 0); 282 283 var currencyCode = string.IsNullOrWhiteSpace(Pageview.User.Currency) ? Pageview.Area.EcomCurrencyId : Pageview.User.Currency; 284 var countryCode = string.IsNullOrWhiteSpace(Pageview.User.CountryCode) ? Pageview.Area.EcomCountryCode : Pageview.User.CountryCode; 285 286 var userCurrency = Dynamicweb.Ecommerce.Services.Currencies.GetCurrency(currencyCode); 287 var userCountry = Dynamicweb.Ecommerce.Services.Countries.GetCountry(countryCode); 288 289 var priceContext = new PriceContext(userCurrency, userCountry, null, Pageview.User, false, null); 290 var productPrice = Dynamicweb.Ecommerce.Services.Prices.FindPrices(priceContext, productSelection, false); 291 292 //throw new Exception(System.Text.Json.JsonSerializer.Serialize(productPrice)); 293 294 var fieldValue = productVariant?.ProductFieldValues?.GetProductFieldValue("BlockedCustomerList")?.Value; 295 296 if ((fieldValue != null && !fieldValue.ToString().Contains(customerNumber)) || String.IsNullOrWhiteSpace(customerNumber)) 297 { 298 299 300 string active = variantId != null && variantId.Contains(option.Id) ? "active" : string.Empty; 301 string buttonId = $"{product.Id}_{option.Id}_{Pageview.CurrentParagraph.ID}"; 302 string contrastColor = string.Empty; 303 304 string searchKey = $"{product.Id}_{option.Id}_"; 305 /*Images*/ 306 var imagePathVariant = option.Image?.Value ?? ""; 307 308 309 var folderPath = Path.GetDirectoryName(imagePathVariant); 310 311 string physicalFolderPath = Dynamicweb.Context.Current.Server.MapPath(folderPath); 312 313 string lastImage = null; 314 315 if (Directory.Exists(physicalFolderPath)) 316 { 317 318 var fileWith15 = Directory.GetFiles(physicalFolderPath) 319 .FirstOrDefault(f => Path.GetFileName(f).Contains($"{product.Id}_{option.Id}_9")); 320 321 if (fileWith15 != null) 322 { 323 lastImage = fileWith15; 324 } 325 else 326 { 327 var files = Directory.GetFiles(physicalFolderPath) 328 .Where(f => Path.GetFileName(f).StartsWith($"{product.Id}_{option.Id}_")) 329 .OrderByDescending(f => 330 { 331 var filename = Path.GetFileNameWithoutExtension(f); 332 var match = System.Text.RegularExpressions.Regex.Match(filename, @"_(\d+)$"); 333 if (match.Success && int.TryParse(match.Groups[1].Value, out int index)) 334 { 335 return index; 336 } 337 return 0; 338 }) 339 .ToList(); 340 341 if (files.Any()) 342 { 343 lastImage = files.First(); 344 } 345 } 346 } 347 348 var lastImageUrl = lastImage != null ? lastImage : "/Files/Images/zijlstra/Afbeeldingen_overig/Coming_Soon.jpg"; 349 int index = lastImageUrl.IndexOf("Files"); 350 string relativePath = index >= 0 ? lastImageUrl.Substring(index).Replace("\\", "/") : lastImageUrl.Replace("\\", "/"); 351 lastImageUrl = "/" + relativePath; 352 lastImageUrl = Dynamicweb.Context.Current.Server.UrlEncode(lastImageUrl); 353 var variantImg = option.Image is object ? Dynamicweb.Context.Current.Server.UrlEncode(option.Image.Value) : null; 354 var variantLink = "/Default.aspx?ID=" + GetPageIdByNavigationTag("Shop") + "&GroupID=" + product.PrimaryOrDefaultGroup.Id + "&ProductID=" + product.Id + "&VariantID=" + option.Id; 355 356 string variantImage = string.Empty; 357 variantImages.TryGetValue(option.Id, out variantImage); 358 /*End Images*/ 359 360 /*stock state*/ 361 double variantStock = productVariant.Stock; 362 string svgInStock = "<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"16\" height=\"16\" fill=\"#44B11A\" class=\"bi bi-check-lg\" viewBox=\"0 0 16 16\"><path d=\"M12.736 3.97a.733.733 0 0 1 1.047 0c.286.289.29.756.01 1.05L7.88 12.01a.733.733 0 0 1-1.065.02L3.217 8.384a.757.757 0 0 1 0-1.06.733.733 0 0 1 1.047 0l3.052 3.093 5.4-6.425z\"/></svg>"; 363 string svgOutStock = "<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"25\" height=\"25\" fill=\"#CA0D0D\" class=\"bi bi-x-lg\" viewBox=\"0 0 16 16\"><path d=\"M4.646 4.646a.5.5 0 0 1 .708 0L8 7.293l2.646-2.647a.5.5 0 0 1 .708.708L8.707 8l2.647 2.646a.5.5 0 0 1-.708.708L8 8.707l-2.646 2.647a.5.5 0 0 1-.708-.708L7.293 8 4.646 5.354a.5.5 0 0 1 0-.708\"/></svg>"; 364 365 string infoStock = "<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"16\" height=\"16\" fill=\"currentColor\" class=\"bi bi-info-circle-fill\" viewBox=\"0 0 16 16\"><path d=\"M8 16A8 8 0 1 0 8 0a8 8 0 0 0 0 16m.93-9.412-1 4.705c-.07.34.029.533.304.533.194 0 .487-.07.686-.246l-.088.416c-.287.346-.92.598-1.465.598-.703 0-1.002-.422-.808-1.319l.738-3.468c.064-.293.006-.399-.287-.47l-.451-.081.082-.381 2.29-.287zM8 5.5a1 1 0 1 1 0-2 1 1 0 0 1 0 2\" /></svg>"; 366 string isNew = productVariant?.ProductFieldValues?.GetProductFieldValue("New")?.Value?.ToString().ToLower() ?? ""; 367 string isNewSvg = "<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"16\" height=\"16\" fill=\"#F2C400\" class=\"bi bi-star-fill\" viewBox=\"0 0 16 16\"><path d = \"M3.612 15.443c-.386.198-.824-.149-.746-.592l.83-4.73L.173 6.765c-.329-.314-.158-.888.283-.95l4.898-.696L7.538.792c.197-.39.73-.39.927 0l2.184 4.327 4.898.696c.441.062.612.636.282.95l-3.522 3.356.83 4.73c.078.443-.36.79-.746.592L8 13.187l-4.389 2.256z\" /></svg> "; 368 string stockState = ""; 369 370 string isSale = productVariant?.ProductFieldValues?.GetProductFieldValue("Sale")?.Value?.ToString().ToLower() ?? ""; 371 string isSaleSvg = "<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"16\" height=\"16\" fill=\"#F03232\" class=\"bi bi-star-fill\" viewBox=\"0 0 16 16\"><path d = \"M3.612 15.443c-.386.198-.824-.149-.746-.592l.83-4.73L.173 6.765c-.329-.314-.158-.888.283-.95l4.898-.696L7.538.792c.197-.39.73-.39.927 0l2.184 4.327 4.898.696c.441.062.612.636.282.95l-3.522 3.356.83 4.73c.078.443-.36.79-.746.592L8 13.187l-4.389 2.256z\" /></svg> "; 372 373 string expectedDeliveryDate = ""; 374 375 if (DateTime.Compare(productVariant.ExpectedDelivery, new DateTime(1900, 1, 1)) != 0) //In DW, if the Date is not set, it is defaulted 01-01-1900 and not null.. 376 { 377 expectedDeliveryDate = productVariant.ExpectedDelivery.ToShortDateString(); 378 } 379 380 string expectedDeliveryDateText = !String.IsNullOrWhiteSpace(expectedDeliveryDate) ? Translate("Verwacht:") + "&nbsp;" + expectedDeliveryDate : ""; 381 382 @if (!(bool?)productVariant.ProductFieldValues.Where(o => o.ProductField.SystemName == "ProductToBeDiscontinued").SingleOrDefault()?.Value ?? false) 383 { 384 if (variantStock > 0) 385 { 386 if (isNew == "true" || isSale == "true") 387 { 388 if (isSale == "true") 389 { 390 stockState += isSaleSvg + "&nbsp; &nbsp;" + Translate("Sale!") + "<br/>"; 391 } 392 393 if (isNew == "true") 394 { 395 stockState += isNewSvg + "&nbsp; &nbsp;" + Translate("New!") + "<br/>"; 396 } 397 398 stockState += "&nbsp;" + Translate("Nu leverbaar"); 399 } 400 else 401 { 402 stockState = svgInStock + "&nbsp; " + Translate("Op voorraad"); 403 404 } 405 } 406 else 407 { 408 stockState = svgOutStock + "&nbsp;" + Translate("Geen voorraad") + "<br/>" + expectedDeliveryDateText; 409 410 } 411 } 412 else 413 { 414 415 stockState = svgOutStock + "&nbsp;" + Translate("Discontinued:") + "<br/>" + variantStock + "&nbsp;" + @Translate("left in stock"); 416 417 } 418 /*End stock state*/ 419 /*Price variants*/ 420 double price = productVariant.DefaultPrice; 421 double cost = productVariant.Cost; 422 423 string priceFormated = Dynamicweb.Ecommerce.Services.Currencies.Format(Dynamicweb.Ecommerce.Services.Currencies.GetCurrency(currency), Convert.ToDouble(productPrice.ToList()[0].Amount, formatProvider)); 424 //string priceFormated = Dynamicweb.Ecommerce.Services.Currencies.Format(Dynamicweb.Ecommerce.Services.Currencies.GetCurrency(currency), Convert.ToDouble(price, formatProvider)); 425 426 427 428 /*End Price variants*/ 429 430 <img class="theme thumbnail" data-stockstate="@WebUtility.HtmlEncode(stockState)" src="/Admin/Public/GetImage.ashx?image=@(lastImageUrl)&width=64&format=webp" onclick="selectVariant('@(product.Id)','/Admin/Public/GetImage.ashx?image=@(variantImg)&format=webp','@variantLink','@product.Id','@option.Id','@option.Name',this.dataset.stockstate,'@isNew','@isSale','@priceFormated','@cost')" /> 431 432 433 } 434 } 435 436 } 437 </div> 438 <button class="thumb-nav next" onclick="scrollThumbs('@sliderId', 1)"> 439 <svg width="20px" height="20px" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" fill="#1D98A5"> 440 441 <g stroke="none" stroke-width="1" fill="none" fill-rule="evenodd"> 442 <g transform="translate(-384.000000, 0.000000)"> 443 <g id="right_line" transform="translate(384.000000, 0.000000)"> 444 <path d="M24,0 L24,24 L0,24 L0,0 L24,0 Z M12.5934901,23.257841 L12.5819402,23.2595131 L12.5108777,23.2950439 L12.4918791,23.2987469 L12.4918791,23.2987469 L12.4767152,23.2950439 L12.4056548,23.2595131 C12.3958229,23.2563662 12.3870493,23.2590235 12.3821421,23.2649074 L12.3780323,23.275831 L12.360941,23.7031097 L12.3658947,23.7234994 L12.3769048,23.7357139 L12.4804777,23.8096931 L12.4953491,23.8136134 L12.4953491,23.8136134 L12.5071152,23.8096931 L12.6106902,23.7357139 L12.6232938,23.7196733 L12.6232938,23.7196733 L12.6266527,23.7031097 L12.609561,23.275831 C12.6075724,23.2657013 12.6010112,23.2592993 12.5934901,23.257841 L12.5934901,23.257841 Z M12.8583906,23.1452862 L12.8445485,23.1473072 L12.6598443,23.2396597 L12.6498822,23.2499052 L12.6498822,23.2499052 L12.6471943,23.2611114 L12.6650943,23.6906389 L12.6699349,23.7034178 L12.6699349,23.7034178 L12.678386,23.7104931 L12.8793402,23.8032389 C12.8914285,23.8068999 12.9022333,23.8029875 12.9078286,23.7952264 L12.9118235,23.7811639 L12.8776777,23.1665331 C12.8752882,23.1545897 12.8674102,23.1470016 12.8583906,23.1452862 L12.8583906,23.1452862 Z M12.1430473,23.1473072 C12.1332178,23.1423925 12.1221763,23.1452606 12.1156365,23.1525954 L12.1099173,23.1665331 L12.0757714,23.7811639 C12.0751323,23.7926639 12.0828099,23.8018602 12.0926481,23.8045676 L12.108256,23.8032389 L12.3092106,23.7104931 L12.3186497,23.7024347 L12.3186497,23.7024347 L12.3225043,23.6906389 L12.340401,23.2611114 L12.337245,23.2485176 L12.337245,23.2485176 L12.3277531,23.2396597 L12.1430473,23.1473072 Z" id="MingCute" fill-rule="nonzero"> </path> 445 <path d="M15.7072,11.2929 C16.0977,11.6834 16.0977,12.3166 15.7072,12.7071 L10.0503,18.364 C9.65982,18.7545 9.02666,18.7545 8.63613,18.364 C8.24561,17.9734 8.24561,17.3403 8.63613,16.9497 L13.5859,12 L8.63613,7.05025 C8.24561,6.65973 8.24561,6.02656 8.63613,5.63604 C9.02666,5.24551 9.65982,5.24551 10.0503,5.63604 L15.7072,11.2929 Z" id="路径" fill="#1D98A5"> </path> 446 </g> 447 </g> 448 449 </svg> 450 451 </button> 452 </div> 453 } 454 455 456 </div> 457 458 } 459 if ((fieldValueBlocked != null && !fieldValueBlocked.ToString().Contains(customerNumber)) || String.IsNullOrWhiteSpace(customerNumber)) 460 { 461 <div class="stock-state pt-2 mt-auto"> 462 @{ 463 464 /*stock state*/ 465 double MainvariantStock = MainVariant.Stock; 466 string MainsvgInStock = "<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"16\" height=\"16\" fill=\"#44B11A\" class=\"bi bi-check-lg\" viewBox=\"0 0 16 16\"><path d=\"M12.736 3.97a.733.733 0 0 1 1.047 0c.286.289.29.756.01 1.05L7.88 12.01a.733.733 0 0 1-1.065.02L3.217 8.384a.757.757 0 0 1 0-1.06.733.733 0 0 1 1.047 0l3.052 3.093 5.4-6.425z\"/></svg>"; 467 string MainsvgOutStock = "<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"25\" height=\"25\" fill=\"#CA0D0D\" class=\"bi bi-x-lg\" viewBox=\"0 0 16 16\"><path d=\"M4.646 4.646a.5.5 0 0 1 .708 0L8 7.293l2.646-2.647a.5.5 0 0 1 .708.708L8.707 8l2.647 2.646a.5.5 0 0 1-.708.708L8 8.707l-2.646 2.647a.5.5 0 0 1-.708-.708L7.293 8 4.646 5.354a.5.5 0 0 1 0-.708\"/></svg>"; 468 469 string MaininfoStock = "<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"16\" height=\"16\" fill=\"currentColor\" class=\"bi bi-info-circle-fill\" viewBox=\"0 0 16 16\"><path d=\"M8 16A8 8 0 1 0 8 0a8 8 0 0 0 0 16m.93-9.412-1 4.705c-.07.34.029.533.304.533.194 0 .487-.07.686-.246l-.088.416c-.287.346-.92.598-1.465.598-.703 0-1.002-.422-.808-1.319l.738-3.468c.064-.293.006-.399-.287-.47l-.451-.081.082-.381 2.29-.287zM8 5.5a1 1 0 1 1 0-2 1 1 0 0 1 0 2\" /></svg>"; 470 string MainisNew = MainVariant?.ProductFieldValues?.GetProductFieldValue("New")?.Value?.ToString().ToLower() ?? ""; 471 string MainisNewSvg = "<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"16\" height=\"16\" fill=\"#F2C400\" class=\"bi bi-star-fill\" viewBox=\"0 0 16 16\"><path d = \"M3.612 15.443c-.386.198-.824-.149-.746-.592l.83-4.73L.173 6.765c-.329-.314-.158-.888.283-.95l4.898-.696L7.538.792c.197-.39.73-.39.927 0l2.184 4.327 4.898.696c.441.062.612.636.282.95l-3.522 3.356.83 4.73c.078.443-.36.79-.746.592L8 13.187l-4.389 2.256z\" /></svg> "; 472 string MainstockState = ""; 473 string MainIsSale = MainVariant?.ProductFieldValues?.GetProductFieldValue("Sale")?.Value?.ToString().ToLower() ?? ""; 474 string MainIsSaleSvg = "<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"16\" height=\"16\" fill=\"#F03232\" class=\"bi bi-star-fill\" viewBox=\"0 0 16 16\"><path d = \"M3.612 15.443c-.386.198-.824-.149-.746-.592l.83-4.73L.173 6.765c-.329-.314-.158-.888.283-.95l4.898-.696L7.538.792c.197-.39.73-.39.927 0l2.184 4.327 4.898.696c.441.062.612.636.282.95l-3.522 3.356.83 4.73c.078.443-.36.79-.746.592L8 13.187l-4.389 2.256z\" /></svg> "; 475 string MainexpectedDeliveryDate = ""; 476 477 if (DateTime.Compare(MainVariant.ExpectedDelivery, new DateTime(1900, 1, 1)) != 0) //In DW, if the Date is not set, it is defaulted 01-01-1900 and not null.. 478 { 479 MainexpectedDeliveryDate = MainVariant.ExpectedDelivery.ToShortDateString(); 480 } 481 482 string MainexpectedDeliveryDateText = !String.IsNullOrWhiteSpace(MainexpectedDeliveryDate) ? Translate("Verwacht:") + "&nbsp;" + MainexpectedDeliveryDate : ""; 483 484 @if (!(bool?)MainVariant.ProductFieldValues.Where(o => o.ProductField.SystemName == "ProductToBeDiscontinued").SingleOrDefault()?.Value ?? false) 485 { 486 if (MainvariantStock > 0) 487 { 488 if (MainisNew == "true" || MainIsSale == "true") 489 { 490 if (MainIsSale == "true") 491 { 492 MainstockState += MainIsSaleSvg + "&nbsp; &nbsp;" + Translate("Sale!") + "<br/>"; 493 } 494 495 if (MainisNew == "true") 496 { 497 MainstockState += MainisNewSvg + "&nbsp; &nbsp;" + Translate("New!") + "<br/>"; 498 } 499 500 MainstockState += "&nbsp;" + Translate("Nu leverbaar"); 501 } 502 else 503 { 504 MainstockState = MainsvgInStock + "&nbsp; " + Translate("Op voorraad"); 505 506 } 507 } 508 else 509 { 510 MainstockState = MainsvgOutStock + "&nbsp;" + Translate("Geen voorraad") + "<br/>" + MainexpectedDeliveryDateText; 511 512 } 513 } 514 else 515 { 516 517 MainstockState = MainsvgOutStock + "&nbsp;" + Translate("Discontinued:") + "<br/>" + MainvariantStock + "&nbsp;" + @Translate("left in stock"); 518 519 } 520 /*End stock state*/ 521 522 523 @MainstockState 524 525 526 } 527 </div> 528 } 529 else 530 { 531 <div class="stock-state pt-2 mt-auto"> 532 @MainOutStock @Translate("Discontinued") 533 </div> 534 } 535 <div class="custom-price mt-auto"> 536 @{ 537 538 539 540 541 bool isErpConnectionDown = !Dynamicweb.Core.Converter.ToBoolean(Dynamicweb.Context.Current.Items["IsWebServiceConnectionAvailable"]); 542 bool hidePrice = anonymousUsersLimitations.Contains("price") && anonymousUser || Pageview.AreaSettings.GetBoolean("ErpDownHidePrices") && isErpConnectionDown; 543 544 bool productIsDiscontinued = product is object && product.Discontinued; 545 bool doNotShowPriceIfProductIsDiscontinued = Model.Item.GetBoolean("DoNotShowPriceIfProductIsDiscontinued"); 546 var isDiscontinued = productIsDiscontinued && doNotShowPriceIfProductIsDiscontinued; 547 } 548 549 @if (product is object && !hidePrice && !isDiscontinued) 550 { 551 string unitId = !string.IsNullOrEmpty(Dynamicweb.Context.Current.Request.Form.Get("UnitId")) ? Dynamicweb.Context.Current.Request.Form.Get("UnitId") : string.Empty; 552 553 string priceFontSize = Model.Item.GetRawValueString("PriceSize", "fs-4"); 554 string horizontalAlign = Model.Item.GetRawValueString("HorizontalAlignment", ""); 555 string layout = Model.Item.GetRawValueString("Layout", "horizontal"); 556 string textAlign = horizontalAlign == "center" ? "text-center" : string.Empty; 557 textAlign = horizontalAlign == "end" ? "text-end" : textAlign; 558 559 horizontalAlign = horizontalAlign == "center" && layout == "horizontal" ? "justify-content-center" : horizontalAlign; 560 horizontalAlign = horizontalAlign == "end" && layout == "horizontal" ? "justify-content-end" : horizontalAlign; 561 horizontalAlign = horizontalAlign == "center" && layout == "vertical" ? "align-items-center" : horizontalAlign; 562 horizontalAlign = horizontalAlign == "end" && layout == "vertical" ? "align-items-end" : horizontalAlign; 563 564 string flexDirection = layout == "horizontal" ? string.Empty : "flex-column"; 565 string flexGap = layout == "horizontal" ? "gap-3" : string.Empty; 566 string order = layout == "horizontal" ? string.Empty : "order-2"; 567 568 569 string contentPadding = Model.Item.GetRawValueString("ContentPadding", ""); 570 contentPadding = contentPadding == "none" ? "p-0" : contentPadding; 571 contentPadding = contentPadding == "small" ? "p-1 px-md-2 py-md-1" : contentPadding; 572 contentPadding = contentPadding == "large" ? "p-2 px-md-3 py-md-2" : contentPadding; 573 string liveInfoClass = ""; 574 575 576 577 578 579 580 if (isLazyLoadingForProductInfoEnabled) 581 { 582 if (Dynamicweb.Context.Current.Items.Contains("ProductInfoFeed")) 583 { 584 productInfoFeed = Dynamicweb.Context.Current.Items["ProductInfoFeed"]?.ToString(); 585 if (!string.IsNullOrEmpty(productInfoFeed)) 586 { 587 productInfoFeed = $"data-product-info-feed=\"{productInfoFeed}\""; 588 } 589 } 590 liveInfoClass = "js-live-info"; 591 } 592 593 <div class="@textAlign @liveInfoClass item_@Model.Item.SystemName.ToLower()" data-product-id="@product.Id" data-variant-id="@product.VariantId" @productInfoFeed> 594 @if (showInformativePrice && product.PriceInformative.Price != 0) 595 { 596 <div class="opacity-50"> 597 <span>@Translate("RRP") </span> 598 <span class="text-decoration-line-through text-price">@product.PriceInformative.PriceFormatted</span> 599 </div> 600 } 601 <div class="@priceFontSize m-0 d-flex flex-wrap @flexDirection @flexGap @horizontalAlign" style="row-gap: 0 !important" itemprop="offers" itemscope itemtype="https://schema.org/Offer"> 602 <span itemprop="priceCurrency" content="@product.Price.CurrencyCode" class="d-none"></span> 603 604 605 @if (showPricesWithVat == "false" && !neverShowVat) 606 { 607 if (isLazyLoadingForProductInfoEnabled && !Pageview.IsVisualEditorMode) 608 { 609 <span itemprop="price" content="" class="d-none"></span> 610 <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> 611 } 612 else 613 { 614 string beforePrice = !string.IsNullOrEmpty(unitId) ? product.GetPrice(unitId).PriceBeforeDiscount.PriceWithoutVatFormatted : product.PriceBeforeDiscount.PriceWithoutVatFormatted; 615 616 <span itemprop="price" content="@product.Price.PriceWithoutVat.ToString("0.00", System.Globalization.CultureInfo.InvariantCulture)" class="d-none"></span> 617 if (product.Price.Price != product.PriceBeforeDiscount.Price) 618 { 619 <span class="text-decoration-line-through opacity-75 @order">@beforePrice</span> 620 } 621 } 622 } 623 else 624 { 625 if (isLazyLoadingForProductInfoEnabled && !Pageview.IsVisualEditorMode) 626 { 627 <span itemprop="price" content="" class="d-none"></span> 628 <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> 629 } 630 else 631 { 632 string beforePrice = !string.IsNullOrEmpty(unitId) ? product.GetPrice(unitId).PriceBeforeDiscount.PriceFormatted : product.PriceBeforeDiscount.PriceFormatted; 633 634 <span itemprop="price" content="@product.Price.Price.ToString("0.00", System.Globalization.CultureInfo.InvariantCulture)" class="d-none"></span> 635 636 if (product.Price.Price != product.PriceBeforeDiscount.Price) 637 { 638 <span class="text-decoration-line-through opacity-75 @order"> 639 <span class="text-price">@beforePrice</span> 640 </span> 641 } 642 } 643 } 644 645 @if (showPricesWithVat == "false" && !neverShowVat) 646 { 647 if (isLazyLoadingForProductInfoEnabled && !Pageview.IsVisualEditorMode) 648 { 649 <span class="text-price js-text-price"> 650 <span class="spinner-border" role="status"></span> 651 </span> 652 } 653 else 654 { 655 string price = !string.IsNullOrEmpty(unitId) ? product.GetPrice(unitId).Price.PriceWithoutVatFormatted : product.Price.PriceWithoutVatFormatted; 656 657 if (product?.VariantInfo?.VariantInfo != null) 658 { 659 priceMin = product?.VariantInfo?.PriceMin?.PriceWithoutVatFormatted != null ? product.VariantInfo.PriceMin.PriceWithoutVatFormatted : ""; 660 priceMax = product?.VariantInfo?.PriceMax?.PriceWithoutVatFormatted != null ? product.VariantInfo.PriceMax.PriceWithoutVatFormatted : ""; 661 } 662 if (priceMin != priceMax) 663 { 664 price = priceMin + " - " + priceMax; 665 } 666 <span class="@theme @contentPadding"> 667 <span class="text-price">@price</span> 668 </span> 669 } 670 } 671 else 672 { 673 if (isLazyLoadingForProductInfoEnabled && !Pageview.IsVisualEditorMode) 674 { 675 <span class="text-price js-text-price"> 676 <span class="spinner-border" role="status"></span> 677 </span> 678 } 679 else 680 { 681 string price = !string.IsNullOrEmpty(unitId) ? product.GetPrice(unitId).Price.PriceFormatted : product.Price.PriceFormatted; 682 683 if (product?.VariantInfo?.VariantInfo != null) 684 { 685 priceMin = product?.VariantInfo?.PriceMin?.PriceFormatted != null ? product.VariantInfo.PriceMin.PriceFormatted : ""; 686 priceMax = product?.VariantInfo?.PriceMax?.PriceFormatted != null ? product.VariantInfo.PriceMax.PriceFormatted : ""; 687 } 688 if (priceMin != priceMax) 689 { 690 price = priceMin + " - " + priceMax; 691 } 692 <span class="@theme @contentPadding"> 693 <span class="text-price">@price</span> 694 </span> 695 } 696 } 697 698 @* Stock state for Schema.org, start *@ 699 @{ 700 Uri url = Dynamicweb.Context.Current.Request.Url; 701 } 702 703 <link itemprop="url" href="@url"> 704 705 @{ 706 bool IsNeverOutOfStock = product.NeverOutOfstock; 707 } 708 709 @if (IsNeverOutOfStock) 710 { 711 <span itemprop="availability" class="d-none">@Translate("Available in stock")</span> 712 } 713 else 714 { 715 if (product.StockLevel > 0) 716 { 717 <span itemprop="availability" class="d-none">InStock</span> 718 } 719 else 720 { 721 <span itemprop="availability" class="d-none">OutOfStock</span> 722 } 723 } 724 @* Stock state for Schema.org, stop *@ 725 726 </div> 727 728 @if (showPricesWithVat == "false" && !neverShowVat) 729 { 730 if (isLazyLoadingForProductInfoEnabled && !Pageview.IsVisualEditorMode) 731 { 732 <small class="opacity-85 fst-normal js-text-price-with-vat d-none" data-suffix="@Translate("Incl. VAT")"></small> 733 } 734 else 735 { 736 string price = !string.IsNullOrEmpty(unitId) ? product.GetPrice(unitId).Price.PriceWithVatFormatted : product.Price.PriceWithVatFormatted; 737 738 if (product?.VariantInfo?.VariantInfo != null) 739 { 740 priceMin = product?.VariantInfo?.PriceMin?.PriceWithVatFormatted != null ? product.VariantInfo.PriceMin.PriceWithVatFormatted : ""; 741 priceMax = product?.VariantInfo?.PriceMax?.PriceWithVatFormatted != null ? product.VariantInfo.PriceMax.PriceWithVatFormatted : ""; 742 } 743 if (priceMin != priceMax) 744 { 745 price = priceMin + " - " + priceMax; 746 } 747 <!-- <small class="opacity-85 fst-normal">@price @Translate("Incl. VAT")</small> --> 748 } 749 } 750 </div> 751 } 752 else if (Pageview.IsVisualEditorMode) 753 { 754 <div class="alert alert-dark m-0" role="alert"> 755 <span>@Translate("No products available")</span> 756 </div> 757 } 758 759 </div> 760 } 761 } 762
Tischlampe block
Error executing template "Designs/Swift/Paragraph/CustomProductSlider.cshtml"
System.NullReferenceException: Object reference not set to an instance of an object.
   at CompiledRazorTemplates.Dynamic.RazorEngine_3562354021b44d5c892fe73dc2806e4f.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 Dynamicweb.Ecommerce.ProductCatalog 3 @using Dynamicweb.Ecommerce.CustomerExperienceCenter.Favorites 4 @using Dynamicweb.Files 5 @using System.IO 6 @using System.Net 7 @using Dynamicweb.Security.UserManagement 8 9 10 @{ 11 ProductViewModel product = null; 12 if (Dynamicweb.Context.Current.Items.Contains("ProductDetails")) 13 { 14 product = (ProductViewModel)Dynamicweb.Context.Current.Items["ProductDetails"]; 15 } 16 else if (Pageview.Page.Item["DummyProduct"] != null && Pageview.IsVisualEditorMode) 17 { 18 var pageViewModel = Dynamicweb.Frontend.ContentViewModelFactory.CreatePageInfoViewModel(Pageview.Page); 19 ProductListViewModel productList = pageViewModel.Item.GetValue("DummyProduct") != null ? pageViewModel.Item.GetValue("DummyProduct") as ProductListViewModel : new ProductListViewModel(); 20 21 if (productList?.Products is object) 22 { 23 product = productList.Products[0]; 24 } 25 } 26 } 27 28 @{ 29 var currentUser = Pageview?.User; 30 var customerNumber = !string.IsNullOrEmpty(currentUser?.CustomerNumber) 31 ? currentUser.CustomerNumber 32 : ""; 33 } 34 @if (product is object) 35 { 36 string imagePath = product?.DefaultImage?.Value ?? ""; 37 string imagePathUrlEncoded = Dynamicweb.Context.Current.Server.UrlEncode(imagePath); 38 39 string ratio = Model.Item.GetRawValueString("ImageAspectRatio", ""); 40 ratio = ratio != "0" ? ratio : ""; 41 string ratioCssClass = ratio != "" ? " ratio" : ""; 42 string ratioVariable = ratio != "" ? "--bs-aspect-ratio: " + ratio + ";" : ""; 43 44 string width = Model.Item.GetRawValueString("Width", "auto"); 45 int smallImageSize = 640; 46 int largeImageSize = width == "auto" ? 1280 : Convert.ToInt32(width); 47 48 string ImageObjectFit = Model.Item.GetRawValueString("ImageObjectFit", "contain"); 49 50 string imagePathXs = "/Admin/Public/GetImage.ashx?width=" + smallImageSize + "&image=" + imagePathUrlEncoded + "&format=webp"; 51 string imagePathS = "/Admin/Public/GetImage.ashx?width=" + largeImageSize + "&image=" + imagePathUrlEncoded + "&format=webp"; 52 string imagePathFallBack = "/Admin/Public/GetImage.ashx?width=" + largeImageSize + "&image=" + imagePathUrlEncoded + "&format=webp"; 53 54 var badgeParms = new Dictionary<string, object>(); 55 badgeParms.Add("size", "h7"); 56 badgeParms.Add("saleBadgeType", Model.Item.GetRawValue("SaleBadgeType")); 57 badgeParms.Add("saleBadgeCssClassName", Model.Item.GetRawValue("SaleBadgeDesign")); 58 badgeParms.Add("newBadgeCssClassName", Model.Item.GetRawValue("NewBadgeDesign")); 59 badgeParms.Add("newPublicationDays", Model.Item.GetInt32("NewPublicationDays")); 60 badgeParms.Add("campaignBadgesValues", Model.Item.GetList("CampaignBadges")?.GetRawValue().OfType<string>().ToList()); 61 62 string badgeSize = Model.Item.GetRawValueString("BadgeSize", "fs-2"); 63 bool saleBadgeEnabled = !string.IsNullOrWhiteSpace(Model.Item.GetRawValueString("SaleBadgeDesign")) && Model.Item.GetRawValueString("SaleBadgeDesign") != "none" ? true : false; 64 bool newBadgeEnabled = !string.IsNullOrWhiteSpace(Model.Item.GetRawValueString("NewBadgeDesign")) && Model.Item.GetRawValueString("NewBadgeDesign") != "none" ? true : false; 65 66 /*Custom badge*/ 67 var productService = new Dynamicweb.Ecommerce.Products.ProductService(); 68 var currency = Dynamicweb.Ecommerce.Common.Context.Currency.Code; 69 var formatProvider = new System.Globalization.NumberFormatInfo(); 70 formatProvider.NumberDecimalSeparator = "."; 71 formatProvider.NumberGroupSeparator = ","; 72 var MainVariant = productService.GetProductById(product.Id, product.VariantId, false); 73 var fieldValueBlocked = MainVariant?.ProductFieldValues?.GetProductFieldValue("BlockedCustomerList")?.Value; 74 75 76 string isNewProduct = MainVariant?.ProductFieldValues?.GetProductFieldValue("New")?.Value?.ToString().ToLower() ?? ""; 77 string MainisSale = MainVariant?.ProductFieldValues?.GetProductFieldValue("Sale")?.Value?.ToString().ToLower() ?? ""; 78 bool showNewBadge = isNewProduct == "true" ? true : false; 79 bool showSaleBadge = MainisSale == "true" ? true : false; 80 string showNewSaleBadge = "d-none"; 81 if (showSaleBadge) 82 { 83 badgeParms.Add("isSale", "true"); 84 85 } 86 else 87 { 88 badgeParms.Add("isSale", "false"); 89 } 90 if (showNewBadge) 91 { 92 badgeParms.Add("isNew", "true"); 93 } 94 else 95 { 96 badgeParms.Add("isNew", "false"); 97 } 98 /*End Custom badge*/ 99 if (showSaleBadge || showNewBadge) 100 { 101 showNewSaleBadge = ""; 102 } 103 DateTime createdDate = product.Created.Value; 104 bool showBadges = saleBadgeEnabled && product.Discount.Price != 0 ? true : false; 105 106 bool showFavoritesSelector = !string.IsNullOrEmpty(Model.Item.GetString("ShowAddToFavorites")) ? Model.Item.GetBoolean("ShowAddToFavorites") : false; 107 string anonymousUsersLimitations = Pageview.AreaSettings.GetRawValueString("AnonymousUsers", ""); 108 bool anonymousUser = Pageview.User == null; 109 110 var favoriteParameters = new Dictionary<string, object>(); 111 if (!anonymousUser && showFavoritesSelector) 112 { 113 int defaultFavoriteListId = 0; 114 115 IEnumerable<FavoriteList> favoreiteLists = Pageview.User.GetFavoriteLists(); 116 if (favoreiteLists.Count() == 1) 117 { 118 foreach (FavoriteList list in favoreiteLists) 119 { 120 defaultFavoriteListId = list.ListId; 121 } 122 } 123 124 favoriteParameters.Add("ListId", defaultFavoriteListId); 125 } 126 127 MediaViewModel alternativeImage = new MediaViewModel(); 128 if (Model.Item.GetBoolean("ShowAlternativeImageOnHover")) 129 { 130 var selectedImageCategories = Model.Item.GetList("GetAlternativeImageFrom")?.GetRawValue().OfType<string>().ToList(); 131 List<MediaViewModel> allAssetsImages = product.AssetCategories.Where(x => selectedImageCategories.Contains(x.SystemName)).SelectMany(x => x.Assets).ToList(); 132 allAssetsImages.RemoveAll(x => x.Value == product.DefaultImage.Value); 133 alternativeImage = allAssetsImages.FirstOrDefault(); 134 } 135 136 string altImagePathXs = string.Empty; 137 string altImagePathS = string.Empty; 138 139 if (!string.IsNullOrEmpty(alternativeImage?.Value)) 140 { 141 altImagePathXs = "/Admin/Public/GetImage.ashx?width=" + smallImageSize + "&image=" + Dynamicweb.Context.Current.Server.UrlEncode(alternativeImage.Value) + "&format=webp"; 142 altImagePathS = "/Admin/Public/GetImage.ashx?width=" + largeImageSize + "&image=" + Dynamicweb.Context.Current.Server.UrlEncode(alternativeImage.Value) + "&format=webp"; 143 } 144 145 @* Theme settings *@ 146 string theme = !string.IsNullOrWhiteSpace(Model.Item.GetRawValueString("Theme")) ? " theme " + Model.Item.GetRawValueString("Theme").Replace(" ", "").Trim().ToLower() : ""; 147 string themeBorder = !string.IsNullOrWhiteSpace(theme) ? "border: 1px solid rgba(0,0,0,0)" : ""; 148 string themePadding = !string.IsNullOrWhiteSpace(theme) ? "p-2 p-lg-3" : ""; 149 150 string imageId = "ProductImage_" + product.Id; 151 152 153 154 string fullWidth = width == "auto" ? "w-100" : ""; 155 string customWidth = width != "auto" ? "style=\"width: " + width + "px\"" : "style=\"min-width: 60px\""; 156 157 string altImageZindex = Model.Item.GetBoolean("ShowAlternativeImageOnHover") && !string.IsNullOrEmpty(alternativeImage?.Value) ? " z-index: 1" : string.Empty; 158 string groupid = !string.IsNullOrEmpty(Dynamicweb.Context.Current.Request.QueryString.Get("GroupID")) ? Dynamicweb.Context.Current.Request.QueryString.Get("GroupID"):"" ; 159 string link = product.GetProductLink(GetPageIdByNavigationTag("Shop"), false); 160 var productVariantGroups = product.VariantGroups(); 161 string MainOutStock = "<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"25\" height=\"25\" fill=\"#CA0D0D\" class=\"bi bi-x-lg\" viewBox=\"0 0 16 16\"><path d=\"M4.646 4.646a.5.5 0 0 1 .708 0L8 7.293l2.646-2.647a.5.5 0 0 1 .708.708L8.707 8l2.647 2.646a.5.5 0 0 1-.708.708L8 8.707l-2.646 2.647a.5.5 0 0 1-.708-.708L7.293 8 4.646 5.354a.5.5 0 0 1 0-.708\"/></svg>"; 162 163 @if (!string.IsNullOrEmpty(imagePath)) 164 { 165 <div class="@fullWidth @theme position-relative item_@Model.Item.SystemName.ToLower() main-image-container" @customWidth> 166 <div class="" style="@(ratioVariable)@(altImageZindex)"> 167 <div class="d-flex justify-content-center align-items-center"> 168 <a class="main-link-link" href="@link"> 169 @if (imagePath.StartsWith("/Files/", StringComparison.OrdinalIgnoreCase)) 170 { 171 <img id="@imageId" 172 srcset=" 173 @imagePathXs @(smallImageSize)w, 174 @imagePathS @(largeImageSize)w" 175 sizes="(max-width: 992px) 50vw, 25vw" 176 src="@imagePathFallBack" 177 loading="lazy" 178 decoding="async" 179 class="h-100 w-100 @themePadding main-image" 180 style="object-fit: @ImageObjectFit; @themeBorder " 181 alt="@product.Name" 182 itemprop="image"> 183 } 184 else 185 { 186 <img src="@product.DefaultImage.Value" 187 loading="lazy" 188 class="h-100 w-100 @themePadding main-image" 189 style="object-fit: contain; @themeBorder" 190 alt="@product.Name" 191 itemprop="image"> 192 } 193 </a> 194 </div> 195 </div> 196 197 <div class="position-absolute top-0 left-0 p-2 pb-0 custom-badge-product-list @showNewSaleBadge"> 198 @{ 199 @RenderPartial("Components/Custom_EcommerceBadge.cshtml", product, badgeParms) 200 } 201 </div> 202 203 204 </div> 205 } 206 207 <div class="product-info h-100"> 208 <div class="fs-7 pt-1 opacity-85 start item_@Model.Item.SystemName.ToLower() product-number" itemprop="sku">@product.Id / @product.VariantId - @product.VariantName</div> 209 <div class="py-2" data-col-size="12"> 210 <h2 class="h6 start m-0 item_swift_productheader product-name" itemprop="name"><b>@product.Name</b></h2> 211 </div> 212 </div> 213 var sliderId = $"thumb-scroll-{product.Id}"; 214 if (productVariantGroups.Any() && product?.VariantInfo?.VariantInfo != null) 215 216 { 217 @using Dynamicweb.Ecommerce.Prices 218 @{ 219 string[] variantId = product.VariantId.Split('.'); 220 string showPricesWithVat = Pageview.Area.EcomPricesWithVat.ToLower(); 221 bool neverShowVat = string.IsNullOrEmpty(showPricesWithVat); 222 bool showInformativePrice = Model.Item.GetBoolean("ShowInformativePrice"); 223 string productInfoFeed = ""; 224 bool isLazyLoadingForProductInfoEnabled = Dynamicweb.Core.Converter.ToBoolean(Dynamicweb.Context.Current.Items["IsLazyLoadingForProductInfoEnabled"]); 225 if (isLazyLoadingForProductInfoEnabled) 226 { 227 if (Dynamicweb.Context.Current.Items.Contains("ProductInfoFeed")) 228 { 229 productInfoFeed = Dynamicweb.Context.Current.Items["ProductInfoFeed"]?.ToString(); 230 if (!string.IsNullOrEmpty(productInfoFeed)) 231 { 232 productInfoFeed =productInfoFeed; 233 } 234 } 235 236 } 237 string priceMin = ""; 238 string priceMax = ""; 239 int groupNumber = 1; 240 241 242 243 244 string baseUrl = $"Default.aspx?ID={GetPageIdByNavigationTag("Shop")}&GroupID={product.PrimaryOrDefaultGroup.Id}&ProductID={product.Id}"; 245 if (!string.IsNullOrEmpty(baseUrl)) 246 { 247 baseUrl = $"/{baseUrl.TrimStart('/')}"; 248 } 249 string variantUrl = string.Empty; 250 251 252 Dictionary<string, string> 253 variantImages = new Dictionary<string, string> 254 (); 255 <div class="last-row mt-auto"> 256 257 @foreach (var variantGroup in productVariantGroups) 258 { 259 <div class="thumbnail-wrapper"> 260 <button class="thumb-nav prev" onclick="scrollThumbs('@sliderId', -1)"> 261 <svg width="20px" height="20px" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" fill="#1D98A5"> 262 263 <g stroke="none" stroke-width="1" fill="none" fill-rule="evenodd"> 264 <g transform="translate(-336.000000, 0.000000)"> 265 <g id="left_line" transform="translate(336.000000, 0.000000)"> 266 <path d="M24,0 L24,24 L0,24 L0,0 L24,0 Z M12.5934901,23.257841 L12.5819402,23.2595131 L12.5108777,23.2950439 L12.4918791,23.2987469 L12.4918791,23.2987469 L12.4767152,23.2950439 L12.4056548,23.2595131 C12.3958229,23.2563662 12.3870493,23.2590235 12.3821421,23.2649074 L12.3780323,23.275831 L12.360941,23.7031097 L12.3658947,23.7234994 L12.3769048,23.7357139 L12.4804777,23.8096931 L12.4953491,23.8136134 L12.4953491,23.8136134 L12.5071152,23.8096931 L12.6106902,23.7357139 L12.6232938,23.7196733 L12.6232938,23.7196733 L12.6266527,23.7031097 L12.609561,23.275831 C12.6075724,23.2657013 12.6010112,23.2592993 12.5934901,23.257841 L12.5934901,23.257841 Z M12.8583906,23.1452862 L12.8445485,23.1473072 L12.6598443,23.2396597 L12.6498822,23.2499052 L12.6498822,23.2499052 L12.6471943,23.2611114 L12.6650943,23.6906389 L12.6699349,23.7034178 L12.6699349,23.7034178 L12.678386,23.7104931 L12.8793402,23.8032389 C12.8914285,23.8068999 12.9022333,23.8029875 12.9078286,23.7952264 L12.9118235,23.7811639 L12.8776777,23.1665331 C12.8752882,23.1545897 12.8674102,23.1470016 12.8583906,23.1452862 L12.8583906,23.1452862 Z M12.1430473,23.1473072 C12.1332178,23.1423925 12.1221763,23.1452606 12.1156365,23.1525954 L12.1099173,23.1665331 L12.0757714,23.7811639 C12.0751323,23.7926639 12.0828099,23.8018602 12.0926481,23.8045676 L12.108256,23.8032389 L12.3092106,23.7104931 L12.3186497,23.7024347 L12.3186497,23.7024347 L12.3225043,23.6906389 L12.340401,23.2611114 L12.337245,23.2485176 L12.337245,23.2485176 L12.3277531,23.2396597 L12.1430473,23.1473072 Z" id="MingCute" fill-rule="nonzero"> </path> 267 <path d="M8.29292,12.7071 C7.9024,12.3166 7.9024,11.6834 8.29292,11.2929 L13.9498,5.63604 C14.3403,5.24551 14.9735,5.24551 15.364,5.63604 C15.7545,6.02656 15.7545,6.65973 15.364,7.05025 L10.4142,12 L15.364,16.9497 C15.7545,17.3403 15.7545,17.9734 15.364,18.364 C14.9735,18.7545 14.3403,18.7545 13.9498,18.364 L8.29292,12.7071 Z" id="路径" fill="#1D98A5"> </path> 268 </g> 269 </g> 270 </g> 271 </svg> 272 273 </button> 274 <div class="thumbnail-scroll" id="@sliderId"> 275 @{ 276 VariantGroupViewModel group = variantGroup; 277 foreach (var option in group.Options.OrderBy(o => o.Id)) 278 { 279 var productVariant = productService.GetProductById(product.Id, option.Id, false); 280 281 var productSelection = new PriceProductSelection(productVariant, null, 0); 282 283 var currencyCode = string.IsNullOrWhiteSpace(Pageview.User.Currency) ? Pageview.Area.EcomCurrencyId : Pageview.User.Currency; 284 var countryCode = string.IsNullOrWhiteSpace(Pageview.User.CountryCode) ? Pageview.Area.EcomCountryCode : Pageview.User.CountryCode; 285 286 var userCurrency = Dynamicweb.Ecommerce.Services.Currencies.GetCurrency(currencyCode); 287 var userCountry = Dynamicweb.Ecommerce.Services.Countries.GetCountry(countryCode); 288 289 var priceContext = new PriceContext(userCurrency, userCountry, null, Pageview.User, false, null); 290 var productPrice = Dynamicweb.Ecommerce.Services.Prices.FindPrices(priceContext, productSelection, false); 291 292 //throw new Exception(System.Text.Json.JsonSerializer.Serialize(productPrice)); 293 294 var fieldValue = productVariant?.ProductFieldValues?.GetProductFieldValue("BlockedCustomerList")?.Value; 295 296 if ((fieldValue != null && !fieldValue.ToString().Contains(customerNumber)) || String.IsNullOrWhiteSpace(customerNumber)) 297 { 298 299 300 string active = variantId != null && variantId.Contains(option.Id) ? "active" : string.Empty; 301 string buttonId = $"{product.Id}_{option.Id}_{Pageview.CurrentParagraph.ID}"; 302 string contrastColor = string.Empty; 303 304 string searchKey = $"{product.Id}_{option.Id}_"; 305 /*Images*/ 306 var imagePathVariant = option.Image?.Value ?? ""; 307 308 309 var folderPath = Path.GetDirectoryName(imagePathVariant); 310 311 string physicalFolderPath = Dynamicweb.Context.Current.Server.MapPath(folderPath); 312 313 string lastImage = null; 314 315 if (Directory.Exists(physicalFolderPath)) 316 { 317 318 var fileWith15 = Directory.GetFiles(physicalFolderPath) 319 .FirstOrDefault(f => Path.GetFileName(f).Contains($"{product.Id}_{option.Id}_9")); 320 321 if (fileWith15 != null) 322 { 323 lastImage = fileWith15; 324 } 325 else 326 { 327 var files = Directory.GetFiles(physicalFolderPath) 328 .Where(f => Path.GetFileName(f).StartsWith($"{product.Id}_{option.Id}_")) 329 .OrderByDescending(f => 330 { 331 var filename = Path.GetFileNameWithoutExtension(f); 332 var match = System.Text.RegularExpressions.Regex.Match(filename, @"_(\d+)$"); 333 if (match.Success && int.TryParse(match.Groups[1].Value, out int index)) 334 { 335 return index; 336 } 337 return 0; 338 }) 339 .ToList(); 340 341 if (files.Any()) 342 { 343 lastImage = files.First(); 344 } 345 } 346 } 347 348 var lastImageUrl = lastImage != null ? lastImage : "/Files/Images/zijlstra/Afbeeldingen_overig/Coming_Soon.jpg"; 349 int index = lastImageUrl.IndexOf("Files"); 350 string relativePath = index >= 0 ? lastImageUrl.Substring(index).Replace("\\", "/") : lastImageUrl.Replace("\\", "/"); 351 lastImageUrl = "/" + relativePath; 352 lastImageUrl = Dynamicweb.Context.Current.Server.UrlEncode(lastImageUrl); 353 var variantImg = option.Image is object ? Dynamicweb.Context.Current.Server.UrlEncode(option.Image.Value) : null; 354 var variantLink = "/Default.aspx?ID=" + GetPageIdByNavigationTag("Shop") + "&GroupID=" + product.PrimaryOrDefaultGroup.Id + "&ProductID=" + product.Id + "&VariantID=" + option.Id; 355 356 string variantImage = string.Empty; 357 variantImages.TryGetValue(option.Id, out variantImage); 358 /*End Images*/ 359 360 /*stock state*/ 361 double variantStock = productVariant.Stock; 362 string svgInStock = "<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"16\" height=\"16\" fill=\"#44B11A\" class=\"bi bi-check-lg\" viewBox=\"0 0 16 16\"><path d=\"M12.736 3.97a.733.733 0 0 1 1.047 0c.286.289.29.756.01 1.05L7.88 12.01a.733.733 0 0 1-1.065.02L3.217 8.384a.757.757 0 0 1 0-1.06.733.733 0 0 1 1.047 0l3.052 3.093 5.4-6.425z\"/></svg>"; 363 string svgOutStock = "<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"25\" height=\"25\" fill=\"#CA0D0D\" class=\"bi bi-x-lg\" viewBox=\"0 0 16 16\"><path d=\"M4.646 4.646a.5.5 0 0 1 .708 0L8 7.293l2.646-2.647a.5.5 0 0 1 .708.708L8.707 8l2.647 2.646a.5.5 0 0 1-.708.708L8 8.707l-2.646 2.647a.5.5 0 0 1-.708-.708L7.293 8 4.646 5.354a.5.5 0 0 1 0-.708\"/></svg>"; 364 365 string infoStock = "<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"16\" height=\"16\" fill=\"currentColor\" class=\"bi bi-info-circle-fill\" viewBox=\"0 0 16 16\"><path d=\"M8 16A8 8 0 1 0 8 0a8 8 0 0 0 0 16m.93-9.412-1 4.705c-.07.34.029.533.304.533.194 0 .487-.07.686-.246l-.088.416c-.287.346-.92.598-1.465.598-.703 0-1.002-.422-.808-1.319l.738-3.468c.064-.293.006-.399-.287-.47l-.451-.081.082-.381 2.29-.287zM8 5.5a1 1 0 1 1 0-2 1 1 0 0 1 0 2\" /></svg>"; 366 string isNew = productVariant?.ProductFieldValues?.GetProductFieldValue("New")?.Value?.ToString().ToLower() ?? ""; 367 string isNewSvg = "<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"16\" height=\"16\" fill=\"#F2C400\" class=\"bi bi-star-fill\" viewBox=\"0 0 16 16\"><path d = \"M3.612 15.443c-.386.198-.824-.149-.746-.592l.83-4.73L.173 6.765c-.329-.314-.158-.888.283-.95l4.898-.696L7.538.792c.197-.39.73-.39.927 0l2.184 4.327 4.898.696c.441.062.612.636.282.95l-3.522 3.356.83 4.73c.078.443-.36.79-.746.592L8 13.187l-4.389 2.256z\" /></svg> "; 368 string stockState = ""; 369 370 string isSale = productVariant?.ProductFieldValues?.GetProductFieldValue("Sale")?.Value?.ToString().ToLower() ?? ""; 371 string isSaleSvg = "<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"16\" height=\"16\" fill=\"#F03232\" class=\"bi bi-star-fill\" viewBox=\"0 0 16 16\"><path d = \"M3.612 15.443c-.386.198-.824-.149-.746-.592l.83-4.73L.173 6.765c-.329-.314-.158-.888.283-.95l4.898-.696L7.538.792c.197-.39.73-.39.927 0l2.184 4.327 4.898.696c.441.062.612.636.282.95l-3.522 3.356.83 4.73c.078.443-.36.79-.746.592L8 13.187l-4.389 2.256z\" /></svg> "; 372 373 string expectedDeliveryDate = ""; 374 375 if (DateTime.Compare(productVariant.ExpectedDelivery, new DateTime(1900, 1, 1)) != 0) //In DW, if the Date is not set, it is defaulted 01-01-1900 and not null.. 376 { 377 expectedDeliveryDate = productVariant.ExpectedDelivery.ToShortDateString(); 378 } 379 380 string expectedDeliveryDateText = !String.IsNullOrWhiteSpace(expectedDeliveryDate) ? Translate("Verwacht:") + "&nbsp;" + expectedDeliveryDate : ""; 381 382 @if (!(bool?)productVariant.ProductFieldValues.Where(o => o.ProductField.SystemName == "ProductToBeDiscontinued").SingleOrDefault()?.Value ?? false) 383 { 384 if (variantStock > 0) 385 { 386 if (isNew == "true" || isSale == "true") 387 { 388 if (isSale == "true") 389 { 390 stockState += isSaleSvg + "&nbsp; &nbsp;" + Translate("Sale!") + "<br/>"; 391 } 392 393 if (isNew == "true") 394 { 395 stockState += isNewSvg + "&nbsp; &nbsp;" + Translate("New!") + "<br/>"; 396 } 397 398 stockState += "&nbsp;" + Translate("Nu leverbaar"); 399 } 400 else 401 { 402 stockState = svgInStock + "&nbsp; " + Translate("Op voorraad"); 403 404 } 405 } 406 else 407 { 408 stockState = svgOutStock + "&nbsp;" + Translate("Geen voorraad") + "<br/>" + expectedDeliveryDateText; 409 410 } 411 } 412 else 413 { 414 415 stockState = svgOutStock + "&nbsp;" + Translate("Discontinued:") + "<br/>" + variantStock + "&nbsp;" + @Translate("left in stock"); 416 417 } 418 /*End stock state*/ 419 /*Price variants*/ 420 double price = productVariant.DefaultPrice; 421 double cost = productVariant.Cost; 422 423 string priceFormated = Dynamicweb.Ecommerce.Services.Currencies.Format(Dynamicweb.Ecommerce.Services.Currencies.GetCurrency(currency), Convert.ToDouble(productPrice.ToList()[0].Amount, formatProvider)); 424 //string priceFormated = Dynamicweb.Ecommerce.Services.Currencies.Format(Dynamicweb.Ecommerce.Services.Currencies.GetCurrency(currency), Convert.ToDouble(price, formatProvider)); 425 426 427 428 /*End Price variants*/ 429 430 <img class="theme thumbnail" data-stockstate="@WebUtility.HtmlEncode(stockState)" src="/Admin/Public/GetImage.ashx?image=@(lastImageUrl)&width=64&format=webp" onclick="selectVariant('@(product.Id)','/Admin/Public/GetImage.ashx?image=@(variantImg)&format=webp','@variantLink','@product.Id','@option.Id','@option.Name',this.dataset.stockstate,'@isNew','@isSale','@priceFormated','@cost')" /> 431 432 433 } 434 } 435 436 } 437 </div> 438 <button class="thumb-nav next" onclick="scrollThumbs('@sliderId', 1)"> 439 <svg width="20px" height="20px" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" fill="#1D98A5"> 440 441 <g stroke="none" stroke-width="1" fill="none" fill-rule="evenodd"> 442 <g transform="translate(-384.000000, 0.000000)"> 443 <g id="right_line" transform="translate(384.000000, 0.000000)"> 444 <path d="M24,0 L24,24 L0,24 L0,0 L24,0 Z M12.5934901,23.257841 L12.5819402,23.2595131 L12.5108777,23.2950439 L12.4918791,23.2987469 L12.4918791,23.2987469 L12.4767152,23.2950439 L12.4056548,23.2595131 C12.3958229,23.2563662 12.3870493,23.2590235 12.3821421,23.2649074 L12.3780323,23.275831 L12.360941,23.7031097 L12.3658947,23.7234994 L12.3769048,23.7357139 L12.4804777,23.8096931 L12.4953491,23.8136134 L12.4953491,23.8136134 L12.5071152,23.8096931 L12.6106902,23.7357139 L12.6232938,23.7196733 L12.6232938,23.7196733 L12.6266527,23.7031097 L12.609561,23.275831 C12.6075724,23.2657013 12.6010112,23.2592993 12.5934901,23.257841 L12.5934901,23.257841 Z M12.8583906,23.1452862 L12.8445485,23.1473072 L12.6598443,23.2396597 L12.6498822,23.2499052 L12.6498822,23.2499052 L12.6471943,23.2611114 L12.6650943,23.6906389 L12.6699349,23.7034178 L12.6699349,23.7034178 L12.678386,23.7104931 L12.8793402,23.8032389 C12.8914285,23.8068999 12.9022333,23.8029875 12.9078286,23.7952264 L12.9118235,23.7811639 L12.8776777,23.1665331 C12.8752882,23.1545897 12.8674102,23.1470016 12.8583906,23.1452862 L12.8583906,23.1452862 Z M12.1430473,23.1473072 C12.1332178,23.1423925 12.1221763,23.1452606 12.1156365,23.1525954 L12.1099173,23.1665331 L12.0757714,23.7811639 C12.0751323,23.7926639 12.0828099,23.8018602 12.0926481,23.8045676 L12.108256,23.8032389 L12.3092106,23.7104931 L12.3186497,23.7024347 L12.3186497,23.7024347 L12.3225043,23.6906389 L12.340401,23.2611114 L12.337245,23.2485176 L12.337245,23.2485176 L12.3277531,23.2396597 L12.1430473,23.1473072 Z" id="MingCute" fill-rule="nonzero"> </path> 445 <path d="M15.7072,11.2929 C16.0977,11.6834 16.0977,12.3166 15.7072,12.7071 L10.0503,18.364 C9.65982,18.7545 9.02666,18.7545 8.63613,18.364 C8.24561,17.9734 8.24561,17.3403 8.63613,16.9497 L13.5859,12 L8.63613,7.05025 C8.24561,6.65973 8.24561,6.02656 8.63613,5.63604 C9.02666,5.24551 9.65982,5.24551 10.0503,5.63604 L15.7072,11.2929 Z" id="路径" fill="#1D98A5"> </path> 446 </g> 447 </g> 448 449 </svg> 450 451 </button> 452 </div> 453 } 454 455 456 </div> 457 458 } 459 if ((fieldValueBlocked != null && !fieldValueBlocked.ToString().Contains(customerNumber)) || String.IsNullOrWhiteSpace(customerNumber)) 460 { 461 <div class="stock-state pt-2 mt-auto"> 462 @{ 463 464 /*stock state*/ 465 double MainvariantStock = MainVariant.Stock; 466 string MainsvgInStock = "<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"16\" height=\"16\" fill=\"#44B11A\" class=\"bi bi-check-lg\" viewBox=\"0 0 16 16\"><path d=\"M12.736 3.97a.733.733 0 0 1 1.047 0c.286.289.29.756.01 1.05L7.88 12.01a.733.733 0 0 1-1.065.02L3.217 8.384a.757.757 0 0 1 0-1.06.733.733 0 0 1 1.047 0l3.052 3.093 5.4-6.425z\"/></svg>"; 467 string MainsvgOutStock = "<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"25\" height=\"25\" fill=\"#CA0D0D\" class=\"bi bi-x-lg\" viewBox=\"0 0 16 16\"><path d=\"M4.646 4.646a.5.5 0 0 1 .708 0L8 7.293l2.646-2.647a.5.5 0 0 1 .708.708L8.707 8l2.647 2.646a.5.5 0 0 1-.708.708L8 8.707l-2.646 2.647a.5.5 0 0 1-.708-.708L7.293 8 4.646 5.354a.5.5 0 0 1 0-.708\"/></svg>"; 468 469 string MaininfoStock = "<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"16\" height=\"16\" fill=\"currentColor\" class=\"bi bi-info-circle-fill\" viewBox=\"0 0 16 16\"><path d=\"M8 16A8 8 0 1 0 8 0a8 8 0 0 0 0 16m.93-9.412-1 4.705c-.07.34.029.533.304.533.194 0 .487-.07.686-.246l-.088.416c-.287.346-.92.598-1.465.598-.703 0-1.002-.422-.808-1.319l.738-3.468c.064-.293.006-.399-.287-.47l-.451-.081.082-.381 2.29-.287zM8 5.5a1 1 0 1 1 0-2 1 1 0 0 1 0 2\" /></svg>"; 470 string MainisNew = MainVariant?.ProductFieldValues?.GetProductFieldValue("New")?.Value?.ToString().ToLower() ?? ""; 471 string MainisNewSvg = "<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"16\" height=\"16\" fill=\"#F2C400\" class=\"bi bi-star-fill\" viewBox=\"0 0 16 16\"><path d = \"M3.612 15.443c-.386.198-.824-.149-.746-.592l.83-4.73L.173 6.765c-.329-.314-.158-.888.283-.95l4.898-.696L7.538.792c.197-.39.73-.39.927 0l2.184 4.327 4.898.696c.441.062.612.636.282.95l-3.522 3.356.83 4.73c.078.443-.36.79-.746.592L8 13.187l-4.389 2.256z\" /></svg> "; 472 string MainstockState = ""; 473 string MainIsSale = MainVariant?.ProductFieldValues?.GetProductFieldValue("Sale")?.Value?.ToString().ToLower() ?? ""; 474 string MainIsSaleSvg = "<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"16\" height=\"16\" fill=\"#F03232\" class=\"bi bi-star-fill\" viewBox=\"0 0 16 16\"><path d = \"M3.612 15.443c-.386.198-.824-.149-.746-.592l.83-4.73L.173 6.765c-.329-.314-.158-.888.283-.95l4.898-.696L7.538.792c.197-.39.73-.39.927 0l2.184 4.327 4.898.696c.441.062.612.636.282.95l-3.522 3.356.83 4.73c.078.443-.36.79-.746.592L8 13.187l-4.389 2.256z\" /></svg> "; 475 string MainexpectedDeliveryDate = ""; 476 477 if (DateTime.Compare(MainVariant.ExpectedDelivery, new DateTime(1900, 1, 1)) != 0) //In DW, if the Date is not set, it is defaulted 01-01-1900 and not null.. 478 { 479 MainexpectedDeliveryDate = MainVariant.ExpectedDelivery.ToShortDateString(); 480 } 481 482 string MainexpectedDeliveryDateText = !String.IsNullOrWhiteSpace(MainexpectedDeliveryDate) ? Translate("Verwacht:") + "&nbsp;" + MainexpectedDeliveryDate : ""; 483 484 @if (!(bool?)MainVariant.ProductFieldValues.Where(o => o.ProductField.SystemName == "ProductToBeDiscontinued").SingleOrDefault()?.Value ?? false) 485 { 486 if (MainvariantStock > 0) 487 { 488 if (MainisNew == "true" || MainIsSale == "true") 489 { 490 if (MainIsSale == "true") 491 { 492 MainstockState += MainIsSaleSvg + "&nbsp; &nbsp;" + Translate("Sale!") + "<br/>"; 493 } 494 495 if (MainisNew == "true") 496 { 497 MainstockState += MainisNewSvg + "&nbsp; &nbsp;" + Translate("New!") + "<br/>"; 498 } 499 500 MainstockState += "&nbsp;" + Translate("Nu leverbaar"); 501 } 502 else 503 { 504 MainstockState = MainsvgInStock + "&nbsp; " + Translate("Op voorraad"); 505 506 } 507 } 508 else 509 { 510 MainstockState = MainsvgOutStock + "&nbsp;" + Translate("Geen voorraad") + "<br/>" + MainexpectedDeliveryDateText; 511 512 } 513 } 514 else 515 { 516 517 MainstockState = MainsvgOutStock + "&nbsp;" + Translate("Discontinued:") + "<br/>" + MainvariantStock + "&nbsp;" + @Translate("left in stock"); 518 519 } 520 /*End stock state*/ 521 522 523 @MainstockState 524 525 526 } 527 </div> 528 } 529 else 530 { 531 <div class="stock-state pt-2 mt-auto"> 532 @MainOutStock @Translate("Discontinued") 533 </div> 534 } 535 <div class="custom-price mt-auto"> 536 @{ 537 538 539 540 541 bool isErpConnectionDown = !Dynamicweb.Core.Converter.ToBoolean(Dynamicweb.Context.Current.Items["IsWebServiceConnectionAvailable"]); 542 bool hidePrice = anonymousUsersLimitations.Contains("price") && anonymousUser || Pageview.AreaSettings.GetBoolean("ErpDownHidePrices") && isErpConnectionDown; 543 544 bool productIsDiscontinued = product is object && product.Discontinued; 545 bool doNotShowPriceIfProductIsDiscontinued = Model.Item.GetBoolean("DoNotShowPriceIfProductIsDiscontinued"); 546 var isDiscontinued = productIsDiscontinued && doNotShowPriceIfProductIsDiscontinued; 547 } 548 549 @if (product is object && !hidePrice && !isDiscontinued) 550 { 551 string unitId = !string.IsNullOrEmpty(Dynamicweb.Context.Current.Request.Form.Get("UnitId")) ? Dynamicweb.Context.Current.Request.Form.Get("UnitId") : string.Empty; 552 553 string priceFontSize = Model.Item.GetRawValueString("PriceSize", "fs-4"); 554 string horizontalAlign = Model.Item.GetRawValueString("HorizontalAlignment", ""); 555 string layout = Model.Item.GetRawValueString("Layout", "horizontal"); 556 string textAlign = horizontalAlign == "center" ? "text-center" : string.Empty; 557 textAlign = horizontalAlign == "end" ? "text-end" : textAlign; 558 559 horizontalAlign = horizontalAlign == "center" && layout == "horizontal" ? "justify-content-center" : horizontalAlign; 560 horizontalAlign = horizontalAlign == "end" && layout == "horizontal" ? "justify-content-end" : horizontalAlign; 561 horizontalAlign = horizontalAlign == "center" && layout == "vertical" ? "align-items-center" : horizontalAlign; 562 horizontalAlign = horizontalAlign == "end" && layout == "vertical" ? "align-items-end" : horizontalAlign; 563 564 string flexDirection = layout == "horizontal" ? string.Empty : "flex-column"; 565 string flexGap = layout == "horizontal" ? "gap-3" : string.Empty; 566 string order = layout == "horizontal" ? string.Empty : "order-2"; 567 568 569 string contentPadding = Model.Item.GetRawValueString("ContentPadding", ""); 570 contentPadding = contentPadding == "none" ? "p-0" : contentPadding; 571 contentPadding = contentPadding == "small" ? "p-1 px-md-2 py-md-1" : contentPadding; 572 contentPadding = contentPadding == "large" ? "p-2 px-md-3 py-md-2" : contentPadding; 573 string liveInfoClass = ""; 574 575 576 577 578 579 580 if (isLazyLoadingForProductInfoEnabled) 581 { 582 if (Dynamicweb.Context.Current.Items.Contains("ProductInfoFeed")) 583 { 584 productInfoFeed = Dynamicweb.Context.Current.Items["ProductInfoFeed"]?.ToString(); 585 if (!string.IsNullOrEmpty(productInfoFeed)) 586 { 587 productInfoFeed = $"data-product-info-feed=\"{productInfoFeed}\""; 588 } 589 } 590 liveInfoClass = "js-live-info"; 591 } 592 593 <div class="@textAlign @liveInfoClass item_@Model.Item.SystemName.ToLower()" data-product-id="@product.Id" data-variant-id="@product.VariantId" @productInfoFeed> 594 @if (showInformativePrice && product.PriceInformative.Price != 0) 595 { 596 <div class="opacity-50"> 597 <span>@Translate("RRP") </span> 598 <span class="text-decoration-line-through text-price">@product.PriceInformative.PriceFormatted</span> 599 </div> 600 } 601 <div class="@priceFontSize m-0 d-flex flex-wrap @flexDirection @flexGap @horizontalAlign" style="row-gap: 0 !important" itemprop="offers" itemscope itemtype="https://schema.org/Offer"> 602 <span itemprop="priceCurrency" content="@product.Price.CurrencyCode" class="d-none"></span> 603 604 605 @if (showPricesWithVat == "false" && !neverShowVat) 606 { 607 if (isLazyLoadingForProductInfoEnabled && !Pageview.IsVisualEditorMode) 608 { 609 <span itemprop="price" content="" class="d-none"></span> 610 <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> 611 } 612 else 613 { 614 string beforePrice = !string.IsNullOrEmpty(unitId) ? product.GetPrice(unitId).PriceBeforeDiscount.PriceWithoutVatFormatted : product.PriceBeforeDiscount.PriceWithoutVatFormatted; 615 616 <span itemprop="price" content="@product.Price.PriceWithoutVat.ToString("0.00", System.Globalization.CultureInfo.InvariantCulture)" class="d-none"></span> 617 if (product.Price.Price != product.PriceBeforeDiscount.Price) 618 { 619 <span class="text-decoration-line-through opacity-75 @order">@beforePrice</span> 620 } 621 } 622 } 623 else 624 { 625 if (isLazyLoadingForProductInfoEnabled && !Pageview.IsVisualEditorMode) 626 { 627 <span itemprop="price" content="" class="d-none"></span> 628 <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> 629 } 630 else 631 { 632 string beforePrice = !string.IsNullOrEmpty(unitId) ? product.GetPrice(unitId).PriceBeforeDiscount.PriceFormatted : product.PriceBeforeDiscount.PriceFormatted; 633 634 <span itemprop="price" content="@product.Price.Price.ToString("0.00", System.Globalization.CultureInfo.InvariantCulture)" class="d-none"></span> 635 636 if (product.Price.Price != product.PriceBeforeDiscount.Price) 637 { 638 <span class="text-decoration-line-through opacity-75 @order"> 639 <span class="text-price">@beforePrice</span> 640 </span> 641 } 642 } 643 } 644 645 @if (showPricesWithVat == "false" && !neverShowVat) 646 { 647 if (isLazyLoadingForProductInfoEnabled && !Pageview.IsVisualEditorMode) 648 { 649 <span class="text-price js-text-price"> 650 <span class="spinner-border" role="status"></span> 651 </span> 652 } 653 else 654 { 655 string price = !string.IsNullOrEmpty(unitId) ? product.GetPrice(unitId).Price.PriceWithoutVatFormatted : product.Price.PriceWithoutVatFormatted; 656 657 if (product?.VariantInfo?.VariantInfo != null) 658 { 659 priceMin = product?.VariantInfo?.PriceMin?.PriceWithoutVatFormatted != null ? product.VariantInfo.PriceMin.PriceWithoutVatFormatted : ""; 660 priceMax = product?.VariantInfo?.PriceMax?.PriceWithoutVatFormatted != null ? product.VariantInfo.PriceMax.PriceWithoutVatFormatted : ""; 661 } 662 if (priceMin != priceMax) 663 { 664 price = priceMin + " - " + priceMax; 665 } 666 <span class="@theme @contentPadding"> 667 <span class="text-price">@price</span> 668 </span> 669 } 670 } 671 else 672 { 673 if (isLazyLoadingForProductInfoEnabled && !Pageview.IsVisualEditorMode) 674 { 675 <span class="text-price js-text-price"> 676 <span class="spinner-border" role="status"></span> 677 </span> 678 } 679 else 680 { 681 string price = !string.IsNullOrEmpty(unitId) ? product.GetPrice(unitId).Price.PriceFormatted : product.Price.PriceFormatted; 682 683 if (product?.VariantInfo?.VariantInfo != null) 684 { 685 priceMin = product?.VariantInfo?.PriceMin?.PriceFormatted != null ? product.VariantInfo.PriceMin.PriceFormatted : ""; 686 priceMax = product?.VariantInfo?.PriceMax?.PriceFormatted != null ? product.VariantInfo.PriceMax.PriceFormatted : ""; 687 } 688 if (priceMin != priceMax) 689 { 690 price = priceMin + " - " + priceMax; 691 } 692 <span class="@theme @contentPadding"> 693 <span class="text-price">@price</span> 694 </span> 695 } 696 } 697 698 @* Stock state for Schema.org, start *@ 699 @{ 700 Uri url = Dynamicweb.Context.Current.Request.Url; 701 } 702 703 <link itemprop="url" href="@url"> 704 705 @{ 706 bool IsNeverOutOfStock = product.NeverOutOfstock; 707 } 708 709 @if (IsNeverOutOfStock) 710 { 711 <span itemprop="availability" class="d-none">@Translate("Available in stock")</span> 712 } 713 else 714 { 715 if (product.StockLevel > 0) 716 { 717 <span itemprop="availability" class="d-none">InStock</span> 718 } 719 else 720 { 721 <span itemprop="availability" class="d-none">OutOfStock</span> 722 } 723 } 724 @* Stock state for Schema.org, stop *@ 725 726 </div> 727 728 @if (showPricesWithVat == "false" && !neverShowVat) 729 { 730 if (isLazyLoadingForProductInfoEnabled && !Pageview.IsVisualEditorMode) 731 { 732 <small class="opacity-85 fst-normal js-text-price-with-vat d-none" data-suffix="@Translate("Incl. VAT")"></small> 733 } 734 else 735 { 736 string price = !string.IsNullOrEmpty(unitId) ? product.GetPrice(unitId).Price.PriceWithVatFormatted : product.Price.PriceWithVatFormatted; 737 738 if (product?.VariantInfo?.VariantInfo != null) 739 { 740 priceMin = product?.VariantInfo?.PriceMin?.PriceWithVatFormatted != null ? product.VariantInfo.PriceMin.PriceWithVatFormatted : ""; 741 priceMax = product?.VariantInfo?.PriceMax?.PriceWithVatFormatted != null ? product.VariantInfo.PriceMax.PriceWithVatFormatted : ""; 742 } 743 if (priceMin != priceMax) 744 { 745 price = priceMin + " - " + priceMax; 746 } 747 <!-- <small class="opacity-85 fst-normal">@price @Translate("Incl. VAT")</small> --> 748 } 749 } 750 </div> 751 } 752 else if (Pageview.IsVisualEditorMode) 753 { 754 <div class="alert alert-dark m-0" role="alert"> 755 <span>@Translate("No products available")</span> 756 </div> 757 } 758 759 </div> 760 } 761 } 762
Tischlampe Arch
Error executing template "Designs/Swift/Paragraph/CustomProductSlider.cshtml"
System.NullReferenceException: Object reference not set to an instance of an object.
   at CompiledRazorTemplates.Dynamic.RazorEngine_3562354021b44d5c892fe73dc2806e4f.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 Dynamicweb.Ecommerce.ProductCatalog 3 @using Dynamicweb.Ecommerce.CustomerExperienceCenter.Favorites 4 @using Dynamicweb.Files 5 @using System.IO 6 @using System.Net 7 @using Dynamicweb.Security.UserManagement 8 9 10 @{ 11 ProductViewModel product = null; 12 if (Dynamicweb.Context.Current.Items.Contains("ProductDetails")) 13 { 14 product = (ProductViewModel)Dynamicweb.Context.Current.Items["ProductDetails"]; 15 } 16 else if (Pageview.Page.Item["DummyProduct"] != null && Pageview.IsVisualEditorMode) 17 { 18 var pageViewModel = Dynamicweb.Frontend.ContentViewModelFactory.CreatePageInfoViewModel(Pageview.Page); 19 ProductListViewModel productList = pageViewModel.Item.GetValue("DummyProduct") != null ? pageViewModel.Item.GetValue("DummyProduct") as ProductListViewModel : new ProductListViewModel(); 20 21 if (productList?.Products is object) 22 { 23 product = productList.Products[0]; 24 } 25 } 26 } 27 28 @{ 29 var currentUser = Pageview?.User; 30 var customerNumber = !string.IsNullOrEmpty(currentUser?.CustomerNumber) 31 ? currentUser.CustomerNumber 32 : ""; 33 } 34 @if (product is object) 35 { 36 string imagePath = product?.DefaultImage?.Value ?? ""; 37 string imagePathUrlEncoded = Dynamicweb.Context.Current.Server.UrlEncode(imagePath); 38 39 string ratio = Model.Item.GetRawValueString("ImageAspectRatio", ""); 40 ratio = ratio != "0" ? ratio : ""; 41 string ratioCssClass = ratio != "" ? " ratio" : ""; 42 string ratioVariable = ratio != "" ? "--bs-aspect-ratio: " + ratio + ";" : ""; 43 44 string width = Model.Item.GetRawValueString("Width", "auto"); 45 int smallImageSize = 640; 46 int largeImageSize = width == "auto" ? 1280 : Convert.ToInt32(width); 47 48 string ImageObjectFit = Model.Item.GetRawValueString("ImageObjectFit", "contain"); 49 50 string imagePathXs = "/Admin/Public/GetImage.ashx?width=" + smallImageSize + "&image=" + imagePathUrlEncoded + "&format=webp"; 51 string imagePathS = "/Admin/Public/GetImage.ashx?width=" + largeImageSize + "&image=" + imagePathUrlEncoded + "&format=webp"; 52 string imagePathFallBack = "/Admin/Public/GetImage.ashx?width=" + largeImageSize + "&image=" + imagePathUrlEncoded + "&format=webp"; 53 54 var badgeParms = new Dictionary<string, object>(); 55 badgeParms.Add("size", "h7"); 56 badgeParms.Add("saleBadgeType", Model.Item.GetRawValue("SaleBadgeType")); 57 badgeParms.Add("saleBadgeCssClassName", Model.Item.GetRawValue("SaleBadgeDesign")); 58 badgeParms.Add("newBadgeCssClassName", Model.Item.GetRawValue("NewBadgeDesign")); 59 badgeParms.Add("newPublicationDays", Model.Item.GetInt32("NewPublicationDays")); 60 badgeParms.Add("campaignBadgesValues", Model.Item.GetList("CampaignBadges")?.GetRawValue().OfType<string>().ToList()); 61 62 string badgeSize = Model.Item.GetRawValueString("BadgeSize", "fs-2"); 63 bool saleBadgeEnabled = !string.IsNullOrWhiteSpace(Model.Item.GetRawValueString("SaleBadgeDesign")) && Model.Item.GetRawValueString("SaleBadgeDesign") != "none" ? true : false; 64 bool newBadgeEnabled = !string.IsNullOrWhiteSpace(Model.Item.GetRawValueString("NewBadgeDesign")) && Model.Item.GetRawValueString("NewBadgeDesign") != "none" ? true : false; 65 66 /*Custom badge*/ 67 var productService = new Dynamicweb.Ecommerce.Products.ProductService(); 68 var currency = Dynamicweb.Ecommerce.Common.Context.Currency.Code; 69 var formatProvider = new System.Globalization.NumberFormatInfo(); 70 formatProvider.NumberDecimalSeparator = "."; 71 formatProvider.NumberGroupSeparator = ","; 72 var MainVariant = productService.GetProductById(product.Id, product.VariantId, false); 73 var fieldValueBlocked = MainVariant?.ProductFieldValues?.GetProductFieldValue("BlockedCustomerList")?.Value; 74 75 76 string isNewProduct = MainVariant?.ProductFieldValues?.GetProductFieldValue("New")?.Value?.ToString().ToLower() ?? ""; 77 string MainisSale = MainVariant?.ProductFieldValues?.GetProductFieldValue("Sale")?.Value?.ToString().ToLower() ?? ""; 78 bool showNewBadge = isNewProduct == "true" ? true : false; 79 bool showSaleBadge = MainisSale == "true" ? true : false; 80 string showNewSaleBadge = "d-none"; 81 if (showSaleBadge) 82 { 83 badgeParms.Add("isSale", "true"); 84 85 } 86 else 87 { 88 badgeParms.Add("isSale", "false"); 89 } 90 if (showNewBadge) 91 { 92 badgeParms.Add("isNew", "true"); 93 } 94 else 95 { 96 badgeParms.Add("isNew", "false"); 97 } 98 /*End Custom badge*/ 99 if (showSaleBadge || showNewBadge) 100 { 101 showNewSaleBadge = ""; 102 } 103 DateTime createdDate = product.Created.Value; 104 bool showBadges = saleBadgeEnabled && product.Discount.Price != 0 ? true : false; 105 106 bool showFavoritesSelector = !string.IsNullOrEmpty(Model.Item.GetString("ShowAddToFavorites")) ? Model.Item.GetBoolean("ShowAddToFavorites") : false; 107 string anonymousUsersLimitations = Pageview.AreaSettings.GetRawValueString("AnonymousUsers", ""); 108 bool anonymousUser = Pageview.User == null; 109 110 var favoriteParameters = new Dictionary<string, object>(); 111 if (!anonymousUser && showFavoritesSelector) 112 { 113 int defaultFavoriteListId = 0; 114 115 IEnumerable<FavoriteList> favoreiteLists = Pageview.User.GetFavoriteLists(); 116 if (favoreiteLists.Count() == 1) 117 { 118 foreach (FavoriteList list in favoreiteLists) 119 { 120 defaultFavoriteListId = list.ListId; 121 } 122 } 123 124 favoriteParameters.Add("ListId", defaultFavoriteListId); 125 } 126 127 MediaViewModel alternativeImage = new MediaViewModel(); 128 if (Model.Item.GetBoolean("ShowAlternativeImageOnHover")) 129 { 130 var selectedImageCategories = Model.Item.GetList("GetAlternativeImageFrom")?.GetRawValue().OfType<string>().ToList(); 131 List<MediaViewModel> allAssetsImages = product.AssetCategories.Where(x => selectedImageCategories.Contains(x.SystemName)).SelectMany(x => x.Assets).ToList(); 132 allAssetsImages.RemoveAll(x => x.Value == product.DefaultImage.Value); 133 alternativeImage = allAssetsImages.FirstOrDefault(); 134 } 135 136 string altImagePathXs = string.Empty; 137 string altImagePathS = string.Empty; 138 139 if (!string.IsNullOrEmpty(alternativeImage?.Value)) 140 { 141 altImagePathXs = "/Admin/Public/GetImage.ashx?width=" + smallImageSize + "&image=" + Dynamicweb.Context.Current.Server.UrlEncode(alternativeImage.Value) + "&format=webp"; 142 altImagePathS = "/Admin/Public/GetImage.ashx?width=" + largeImageSize + "&image=" + Dynamicweb.Context.Current.Server.UrlEncode(alternativeImage.Value) + "&format=webp"; 143 } 144 145 @* Theme settings *@ 146 string theme = !string.IsNullOrWhiteSpace(Model.Item.GetRawValueString("Theme")) ? " theme " + Model.Item.GetRawValueString("Theme").Replace(" ", "").Trim().ToLower() : ""; 147 string themeBorder = !string.IsNullOrWhiteSpace(theme) ? "border: 1px solid rgba(0,0,0,0)" : ""; 148 string themePadding = !string.IsNullOrWhiteSpace(theme) ? "p-2 p-lg-3" : ""; 149 150 string imageId = "ProductImage_" + product.Id; 151 152 153 154 string fullWidth = width == "auto" ? "w-100" : ""; 155 string customWidth = width != "auto" ? "style=\"width: " + width + "px\"" : "style=\"min-width: 60px\""; 156 157 string altImageZindex = Model.Item.GetBoolean("ShowAlternativeImageOnHover") && !string.IsNullOrEmpty(alternativeImage?.Value) ? " z-index: 1" : string.Empty; 158 string groupid = !string.IsNullOrEmpty(Dynamicweb.Context.Current.Request.QueryString.Get("GroupID")) ? Dynamicweb.Context.Current.Request.QueryString.Get("GroupID"):"" ; 159 string link = product.GetProductLink(GetPageIdByNavigationTag("Shop"), false); 160 var productVariantGroups = product.VariantGroups(); 161 string MainOutStock = "<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"25\" height=\"25\" fill=\"#CA0D0D\" class=\"bi bi-x-lg\" viewBox=\"0 0 16 16\"><path d=\"M4.646 4.646a.5.5 0 0 1 .708 0L8 7.293l2.646-2.647a.5.5 0 0 1 .708.708L8.707 8l2.647 2.646a.5.5 0 0 1-.708.708L8 8.707l-2.646 2.647a.5.5 0 0 1-.708-.708L7.293 8 4.646 5.354a.5.5 0 0 1 0-.708\"/></svg>"; 162 163 @if (!string.IsNullOrEmpty(imagePath)) 164 { 165 <div class="@fullWidth @theme position-relative item_@Model.Item.SystemName.ToLower() main-image-container" @customWidth> 166 <div class="" style="@(ratioVariable)@(altImageZindex)"> 167 <div class="d-flex justify-content-center align-items-center"> 168 <a class="main-link-link" href="@link"> 169 @if (imagePath.StartsWith("/Files/", StringComparison.OrdinalIgnoreCase)) 170 { 171 <img id="@imageId" 172 srcset=" 173 @imagePathXs @(smallImageSize)w, 174 @imagePathS @(largeImageSize)w" 175 sizes="(max-width: 992px) 50vw, 25vw" 176 src="@imagePathFallBack" 177 loading="lazy" 178 decoding="async" 179 class="h-100 w-100 @themePadding main-image" 180 style="object-fit: @ImageObjectFit; @themeBorder " 181 alt="@product.Name" 182 itemprop="image"> 183 } 184 else 185 { 186 <img src="@product.DefaultImage.Value" 187 loading="lazy" 188 class="h-100 w-100 @themePadding main-image" 189 style="object-fit: contain; @themeBorder" 190 alt="@product.Name" 191 itemprop="image"> 192 } 193 </a> 194 </div> 195 </div> 196 197 <div class="position-absolute top-0 left-0 p-2 pb-0 custom-badge-product-list @showNewSaleBadge"> 198 @{ 199 @RenderPartial("Components/Custom_EcommerceBadge.cshtml", product, badgeParms) 200 } 201 </div> 202 203 204 </div> 205 } 206 207 <div class="product-info h-100"> 208 <div class="fs-7 pt-1 opacity-85 start item_@Model.Item.SystemName.ToLower() product-number" itemprop="sku">@product.Id / @product.VariantId - @product.VariantName</div> 209 <div class="py-2" data-col-size="12"> 210 <h2 class="h6 start m-0 item_swift_productheader product-name" itemprop="name"><b>@product.Name</b></h2> 211 </div> 212 </div> 213 var sliderId = $"thumb-scroll-{product.Id}"; 214 if (productVariantGroups.Any() && product?.VariantInfo?.VariantInfo != null) 215 216 { 217 @using Dynamicweb.Ecommerce.Prices 218 @{ 219 string[] variantId = product.VariantId.Split('.'); 220 string showPricesWithVat = Pageview.Area.EcomPricesWithVat.ToLower(); 221 bool neverShowVat = string.IsNullOrEmpty(showPricesWithVat); 222 bool showInformativePrice = Model.Item.GetBoolean("ShowInformativePrice"); 223 string productInfoFeed = ""; 224 bool isLazyLoadingForProductInfoEnabled = Dynamicweb.Core.Converter.ToBoolean(Dynamicweb.Context.Current.Items["IsLazyLoadingForProductInfoEnabled"]); 225 if (isLazyLoadingForProductInfoEnabled) 226 { 227 if (Dynamicweb.Context.Current.Items.Contains("ProductInfoFeed")) 228 { 229 productInfoFeed = Dynamicweb.Context.Current.Items["ProductInfoFeed"]?.ToString(); 230 if (!string.IsNullOrEmpty(productInfoFeed)) 231 { 232 productInfoFeed =productInfoFeed; 233 } 234 } 235 236 } 237 string priceMin = ""; 238 string priceMax = ""; 239 int groupNumber = 1; 240 241 242 243 244 string baseUrl = $"Default.aspx?ID={GetPageIdByNavigationTag("Shop")}&GroupID={product.PrimaryOrDefaultGroup.Id}&ProductID={product.Id}"; 245 if (!string.IsNullOrEmpty(baseUrl)) 246 { 247 baseUrl = $"/{baseUrl.TrimStart('/')}"; 248 } 249 string variantUrl = string.Empty; 250 251 252 Dictionary<string, string> 253 variantImages = new Dictionary<string, string> 254 (); 255 <div class="last-row mt-auto"> 256 257 @foreach (var variantGroup in productVariantGroups) 258 { 259 <div class="thumbnail-wrapper"> 260 <button class="thumb-nav prev" onclick="scrollThumbs('@sliderId', -1)"> 261 <svg width="20px" height="20px" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" fill="#1D98A5"> 262 263 <g stroke="none" stroke-width="1" fill="none" fill-rule="evenodd"> 264 <g transform="translate(-336.000000, 0.000000)"> 265 <g id="left_line" transform="translate(336.000000, 0.000000)"> 266 <path d="M24,0 L24,24 L0,24 L0,0 L24,0 Z M12.5934901,23.257841 L12.5819402,23.2595131 L12.5108777,23.2950439 L12.4918791,23.2987469 L12.4918791,23.2987469 L12.4767152,23.2950439 L12.4056548,23.2595131 C12.3958229,23.2563662 12.3870493,23.2590235 12.3821421,23.2649074 L12.3780323,23.275831 L12.360941,23.7031097 L12.3658947,23.7234994 L12.3769048,23.7357139 L12.4804777,23.8096931 L12.4953491,23.8136134 L12.4953491,23.8136134 L12.5071152,23.8096931 L12.6106902,23.7357139 L12.6232938,23.7196733 L12.6232938,23.7196733 L12.6266527,23.7031097 L12.609561,23.275831 C12.6075724,23.2657013 12.6010112,23.2592993 12.5934901,23.257841 L12.5934901,23.257841 Z M12.8583906,23.1452862 L12.8445485,23.1473072 L12.6598443,23.2396597 L12.6498822,23.2499052 L12.6498822,23.2499052 L12.6471943,23.2611114 L12.6650943,23.6906389 L12.6699349,23.7034178 L12.6699349,23.7034178 L12.678386,23.7104931 L12.8793402,23.8032389 C12.8914285,23.8068999 12.9022333,23.8029875 12.9078286,23.7952264 L12.9118235,23.7811639 L12.8776777,23.1665331 C12.8752882,23.1545897 12.8674102,23.1470016 12.8583906,23.1452862 L12.8583906,23.1452862 Z M12.1430473,23.1473072 C12.1332178,23.1423925 12.1221763,23.1452606 12.1156365,23.1525954 L12.1099173,23.1665331 L12.0757714,23.7811639 C12.0751323,23.7926639 12.0828099,23.8018602 12.0926481,23.8045676 L12.108256,23.8032389 L12.3092106,23.7104931 L12.3186497,23.7024347 L12.3186497,23.7024347 L12.3225043,23.6906389 L12.340401,23.2611114 L12.337245,23.2485176 L12.337245,23.2485176 L12.3277531,23.2396597 L12.1430473,23.1473072 Z" id="MingCute" fill-rule="nonzero"> </path> 267 <path d="M8.29292,12.7071 C7.9024,12.3166 7.9024,11.6834 8.29292,11.2929 L13.9498,5.63604 C14.3403,5.24551 14.9735,5.24551 15.364,5.63604 C15.7545,6.02656 15.7545,6.65973 15.364,7.05025 L10.4142,12 L15.364,16.9497 C15.7545,17.3403 15.7545,17.9734 15.364,18.364 C14.9735,18.7545 14.3403,18.7545 13.9498,18.364 L8.29292,12.7071 Z" id="路径" fill="#1D98A5"> </path> 268 </g> 269 </g> 270 </g> 271 </svg> 272 273 </button> 274 <div class="thumbnail-scroll" id="@sliderId"> 275 @{ 276 VariantGroupViewModel group = variantGroup; 277 foreach (var option in group.Options.OrderBy(o => o.Id)) 278 { 279 var productVariant = productService.GetProductById(product.Id, option.Id, false); 280 281 var productSelection = new PriceProductSelection(productVariant, null, 0); 282 283 var currencyCode = string.IsNullOrWhiteSpace(Pageview.User.Currency) ? Pageview.Area.EcomCurrencyId : Pageview.User.Currency; 284 var countryCode = string.IsNullOrWhiteSpace(Pageview.User.CountryCode) ? Pageview.Area.EcomCountryCode : Pageview.User.CountryCode; 285 286 var userCurrency = Dynamicweb.Ecommerce.Services.Currencies.GetCurrency(currencyCode); 287 var userCountry = Dynamicweb.Ecommerce.Services.Countries.GetCountry(countryCode); 288 289 var priceContext = new PriceContext(userCurrency, userCountry, null, Pageview.User, false, null); 290 var productPrice = Dynamicweb.Ecommerce.Services.Prices.FindPrices(priceContext, productSelection, false); 291 292 //throw new Exception(System.Text.Json.JsonSerializer.Serialize(productPrice)); 293 294 var fieldValue = productVariant?.ProductFieldValues?.GetProductFieldValue("BlockedCustomerList")?.Value; 295 296 if ((fieldValue != null && !fieldValue.ToString().Contains(customerNumber)) || String.IsNullOrWhiteSpace(customerNumber)) 297 { 298 299 300 string active = variantId != null && variantId.Contains(option.Id) ? "active" : string.Empty; 301 string buttonId = $"{product.Id}_{option.Id}_{Pageview.CurrentParagraph.ID}"; 302 string contrastColor = string.Empty; 303 304 string searchKey = $"{product.Id}_{option.Id}_"; 305 /*Images*/ 306 var imagePathVariant = option.Image?.Value ?? ""; 307 308 309 var folderPath = Path.GetDirectoryName(imagePathVariant); 310 311 string physicalFolderPath = Dynamicweb.Context.Current.Server.MapPath(folderPath); 312 313 string lastImage = null; 314 315 if (Directory.Exists(physicalFolderPath)) 316 { 317 318 var fileWith15 = Directory.GetFiles(physicalFolderPath) 319 .FirstOrDefault(f => Path.GetFileName(f).Contains($"{product.Id}_{option.Id}_9")); 320 321 if (fileWith15 != null) 322 { 323 lastImage = fileWith15; 324 } 325 else 326 { 327 var files = Directory.GetFiles(physicalFolderPath) 328 .Where(f => Path.GetFileName(f).StartsWith($"{product.Id}_{option.Id}_")) 329 .OrderByDescending(f => 330 { 331 var filename = Path.GetFileNameWithoutExtension(f); 332 var match = System.Text.RegularExpressions.Regex.Match(filename, @"_(\d+)$"); 333 if (match.Success && int.TryParse(match.Groups[1].Value, out int index)) 334 { 335 return index; 336 } 337 return 0; 338 }) 339 .ToList(); 340 341 if (files.Any()) 342 { 343 lastImage = files.First(); 344 } 345 } 346 } 347 348 var lastImageUrl = lastImage != null ? lastImage : "/Files/Images/zijlstra/Afbeeldingen_overig/Coming_Soon.jpg"; 349 int index = lastImageUrl.IndexOf("Files"); 350 string relativePath = index >= 0 ? lastImageUrl.Substring(index).Replace("\\", "/") : lastImageUrl.Replace("\\", "/"); 351 lastImageUrl = "/" + relativePath; 352 lastImageUrl = Dynamicweb.Context.Current.Server.UrlEncode(lastImageUrl); 353 var variantImg = option.Image is object ? Dynamicweb.Context.Current.Server.UrlEncode(option.Image.Value) : null; 354 var variantLink = "/Default.aspx?ID=" + GetPageIdByNavigationTag("Shop") + "&GroupID=" + product.PrimaryOrDefaultGroup.Id + "&ProductID=" + product.Id + "&VariantID=" + option.Id; 355 356 string variantImage = string.Empty; 357 variantImages.TryGetValue(option.Id, out variantImage); 358 /*End Images*/ 359 360 /*stock state*/ 361 double variantStock = productVariant.Stock; 362 string svgInStock = "<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"16\" height=\"16\" fill=\"#44B11A\" class=\"bi bi-check-lg\" viewBox=\"0 0 16 16\"><path d=\"M12.736 3.97a.733.733 0 0 1 1.047 0c.286.289.29.756.01 1.05L7.88 12.01a.733.733 0 0 1-1.065.02L3.217 8.384a.757.757 0 0 1 0-1.06.733.733 0 0 1 1.047 0l3.052 3.093 5.4-6.425z\"/></svg>"; 363 string svgOutStock = "<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"25\" height=\"25\" fill=\"#CA0D0D\" class=\"bi bi-x-lg\" viewBox=\"0 0 16 16\"><path d=\"M4.646 4.646a.5.5 0 0 1 .708 0L8 7.293l2.646-2.647a.5.5 0 0 1 .708.708L8.707 8l2.647 2.646a.5.5 0 0 1-.708.708L8 8.707l-2.646 2.647a.5.5 0 0 1-.708-.708L7.293 8 4.646 5.354a.5.5 0 0 1 0-.708\"/></svg>"; 364 365 string infoStock = "<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"16\" height=\"16\" fill=\"currentColor\" class=\"bi bi-info-circle-fill\" viewBox=\"0 0 16 16\"><path d=\"M8 16A8 8 0 1 0 8 0a8 8 0 0 0 0 16m.93-9.412-1 4.705c-.07.34.029.533.304.533.194 0 .487-.07.686-.246l-.088.416c-.287.346-.92.598-1.465.598-.703 0-1.002-.422-.808-1.319l.738-3.468c.064-.293.006-.399-.287-.47l-.451-.081.082-.381 2.29-.287zM8 5.5a1 1 0 1 1 0-2 1 1 0 0 1 0 2\" /></svg>"; 366 string isNew = productVariant?.ProductFieldValues?.GetProductFieldValue("New")?.Value?.ToString().ToLower() ?? ""; 367 string isNewSvg = "<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"16\" height=\"16\" fill=\"#F2C400\" class=\"bi bi-star-fill\" viewBox=\"0 0 16 16\"><path d = \"M3.612 15.443c-.386.198-.824-.149-.746-.592l.83-4.73L.173 6.765c-.329-.314-.158-.888.283-.95l4.898-.696L7.538.792c.197-.39.73-.39.927 0l2.184 4.327 4.898.696c.441.062.612.636.282.95l-3.522 3.356.83 4.73c.078.443-.36.79-.746.592L8 13.187l-4.389 2.256z\" /></svg> "; 368 string stockState = ""; 369 370 string isSale = productVariant?.ProductFieldValues?.GetProductFieldValue("Sale")?.Value?.ToString().ToLower() ?? ""; 371 string isSaleSvg = "<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"16\" height=\"16\" fill=\"#F03232\" class=\"bi bi-star-fill\" viewBox=\"0 0 16 16\"><path d = \"M3.612 15.443c-.386.198-.824-.149-.746-.592l.83-4.73L.173 6.765c-.329-.314-.158-.888.283-.95l4.898-.696L7.538.792c.197-.39.73-.39.927 0l2.184 4.327 4.898.696c.441.062.612.636.282.95l-3.522 3.356.83 4.73c.078.443-.36.79-.746.592L8 13.187l-4.389 2.256z\" /></svg> "; 372 373 string expectedDeliveryDate = ""; 374 375 if (DateTime.Compare(productVariant.ExpectedDelivery, new DateTime(1900, 1, 1)) != 0) //In DW, if the Date is not set, it is defaulted 01-01-1900 and not null.. 376 { 377 expectedDeliveryDate = productVariant.ExpectedDelivery.ToShortDateString(); 378 } 379 380 string expectedDeliveryDateText = !String.IsNullOrWhiteSpace(expectedDeliveryDate) ? Translate("Verwacht:") + "&nbsp;" + expectedDeliveryDate : ""; 381 382 @if (!(bool?)productVariant.ProductFieldValues.Where(o => o.ProductField.SystemName == "ProductToBeDiscontinued").SingleOrDefault()?.Value ?? false) 383 { 384 if (variantStock > 0) 385 { 386 if (isNew == "true" || isSale == "true") 387 { 388 if (isSale == "true") 389 { 390 stockState += isSaleSvg + "&nbsp; &nbsp;" + Translate("Sale!") + "<br/>"; 391 } 392 393 if (isNew == "true") 394 { 395 stockState += isNewSvg + "&nbsp; &nbsp;" + Translate("New!") + "<br/>"; 396 } 397 398 stockState += "&nbsp;" + Translate("Nu leverbaar"); 399 } 400 else 401 { 402 stockState = svgInStock + "&nbsp; " + Translate("Op voorraad"); 403 404 } 405 } 406 else 407 { 408 stockState = svgOutStock + "&nbsp;" + Translate("Geen voorraad") + "<br/>" + expectedDeliveryDateText; 409 410 } 411 } 412 else 413 { 414 415 stockState = svgOutStock + "&nbsp;" + Translate("Discontinued:") + "<br/>" + variantStock + "&nbsp;" + @Translate("left in stock"); 416 417 } 418 /*End stock state*/ 419 /*Price variants*/ 420 double price = productVariant.DefaultPrice; 421 double cost = productVariant.Cost; 422 423 string priceFormated = Dynamicweb.Ecommerce.Services.Currencies.Format(Dynamicweb.Ecommerce.Services.Currencies.GetCurrency(currency), Convert.ToDouble(productPrice.ToList()[0].Amount, formatProvider)); 424 //string priceFormated = Dynamicweb.Ecommerce.Services.Currencies.Format(Dynamicweb.Ecommerce.Services.Currencies.GetCurrency(currency), Convert.ToDouble(price, formatProvider)); 425 426 427 428 /*End Price variants*/ 429 430 <img class="theme thumbnail" data-stockstate="@WebUtility.HtmlEncode(stockState)" src="/Admin/Public/GetImage.ashx?image=@(lastImageUrl)&width=64&format=webp" onclick="selectVariant('@(product.Id)','/Admin/Public/GetImage.ashx?image=@(variantImg)&format=webp','@variantLink','@product.Id','@option.Id','@option.Name',this.dataset.stockstate,'@isNew','@isSale','@priceFormated','@cost')" /> 431 432 433 } 434 } 435 436 } 437 </div> 438 <button class="thumb-nav next" onclick="scrollThumbs('@sliderId', 1)"> 439 <svg width="20px" height="20px" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" fill="#1D98A5"> 440 441 <g stroke="none" stroke-width="1" fill="none" fill-rule="evenodd"> 442 <g transform="translate(-384.000000, 0.000000)"> 443 <g id="right_line" transform="translate(384.000000, 0.000000)"> 444 <path d="M24,0 L24,24 L0,24 L0,0 L24,0 Z M12.5934901,23.257841 L12.5819402,23.2595131 L12.5108777,23.2950439 L12.4918791,23.2987469 L12.4918791,23.2987469 L12.4767152,23.2950439 L12.4056548,23.2595131 C12.3958229,23.2563662 12.3870493,23.2590235 12.3821421,23.2649074 L12.3780323,23.275831 L12.360941,23.7031097 L12.3658947,23.7234994 L12.3769048,23.7357139 L12.4804777,23.8096931 L12.4953491,23.8136134 L12.4953491,23.8136134 L12.5071152,23.8096931 L12.6106902,23.7357139 L12.6232938,23.7196733 L12.6232938,23.7196733 L12.6266527,23.7031097 L12.609561,23.275831 C12.6075724,23.2657013 12.6010112,23.2592993 12.5934901,23.257841 L12.5934901,23.257841 Z M12.8583906,23.1452862 L12.8445485,23.1473072 L12.6598443,23.2396597 L12.6498822,23.2499052 L12.6498822,23.2499052 L12.6471943,23.2611114 L12.6650943,23.6906389 L12.6699349,23.7034178 L12.6699349,23.7034178 L12.678386,23.7104931 L12.8793402,23.8032389 C12.8914285,23.8068999 12.9022333,23.8029875 12.9078286,23.7952264 L12.9118235,23.7811639 L12.8776777,23.1665331 C12.8752882,23.1545897 12.8674102,23.1470016 12.8583906,23.1452862 L12.8583906,23.1452862 Z M12.1430473,23.1473072 C12.1332178,23.1423925 12.1221763,23.1452606 12.1156365,23.1525954 L12.1099173,23.1665331 L12.0757714,23.7811639 C12.0751323,23.7926639 12.0828099,23.8018602 12.0926481,23.8045676 L12.108256,23.8032389 L12.3092106,23.7104931 L12.3186497,23.7024347 L12.3186497,23.7024347 L12.3225043,23.6906389 L12.340401,23.2611114 L12.337245,23.2485176 L12.337245,23.2485176 L12.3277531,23.2396597 L12.1430473,23.1473072 Z" id="MingCute" fill-rule="nonzero"> </path> 445 <path d="M15.7072,11.2929 C16.0977,11.6834 16.0977,12.3166 15.7072,12.7071 L10.0503,18.364 C9.65982,18.7545 9.02666,18.7545 8.63613,18.364 C8.24561,17.9734 8.24561,17.3403 8.63613,16.9497 L13.5859,12 L8.63613,7.05025 C8.24561,6.65973 8.24561,6.02656 8.63613,5.63604 C9.02666,5.24551 9.65982,5.24551 10.0503,5.63604 L15.7072,11.2929 Z" id="路径" fill="#1D98A5"> </path> 446 </g> 447 </g> 448 449 </svg> 450 451 </button> 452 </div> 453 } 454 455 456 </div> 457 458 } 459 if ((fieldValueBlocked != null && !fieldValueBlocked.ToString().Contains(customerNumber)) || String.IsNullOrWhiteSpace(customerNumber)) 460 { 461 <div class="stock-state pt-2 mt-auto"> 462 @{ 463 464 /*stock state*/ 465 double MainvariantStock = MainVariant.Stock; 466 string MainsvgInStock = "<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"16\" height=\"16\" fill=\"#44B11A\" class=\"bi bi-check-lg\" viewBox=\"0 0 16 16\"><path d=\"M12.736 3.97a.733.733 0 0 1 1.047 0c.286.289.29.756.01 1.05L7.88 12.01a.733.733 0 0 1-1.065.02L3.217 8.384a.757.757 0 0 1 0-1.06.733.733 0 0 1 1.047 0l3.052 3.093 5.4-6.425z\"/></svg>"; 467 string MainsvgOutStock = "<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"25\" height=\"25\" fill=\"#CA0D0D\" class=\"bi bi-x-lg\" viewBox=\"0 0 16 16\"><path d=\"M4.646 4.646a.5.5 0 0 1 .708 0L8 7.293l2.646-2.647a.5.5 0 0 1 .708.708L8.707 8l2.647 2.646a.5.5 0 0 1-.708.708L8 8.707l-2.646 2.647a.5.5 0 0 1-.708-.708L7.293 8 4.646 5.354a.5.5 0 0 1 0-.708\"/></svg>"; 468 469 string MaininfoStock = "<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"16\" height=\"16\" fill=\"currentColor\" class=\"bi bi-info-circle-fill\" viewBox=\"0 0 16 16\"><path d=\"M8 16A8 8 0 1 0 8 0a8 8 0 0 0 0 16m.93-9.412-1 4.705c-.07.34.029.533.304.533.194 0 .487-.07.686-.246l-.088.416c-.287.346-.92.598-1.465.598-.703 0-1.002-.422-.808-1.319l.738-3.468c.064-.293.006-.399-.287-.47l-.451-.081.082-.381 2.29-.287zM8 5.5a1 1 0 1 1 0-2 1 1 0 0 1 0 2\" /></svg>"; 470 string MainisNew = MainVariant?.ProductFieldValues?.GetProductFieldValue("New")?.Value?.ToString().ToLower() ?? ""; 471 string MainisNewSvg = "<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"16\" height=\"16\" fill=\"#F2C400\" class=\"bi bi-star-fill\" viewBox=\"0 0 16 16\"><path d = \"M3.612 15.443c-.386.198-.824-.149-.746-.592l.83-4.73L.173 6.765c-.329-.314-.158-.888.283-.95l4.898-.696L7.538.792c.197-.39.73-.39.927 0l2.184 4.327 4.898.696c.441.062.612.636.282.95l-3.522 3.356.83 4.73c.078.443-.36.79-.746.592L8 13.187l-4.389 2.256z\" /></svg> "; 472 string MainstockState = ""; 473 string MainIsSale = MainVariant?.ProductFieldValues?.GetProductFieldValue("Sale")?.Value?.ToString().ToLower() ?? ""; 474 string MainIsSaleSvg = "<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"16\" height=\"16\" fill=\"#F03232\" class=\"bi bi-star-fill\" viewBox=\"0 0 16 16\"><path d = \"M3.612 15.443c-.386.198-.824-.149-.746-.592l.83-4.73L.173 6.765c-.329-.314-.158-.888.283-.95l4.898-.696L7.538.792c.197-.39.73-.39.927 0l2.184 4.327 4.898.696c.441.062.612.636.282.95l-3.522 3.356.83 4.73c.078.443-.36.79-.746.592L8 13.187l-4.389 2.256z\" /></svg> "; 475 string MainexpectedDeliveryDate = ""; 476 477 if (DateTime.Compare(MainVariant.ExpectedDelivery, new DateTime(1900, 1, 1)) != 0) //In DW, if the Date is not set, it is defaulted 01-01-1900 and not null.. 478 { 479 MainexpectedDeliveryDate = MainVariant.ExpectedDelivery.ToShortDateString(); 480 } 481 482 string MainexpectedDeliveryDateText = !String.IsNullOrWhiteSpace(MainexpectedDeliveryDate) ? Translate("Verwacht:") + "&nbsp;" + MainexpectedDeliveryDate : ""; 483 484 @if (!(bool?)MainVariant.ProductFieldValues.Where(o => o.ProductField.SystemName == "ProductToBeDiscontinued").SingleOrDefault()?.Value ?? false) 485 { 486 if (MainvariantStock > 0) 487 { 488 if (MainisNew == "true" || MainIsSale == "true") 489 { 490 if (MainIsSale == "true") 491 { 492 MainstockState += MainIsSaleSvg + "&nbsp; &nbsp;" + Translate("Sale!") + "<br/>"; 493 } 494 495 if (MainisNew == "true") 496 { 497 MainstockState += MainisNewSvg + "&nbsp; &nbsp;" + Translate("New!") + "<br/>"; 498 } 499 500 MainstockState += "&nbsp;" + Translate("Nu leverbaar"); 501 } 502 else 503 { 504 MainstockState = MainsvgInStock + "&nbsp; " + Translate("Op voorraad"); 505 506 } 507 } 508 else 509 { 510 MainstockState = MainsvgOutStock + "&nbsp;" + Translate("Geen voorraad") + "<br/>" + MainexpectedDeliveryDateText; 511 512 } 513 } 514 else 515 { 516 517 MainstockState = MainsvgOutStock + "&nbsp;" + Translate("Discontinued:") + "<br/>" + MainvariantStock + "&nbsp;" + @Translate("left in stock"); 518 519 } 520 /*End stock state*/ 521 522 523 @MainstockState 524 525 526 } 527 </div> 528 } 529 else 530 { 531 <div class="stock-state pt-2 mt-auto"> 532 @MainOutStock @Translate("Discontinued") 533 </div> 534 } 535 <div class="custom-price mt-auto"> 536 @{ 537 538 539 540 541 bool isErpConnectionDown = !Dynamicweb.Core.Converter.ToBoolean(Dynamicweb.Context.Current.Items["IsWebServiceConnectionAvailable"]); 542 bool hidePrice = anonymousUsersLimitations.Contains("price") && anonymousUser || Pageview.AreaSettings.GetBoolean("ErpDownHidePrices") && isErpConnectionDown; 543 544 bool productIsDiscontinued = product is object && product.Discontinued; 545 bool doNotShowPriceIfProductIsDiscontinued = Model.Item.GetBoolean("DoNotShowPriceIfProductIsDiscontinued"); 546 var isDiscontinued = productIsDiscontinued && doNotShowPriceIfProductIsDiscontinued; 547 } 548 549 @if (product is object && !hidePrice && !isDiscontinued) 550 { 551 string unitId = !string.IsNullOrEmpty(Dynamicweb.Context.Current.Request.Form.Get("UnitId")) ? Dynamicweb.Context.Current.Request.Form.Get("UnitId") : string.Empty; 552 553 string priceFontSize = Model.Item.GetRawValueString("PriceSize", "fs-4"); 554 string horizontalAlign = Model.Item.GetRawValueString("HorizontalAlignment", ""); 555 string layout = Model.Item.GetRawValueString("Layout", "horizontal"); 556 string textAlign = horizontalAlign == "center" ? "text-center" : string.Empty; 557 textAlign = horizontalAlign == "end" ? "text-end" : textAlign; 558 559 horizontalAlign = horizontalAlign == "center" && layout == "horizontal" ? "justify-content-center" : horizontalAlign; 560 horizontalAlign = horizontalAlign == "end" && layout == "horizontal" ? "justify-content-end" : horizontalAlign; 561 horizontalAlign = horizontalAlign == "center" && layout == "vertical" ? "align-items-center" : horizontalAlign; 562 horizontalAlign = horizontalAlign == "end" && layout == "vertical" ? "align-items-end" : horizontalAlign; 563 564 string flexDirection = layout == "horizontal" ? string.Empty : "flex-column"; 565 string flexGap = layout == "horizontal" ? "gap-3" : string.Empty; 566 string order = layout == "horizontal" ? string.Empty : "order-2"; 567 568 569 string contentPadding = Model.Item.GetRawValueString("ContentPadding", ""); 570 contentPadding = contentPadding == "none" ? "p-0" : contentPadding; 571 contentPadding = contentPadding == "small" ? "p-1 px-md-2 py-md-1" : contentPadding; 572 contentPadding = contentPadding == "large" ? "p-2 px-md-3 py-md-2" : contentPadding; 573 string liveInfoClass = ""; 574 575 576 577 578 579 580 if (isLazyLoadingForProductInfoEnabled) 581 { 582 if (Dynamicweb.Context.Current.Items.Contains("ProductInfoFeed")) 583 { 584 productInfoFeed = Dynamicweb.Context.Current.Items["ProductInfoFeed"]?.ToString(); 585 if (!string.IsNullOrEmpty(productInfoFeed)) 586 { 587 productInfoFeed = $"data-product-info-feed=\"{productInfoFeed}\""; 588 } 589 } 590 liveInfoClass = "js-live-info"; 591 } 592 593 <div class="@textAlign @liveInfoClass item_@Model.Item.SystemName.ToLower()" data-product-id="@product.Id" data-variant-id="@product.VariantId" @productInfoFeed> 594 @if (showInformativePrice && product.PriceInformative.Price != 0) 595 { 596 <div class="opacity-50"> 597 <span>@Translate("RRP") </span> 598 <span class="text-decoration-line-through text-price">@product.PriceInformative.PriceFormatted</span> 599 </div> 600 } 601 <div class="@priceFontSize m-0 d-flex flex-wrap @flexDirection @flexGap @horizontalAlign" style="row-gap: 0 !important" itemprop="offers" itemscope itemtype="https://schema.org/Offer"> 602 <span itemprop="priceCurrency" content="@product.Price.CurrencyCode" class="d-none"></span> 603 604 605 @if (showPricesWithVat == "false" && !neverShowVat) 606 { 607 if (isLazyLoadingForProductInfoEnabled && !Pageview.IsVisualEditorMode) 608 { 609 <span itemprop="price" content="" class="d-none"></span> 610 <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> 611 } 612 else 613 { 614 string beforePrice = !string.IsNullOrEmpty(unitId) ? product.GetPrice(unitId).PriceBeforeDiscount.PriceWithoutVatFormatted : product.PriceBeforeDiscount.PriceWithoutVatFormatted; 615 616 <span itemprop="price" content="@product.Price.PriceWithoutVat.ToString("0.00", System.Globalization.CultureInfo.InvariantCulture)" class="d-none"></span> 617 if (product.Price.Price != product.PriceBeforeDiscount.Price) 618 { 619 <span class="text-decoration-line-through opacity-75 @order">@beforePrice</span> 620 } 621 } 622 } 623 else 624 { 625 if (isLazyLoadingForProductInfoEnabled && !Pageview.IsVisualEditorMode) 626 { 627 <span itemprop="price" content="" class="d-none"></span> 628 <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> 629 } 630 else 631 { 632 string beforePrice = !string.IsNullOrEmpty(unitId) ? product.GetPrice(unitId).PriceBeforeDiscount.PriceFormatted : product.PriceBeforeDiscount.PriceFormatted; 633 634 <span itemprop="price" content="@product.Price.Price.ToString("0.00", System.Globalization.CultureInfo.InvariantCulture)" class="d-none"></span> 635 636 if (product.Price.Price != product.PriceBeforeDiscount.Price) 637 { 638 <span class="text-decoration-line-through opacity-75 @order"> 639 <span class="text-price">@beforePrice</span> 640 </span> 641 } 642 } 643 } 644 645 @if (showPricesWithVat == "false" && !neverShowVat) 646 { 647 if (isLazyLoadingForProductInfoEnabled && !Pageview.IsVisualEditorMode) 648 { 649 <span class="text-price js-text-price"> 650 <span class="spinner-border" role="status"></span> 651 </span> 652 } 653 else 654 { 655 string price = !string.IsNullOrEmpty(unitId) ? product.GetPrice(unitId).Price.PriceWithoutVatFormatted : product.Price.PriceWithoutVatFormatted; 656 657 if (product?.VariantInfo?.VariantInfo != null) 658 { 659 priceMin = product?.VariantInfo?.PriceMin?.PriceWithoutVatFormatted != null ? product.VariantInfo.PriceMin.PriceWithoutVatFormatted : ""; 660 priceMax = product?.VariantInfo?.PriceMax?.PriceWithoutVatFormatted != null ? product.VariantInfo.PriceMax.PriceWithoutVatFormatted : ""; 661 } 662 if (priceMin != priceMax) 663 { 664 price = priceMin + " - " + priceMax; 665 } 666 <span class="@theme @contentPadding"> 667 <span class="text-price">@price</span> 668 </span> 669 } 670 } 671 else 672 { 673 if (isLazyLoadingForProductInfoEnabled && !Pageview.IsVisualEditorMode) 674 { 675 <span class="text-price js-text-price"> 676 <span class="spinner-border" role="status"></span> 677 </span> 678 } 679 else 680 { 681 string price = !string.IsNullOrEmpty(unitId) ? product.GetPrice(unitId).Price.PriceFormatted : product.Price.PriceFormatted; 682 683 if (product?.VariantInfo?.VariantInfo != null) 684 { 685 priceMin = product?.VariantInfo?.PriceMin?.PriceFormatted != null ? product.VariantInfo.PriceMin.PriceFormatted : ""; 686 priceMax = product?.VariantInfo?.PriceMax?.PriceFormatted != null ? product.VariantInfo.PriceMax.PriceFormatted : ""; 687 } 688 if (priceMin != priceMax) 689 { 690 price = priceMin + " - " + priceMax; 691 } 692 <span class="@theme @contentPadding"> 693 <span class="text-price">@price</span> 694 </span> 695 } 696 } 697 698 @* Stock state for Schema.org, start *@ 699 @{ 700 Uri url = Dynamicweb.Context.Current.Request.Url; 701 } 702 703 <link itemprop="url" href="@url"> 704 705 @{ 706 bool IsNeverOutOfStock = product.NeverOutOfstock; 707 } 708 709 @if (IsNeverOutOfStock) 710 { 711 <span itemprop="availability" class="d-none">@Translate("Available in stock")</span> 712 } 713 else 714 { 715 if (product.StockLevel > 0) 716 { 717 <span itemprop="availability" class="d-none">InStock</span> 718 } 719 else 720 { 721 <span itemprop="availability" class="d-none">OutOfStock</span> 722 } 723 } 724 @* Stock state for Schema.org, stop *@ 725 726 </div> 727 728 @if (showPricesWithVat == "false" && !neverShowVat) 729 { 730 if (isLazyLoadingForProductInfoEnabled && !Pageview.IsVisualEditorMode) 731 { 732 <small class="opacity-85 fst-normal js-text-price-with-vat d-none" data-suffix="@Translate("Incl. VAT")"></small> 733 } 734 else 735 { 736 string price = !string.IsNullOrEmpty(unitId) ? product.GetPrice(unitId).Price.PriceWithVatFormatted : product.Price.PriceWithVatFormatted; 737 738 if (product?.VariantInfo?.VariantInfo != null) 739 { 740 priceMin = product?.VariantInfo?.PriceMin?.PriceWithVatFormatted != null ? product.VariantInfo.PriceMin.PriceWithVatFormatted : ""; 741 priceMax = product?.VariantInfo?.PriceMax?.PriceWithVatFormatted != null ? product.VariantInfo.PriceMax.PriceWithVatFormatted : ""; 742 } 743 if (priceMin != priceMax) 744 { 745 price = priceMin + " - " + priceMax; 746 } 747 <!-- <small class="opacity-85 fst-normal">@price @Translate("Incl. VAT")</small> --> 748 } 749 } 750 </div> 751 } 752 else if (Pageview.IsVisualEditorMode) 753 { 754 <div class="alert alert-dark m-0" role="alert"> 755 <span>@Translate("No products available")</span> 756 </div> 757 } 758 759 </div> 760 } 761 } 762
Tischlampe Arch L
Error executing template "Designs/Swift/Paragraph/CustomProductSlider.cshtml"
System.NullReferenceException: Object reference not set to an instance of an object.
   at CompiledRazorTemplates.Dynamic.RazorEngine_3562354021b44d5c892fe73dc2806e4f.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 Dynamicweb.Ecommerce.ProductCatalog 3 @using Dynamicweb.Ecommerce.CustomerExperienceCenter.Favorites 4 @using Dynamicweb.Files 5 @using System.IO 6 @using System.Net 7 @using Dynamicweb.Security.UserManagement 8 9 10 @{ 11 ProductViewModel product = null; 12 if (Dynamicweb.Context.Current.Items.Contains("ProductDetails")) 13 { 14 product = (ProductViewModel)Dynamicweb.Context.Current.Items["ProductDetails"]; 15 } 16 else if (Pageview.Page.Item["DummyProduct"] != null && Pageview.IsVisualEditorMode) 17 { 18 var pageViewModel = Dynamicweb.Frontend.ContentViewModelFactory.CreatePageInfoViewModel(Pageview.Page); 19 ProductListViewModel productList = pageViewModel.Item.GetValue("DummyProduct") != null ? pageViewModel.Item.GetValue("DummyProduct") as ProductListViewModel : new ProductListViewModel(); 20 21 if (productList?.Products is object) 22 { 23 product = productList.Products[0]; 24 } 25 } 26 } 27 28 @{ 29 var currentUser = Pageview?.User; 30 var customerNumber = !string.IsNullOrEmpty(currentUser?.CustomerNumber) 31 ? currentUser.CustomerNumber 32 : ""; 33 } 34 @if (product is object) 35 { 36 string imagePath = product?.DefaultImage?.Value ?? ""; 37 string imagePathUrlEncoded = Dynamicweb.Context.Current.Server.UrlEncode(imagePath); 38 39 string ratio = Model.Item.GetRawValueString("ImageAspectRatio", ""); 40 ratio = ratio != "0" ? ratio : ""; 41 string ratioCssClass = ratio != "" ? " ratio" : ""; 42 string ratioVariable = ratio != "" ? "--bs-aspect-ratio: " + ratio + ";" : ""; 43 44 string width = Model.Item.GetRawValueString("Width", "auto"); 45 int smallImageSize = 640; 46 int largeImageSize = width == "auto" ? 1280 : Convert.ToInt32(width); 47 48 string ImageObjectFit = Model.Item.GetRawValueString("ImageObjectFit", "contain"); 49 50 string imagePathXs = "/Admin/Public/GetImage.ashx?width=" + smallImageSize + "&image=" + imagePathUrlEncoded + "&format=webp"; 51 string imagePathS = "/Admin/Public/GetImage.ashx?width=" + largeImageSize + "&image=" + imagePathUrlEncoded + "&format=webp"; 52 string imagePathFallBack = "/Admin/Public/GetImage.ashx?width=" + largeImageSize + "&image=" + imagePathUrlEncoded + "&format=webp"; 53 54 var badgeParms = new Dictionary<string, object>(); 55 badgeParms.Add("size", "h7"); 56 badgeParms.Add("saleBadgeType", Model.Item.GetRawValue("SaleBadgeType")); 57 badgeParms.Add("saleBadgeCssClassName", Model.Item.GetRawValue("SaleBadgeDesign")); 58 badgeParms.Add("newBadgeCssClassName", Model.Item.GetRawValue("NewBadgeDesign")); 59 badgeParms.Add("newPublicationDays", Model.Item.GetInt32("NewPublicationDays")); 60 badgeParms.Add("campaignBadgesValues", Model.Item.GetList("CampaignBadges")?.GetRawValue().OfType<string>().ToList()); 61 62 string badgeSize = Model.Item.GetRawValueString("BadgeSize", "fs-2"); 63 bool saleBadgeEnabled = !string.IsNullOrWhiteSpace(Model.Item.GetRawValueString("SaleBadgeDesign")) && Model.Item.GetRawValueString("SaleBadgeDesign") != "none" ? true : false; 64 bool newBadgeEnabled = !string.IsNullOrWhiteSpace(Model.Item.GetRawValueString("NewBadgeDesign")) && Model.Item.GetRawValueString("NewBadgeDesign") != "none" ? true : false; 65 66 /*Custom badge*/ 67 var productService = new Dynamicweb.Ecommerce.Products.ProductService(); 68 var currency = Dynamicweb.Ecommerce.Common.Context.Currency.Code; 69 var formatProvider = new System.Globalization.NumberFormatInfo(); 70 formatProvider.NumberDecimalSeparator = "."; 71 formatProvider.NumberGroupSeparator = ","; 72 var MainVariant = productService.GetProductById(product.Id, product.VariantId, false); 73 var fieldValueBlocked = MainVariant?.ProductFieldValues?.GetProductFieldValue("BlockedCustomerList")?.Value; 74 75 76 string isNewProduct = MainVariant?.ProductFieldValues?.GetProductFieldValue("New")?.Value?.ToString().ToLower() ?? ""; 77 string MainisSale = MainVariant?.ProductFieldValues?.GetProductFieldValue("Sale")?.Value?.ToString().ToLower() ?? ""; 78 bool showNewBadge = isNewProduct == "true" ? true : false; 79 bool showSaleBadge = MainisSale == "true" ? true : false; 80 string showNewSaleBadge = "d-none"; 81 if (showSaleBadge) 82 { 83 badgeParms.Add("isSale", "true"); 84 85 } 86 else 87 { 88 badgeParms.Add("isSale", "false"); 89 } 90 if (showNewBadge) 91 { 92 badgeParms.Add("isNew", "true"); 93 } 94 else 95 { 96 badgeParms.Add("isNew", "false"); 97 } 98 /*End Custom badge*/ 99 if (showSaleBadge || showNewBadge) 100 { 101 showNewSaleBadge = ""; 102 } 103 DateTime createdDate = product.Created.Value; 104 bool showBadges = saleBadgeEnabled && product.Discount.Price != 0 ? true : false; 105 106 bool showFavoritesSelector = !string.IsNullOrEmpty(Model.Item.GetString("ShowAddToFavorites")) ? Model.Item.GetBoolean("ShowAddToFavorites") : false; 107 string anonymousUsersLimitations = Pageview.AreaSettings.GetRawValueString("AnonymousUsers", ""); 108 bool anonymousUser = Pageview.User == null; 109 110 var favoriteParameters = new Dictionary<string, object>(); 111 if (!anonymousUser && showFavoritesSelector) 112 { 113 int defaultFavoriteListId = 0; 114 115 IEnumerable<FavoriteList> favoreiteLists = Pageview.User.GetFavoriteLists(); 116 if (favoreiteLists.Count() == 1) 117 { 118 foreach (FavoriteList list in favoreiteLists) 119 { 120 defaultFavoriteListId = list.ListId; 121 } 122 } 123 124 favoriteParameters.Add("ListId", defaultFavoriteListId); 125 } 126 127 MediaViewModel alternativeImage = new MediaViewModel(); 128 if (Model.Item.GetBoolean("ShowAlternativeImageOnHover")) 129 { 130 var selectedImageCategories = Model.Item.GetList("GetAlternativeImageFrom")?.GetRawValue().OfType<string>().ToList(); 131 List<MediaViewModel> allAssetsImages = product.AssetCategories.Where(x => selectedImageCategories.Contains(x.SystemName)).SelectMany(x => x.Assets).ToList(); 132 allAssetsImages.RemoveAll(x => x.Value == product.DefaultImage.Value); 133 alternativeImage = allAssetsImages.FirstOrDefault(); 134 } 135 136 string altImagePathXs = string.Empty; 137 string altImagePathS = string.Empty; 138 139 if (!string.IsNullOrEmpty(alternativeImage?.Value)) 140 { 141 altImagePathXs = "/Admin/Public/GetImage.ashx?width=" + smallImageSize + "&image=" + Dynamicweb.Context.Current.Server.UrlEncode(alternativeImage.Value) + "&format=webp"; 142 altImagePathS = "/Admin/Public/GetImage.ashx?width=" + largeImageSize + "&image=" + Dynamicweb.Context.Current.Server.UrlEncode(alternativeImage.Value) + "&format=webp"; 143 } 144 145 @* Theme settings *@ 146 string theme = !string.IsNullOrWhiteSpace(Model.Item.GetRawValueString("Theme")) ? " theme " + Model.Item.GetRawValueString("Theme").Replace(" ", "").Trim().ToLower() : ""; 147 string themeBorder = !string.IsNullOrWhiteSpace(theme) ? "border: 1px solid rgba(0,0,0,0)" : ""; 148 string themePadding = !string.IsNullOrWhiteSpace(theme) ? "p-2 p-lg-3" : ""; 149 150 string imageId = "ProductImage_" + product.Id; 151 152 153 154 string fullWidth = width == "auto" ? "w-100" : ""; 155 string customWidth = width != "auto" ? "style=\"width: " + width + "px\"" : "style=\"min-width: 60px\""; 156 157 string altImageZindex = Model.Item.GetBoolean("ShowAlternativeImageOnHover") && !string.IsNullOrEmpty(alternativeImage?.Value) ? " z-index: 1" : string.Empty; 158 string groupid = !string.IsNullOrEmpty(Dynamicweb.Context.Current.Request.QueryString.Get("GroupID")) ? Dynamicweb.Context.Current.Request.QueryString.Get("GroupID"):"" ; 159 string link = product.GetProductLink(GetPageIdByNavigationTag("Shop"), false); 160 var productVariantGroups = product.VariantGroups(); 161 string MainOutStock = "<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"25\" height=\"25\" fill=\"#CA0D0D\" class=\"bi bi-x-lg\" viewBox=\"0 0 16 16\"><path d=\"M4.646 4.646a.5.5 0 0 1 .708 0L8 7.293l2.646-2.647a.5.5 0 0 1 .708.708L8.707 8l2.647 2.646a.5.5 0 0 1-.708.708L8 8.707l-2.646 2.647a.5.5 0 0 1-.708-.708L7.293 8 4.646 5.354a.5.5 0 0 1 0-.708\"/></svg>"; 162 163 @if (!string.IsNullOrEmpty(imagePath)) 164 { 165 <div class="@fullWidth @theme position-relative item_@Model.Item.SystemName.ToLower() main-image-container" @customWidth> 166 <div class="" style="@(ratioVariable)@(altImageZindex)"> 167 <div class="d-flex justify-content-center align-items-center"> 168 <a class="main-link-link" href="@link"> 169 @if (imagePath.StartsWith("/Files/", StringComparison.OrdinalIgnoreCase)) 170 { 171 <img id="@imageId" 172 srcset=" 173 @imagePathXs @(smallImageSize)w, 174 @imagePathS @(largeImageSize)w" 175 sizes="(max-width: 992px) 50vw, 25vw" 176 src="@imagePathFallBack" 177 loading="lazy" 178 decoding="async" 179 class="h-100 w-100 @themePadding main-image" 180 style="object-fit: @ImageObjectFit; @themeBorder " 181 alt="@product.Name" 182 itemprop="image"> 183 } 184 else 185 { 186 <img src="@product.DefaultImage.Value" 187 loading="lazy" 188 class="h-100 w-100 @themePadding main-image" 189 style="object-fit: contain; @themeBorder" 190 alt="@product.Name" 191 itemprop="image"> 192 } 193 </a> 194 </div> 195 </div> 196 197 <div class="position-absolute top-0 left-0 p-2 pb-0 custom-badge-product-list @showNewSaleBadge"> 198 @{ 199 @RenderPartial("Components/Custom_EcommerceBadge.cshtml", product, badgeParms) 200 } 201 </div> 202 203 204 </div> 205 } 206 207 <div class="product-info h-100"> 208 <div class="fs-7 pt-1 opacity-85 start item_@Model.Item.SystemName.ToLower() product-number" itemprop="sku">@product.Id / @product.VariantId - @product.VariantName</div> 209 <div class="py-2" data-col-size="12"> 210 <h2 class="h6 start m-0 item_swift_productheader product-name" itemprop="name"><b>@product.Name</b></h2> 211 </div> 212 </div> 213 var sliderId = $"thumb-scroll-{product.Id}"; 214 if (productVariantGroups.Any() && product?.VariantInfo?.VariantInfo != null) 215 216 { 217 @using Dynamicweb.Ecommerce.Prices 218 @{ 219 string[] variantId = product.VariantId.Split('.'); 220 string showPricesWithVat = Pageview.Area.EcomPricesWithVat.ToLower(); 221 bool neverShowVat = string.IsNullOrEmpty(showPricesWithVat); 222 bool showInformativePrice = Model.Item.GetBoolean("ShowInformativePrice"); 223 string productInfoFeed = ""; 224 bool isLazyLoadingForProductInfoEnabled = Dynamicweb.Core.Converter.ToBoolean(Dynamicweb.Context.Current.Items["IsLazyLoadingForProductInfoEnabled"]); 225 if (isLazyLoadingForProductInfoEnabled) 226 { 227 if (Dynamicweb.Context.Current.Items.Contains("ProductInfoFeed")) 228 { 229 productInfoFeed = Dynamicweb.Context.Current.Items["ProductInfoFeed"]?.ToString(); 230 if (!string.IsNullOrEmpty(productInfoFeed)) 231 { 232 productInfoFeed =productInfoFeed; 233 } 234 } 235 236 } 237 string priceMin = ""; 238 string priceMax = ""; 239 int groupNumber = 1; 240 241 242 243 244 string baseUrl = $"Default.aspx?ID={GetPageIdByNavigationTag("Shop")}&GroupID={product.PrimaryOrDefaultGroup.Id}&ProductID={product.Id}"; 245 if (!string.IsNullOrEmpty(baseUrl)) 246 { 247 baseUrl = $"/{baseUrl.TrimStart('/')}"; 248 } 249 string variantUrl = string.Empty; 250 251 252 Dictionary<string, string> 253 variantImages = new Dictionary<string, string> 254 (); 255 <div class="last-row mt-auto"> 256 257 @foreach (var variantGroup in productVariantGroups) 258 { 259 <div class="thumbnail-wrapper"> 260 <button class="thumb-nav prev" onclick="scrollThumbs('@sliderId', -1)"> 261 <svg width="20px" height="20px" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" fill="#1D98A5"> 262 263 <g stroke="none" stroke-width="1" fill="none" fill-rule="evenodd"> 264 <g transform="translate(-336.000000, 0.000000)"> 265 <g id="left_line" transform="translate(336.000000, 0.000000)"> 266 <path d="M24,0 L24,24 L0,24 L0,0 L24,0 Z M12.5934901,23.257841 L12.5819402,23.2595131 L12.5108777,23.2950439 L12.4918791,23.2987469 L12.4918791,23.2987469 L12.4767152,23.2950439 L12.4056548,23.2595131 C12.3958229,23.2563662 12.3870493,23.2590235 12.3821421,23.2649074 L12.3780323,23.275831 L12.360941,23.7031097 L12.3658947,23.7234994 L12.3769048,23.7357139 L12.4804777,23.8096931 L12.4953491,23.8136134 L12.4953491,23.8136134 L12.5071152,23.8096931 L12.6106902,23.7357139 L12.6232938,23.7196733 L12.6232938,23.7196733 L12.6266527,23.7031097 L12.609561,23.275831 C12.6075724,23.2657013 12.6010112,23.2592993 12.5934901,23.257841 L12.5934901,23.257841 Z M12.8583906,23.1452862 L12.8445485,23.1473072 L12.6598443,23.2396597 L12.6498822,23.2499052 L12.6498822,23.2499052 L12.6471943,23.2611114 L12.6650943,23.6906389 L12.6699349,23.7034178 L12.6699349,23.7034178 L12.678386,23.7104931 L12.8793402,23.8032389 C12.8914285,23.8068999 12.9022333,23.8029875 12.9078286,23.7952264 L12.9118235,23.7811639 L12.8776777,23.1665331 C12.8752882,23.1545897 12.8674102,23.1470016 12.8583906,23.1452862 L12.8583906,23.1452862 Z M12.1430473,23.1473072 C12.1332178,23.1423925 12.1221763,23.1452606 12.1156365,23.1525954 L12.1099173,23.1665331 L12.0757714,23.7811639 C12.0751323,23.7926639 12.0828099,23.8018602 12.0926481,23.8045676 L12.108256,23.8032389 L12.3092106,23.7104931 L12.3186497,23.7024347 L12.3186497,23.7024347 L12.3225043,23.6906389 L12.340401,23.2611114 L12.337245,23.2485176 L12.337245,23.2485176 L12.3277531,23.2396597 L12.1430473,23.1473072 Z" id="MingCute" fill-rule="nonzero"> </path> 267 <path d="M8.29292,12.7071 C7.9024,12.3166 7.9024,11.6834 8.29292,11.2929 L13.9498,5.63604 C14.3403,5.24551 14.9735,5.24551 15.364,5.63604 C15.7545,6.02656 15.7545,6.65973 15.364,7.05025 L10.4142,12 L15.364,16.9497 C15.7545,17.3403 15.7545,17.9734 15.364,18.364 C14.9735,18.7545 14.3403,18.7545 13.9498,18.364 L8.29292,12.7071 Z" id="路径" fill="#1D98A5"> </path> 268 </g> 269 </g> 270 </g> 271 </svg> 272 273 </button> 274 <div class="thumbnail-scroll" id="@sliderId"> 275 @{ 276 VariantGroupViewModel group = variantGroup; 277 foreach (var option in group.Options.OrderBy(o => o.Id)) 278 { 279 var productVariant = productService.GetProductById(product.Id, option.Id, false); 280 281 var productSelection = new PriceProductSelection(productVariant, null, 0); 282 283 var currencyCode = string.IsNullOrWhiteSpace(Pageview.User.Currency) ? Pageview.Area.EcomCurrencyId : Pageview.User.Currency; 284 var countryCode = string.IsNullOrWhiteSpace(Pageview.User.CountryCode) ? Pageview.Area.EcomCountryCode : Pageview.User.CountryCode; 285 286 var userCurrency = Dynamicweb.Ecommerce.Services.Currencies.GetCurrency(currencyCode); 287 var userCountry = Dynamicweb.Ecommerce.Services.Countries.GetCountry(countryCode); 288 289 var priceContext = new PriceContext(userCurrency, userCountry, null, Pageview.User, false, null); 290 var productPrice = Dynamicweb.Ecommerce.Services.Prices.FindPrices(priceContext, productSelection, false); 291 292 //throw new Exception(System.Text.Json.JsonSerializer.Serialize(productPrice)); 293 294 var fieldValue = productVariant?.ProductFieldValues?.GetProductFieldValue("BlockedCustomerList")?.Value; 295 296 if ((fieldValue != null && !fieldValue.ToString().Contains(customerNumber)) || String.IsNullOrWhiteSpace(customerNumber)) 297 { 298 299 300 string active = variantId != null && variantId.Contains(option.Id) ? "active" : string.Empty; 301 string buttonId = $"{product.Id}_{option.Id}_{Pageview.CurrentParagraph.ID}"; 302 string contrastColor = string.Empty; 303 304 string searchKey = $"{product.Id}_{option.Id}_"; 305 /*Images*/ 306 var imagePathVariant = option.Image?.Value ?? ""; 307 308 309 var folderPath = Path.GetDirectoryName(imagePathVariant); 310 311 string physicalFolderPath = Dynamicweb.Context.Current.Server.MapPath(folderPath); 312 313 string lastImage = null; 314 315 if (Directory.Exists(physicalFolderPath)) 316 { 317 318 var fileWith15 = Directory.GetFiles(physicalFolderPath) 319 .FirstOrDefault(f => Path.GetFileName(f).Contains($"{product.Id}_{option.Id}_9")); 320 321 if (fileWith15 != null) 322 { 323 lastImage = fileWith15; 324 } 325 else 326 { 327 var files = Directory.GetFiles(physicalFolderPath) 328 .Where(f => Path.GetFileName(f).StartsWith($"{product.Id}_{option.Id}_")) 329 .OrderByDescending(f => 330 { 331 var filename = Path.GetFileNameWithoutExtension(f); 332 var match = System.Text.RegularExpressions.Regex.Match(filename, @"_(\d+)$"); 333 if (match.Success && int.TryParse(match.Groups[1].Value, out int index)) 334 { 335 return index; 336 } 337 return 0; 338 }) 339 .ToList(); 340 341 if (files.Any()) 342 { 343 lastImage = files.First(); 344 } 345 } 346 } 347 348 var lastImageUrl = lastImage != null ? lastImage : "/Files/Images/zijlstra/Afbeeldingen_overig/Coming_Soon.jpg"; 349 int index = lastImageUrl.IndexOf("Files"); 350 string relativePath = index >= 0 ? lastImageUrl.Substring(index).Replace("\\", "/") : lastImageUrl.Replace("\\", "/"); 351 lastImageUrl = "/" + relativePath; 352 lastImageUrl = Dynamicweb.Context.Current.Server.UrlEncode(lastImageUrl); 353 var variantImg = option.Image is object ? Dynamicweb.Context.Current.Server.UrlEncode(option.Image.Value) : null; 354 var variantLink = "/Default.aspx?ID=" + GetPageIdByNavigationTag("Shop") + "&GroupID=" + product.PrimaryOrDefaultGroup.Id + "&ProductID=" + product.Id + "&VariantID=" + option.Id; 355 356 string variantImage = string.Empty; 357 variantImages.TryGetValue(option.Id, out variantImage); 358 /*End Images*/ 359 360 /*stock state*/ 361 double variantStock = productVariant.Stock; 362 string svgInStock = "<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"16\" height=\"16\" fill=\"#44B11A\" class=\"bi bi-check-lg\" viewBox=\"0 0 16 16\"><path d=\"M12.736 3.97a.733.733 0 0 1 1.047 0c.286.289.29.756.01 1.05L7.88 12.01a.733.733 0 0 1-1.065.02L3.217 8.384a.757.757 0 0 1 0-1.06.733.733 0 0 1 1.047 0l3.052 3.093 5.4-6.425z\"/></svg>"; 363 string svgOutStock = "<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"25\" height=\"25\" fill=\"#CA0D0D\" class=\"bi bi-x-lg\" viewBox=\"0 0 16 16\"><path d=\"M4.646 4.646a.5.5 0 0 1 .708 0L8 7.293l2.646-2.647a.5.5 0 0 1 .708.708L8.707 8l2.647 2.646a.5.5 0 0 1-.708.708L8 8.707l-2.646 2.647a.5.5 0 0 1-.708-.708L7.293 8 4.646 5.354a.5.5 0 0 1 0-.708\"/></svg>"; 364 365 string infoStock = "<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"16\" height=\"16\" fill=\"currentColor\" class=\"bi bi-info-circle-fill\" viewBox=\"0 0 16 16\"><path d=\"M8 16A8 8 0 1 0 8 0a8 8 0 0 0 0 16m.93-9.412-1 4.705c-.07.34.029.533.304.533.194 0 .487-.07.686-.246l-.088.416c-.287.346-.92.598-1.465.598-.703 0-1.002-.422-.808-1.319l.738-3.468c.064-.293.006-.399-.287-.47l-.451-.081.082-.381 2.29-.287zM8 5.5a1 1 0 1 1 0-2 1 1 0 0 1 0 2\" /></svg>"; 366 string isNew = productVariant?.ProductFieldValues?.GetProductFieldValue("New")?.Value?.ToString().ToLower() ?? ""; 367 string isNewSvg = "<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"16\" height=\"16\" fill=\"#F2C400\" class=\"bi bi-star-fill\" viewBox=\"0 0 16 16\"><path d = \"M3.612 15.443c-.386.198-.824-.149-.746-.592l.83-4.73L.173 6.765c-.329-.314-.158-.888.283-.95l4.898-.696L7.538.792c.197-.39.73-.39.927 0l2.184 4.327 4.898.696c.441.062.612.636.282.95l-3.522 3.356.83 4.73c.078.443-.36.79-.746.592L8 13.187l-4.389 2.256z\" /></svg> "; 368 string stockState = ""; 369 370 string isSale = productVariant?.ProductFieldValues?.GetProductFieldValue("Sale")?.Value?.ToString().ToLower() ?? ""; 371 string isSaleSvg = "<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"16\" height=\"16\" fill=\"#F03232\" class=\"bi bi-star-fill\" viewBox=\"0 0 16 16\"><path d = \"M3.612 15.443c-.386.198-.824-.149-.746-.592l.83-4.73L.173 6.765c-.329-.314-.158-.888.283-.95l4.898-.696L7.538.792c.197-.39.73-.39.927 0l2.184 4.327 4.898.696c.441.062.612.636.282.95l-3.522 3.356.83 4.73c.078.443-.36.79-.746.592L8 13.187l-4.389 2.256z\" /></svg> "; 372 373 string expectedDeliveryDate = ""; 374 375 if (DateTime.Compare(productVariant.ExpectedDelivery, new DateTime(1900, 1, 1)) != 0) //In DW, if the Date is not set, it is defaulted 01-01-1900 and not null.. 376 { 377 expectedDeliveryDate = productVariant.ExpectedDelivery.ToShortDateString(); 378 } 379 380 string expectedDeliveryDateText = !String.IsNullOrWhiteSpace(expectedDeliveryDate) ? Translate("Verwacht:") + "&nbsp;" + expectedDeliveryDate : ""; 381 382 @if (!(bool?)productVariant.ProductFieldValues.Where(o => o.ProductField.SystemName == "ProductToBeDiscontinued").SingleOrDefault()?.Value ?? false) 383 { 384 if (variantStock > 0) 385 { 386 if (isNew == "true" || isSale == "true") 387 { 388 if (isSale == "true") 389 { 390 stockState += isSaleSvg + "&nbsp; &nbsp;" + Translate("Sale!") + "<br/>"; 391 } 392 393 if (isNew == "true") 394 { 395 stockState += isNewSvg + "&nbsp; &nbsp;" + Translate("New!") + "<br/>"; 396 } 397 398 stockState += "&nbsp;" + Translate("Nu leverbaar"); 399 } 400 else 401 { 402 stockState = svgInStock + "&nbsp; " + Translate("Op voorraad"); 403 404 } 405 } 406 else 407 { 408 stockState = svgOutStock + "&nbsp;" + Translate("Geen voorraad") + "<br/>" + expectedDeliveryDateText; 409 410 } 411 } 412 else 413 { 414 415 stockState = svgOutStock + "&nbsp;" + Translate("Discontinued:") + "<br/>" + variantStock + "&nbsp;" + @Translate("left in stock"); 416 417 } 418 /*End stock state*/ 419 /*Price variants*/ 420 double price = productVariant.DefaultPrice; 421 double cost = productVariant.Cost; 422 423 string priceFormated = Dynamicweb.Ecommerce.Services.Currencies.Format(Dynamicweb.Ecommerce.Services.Currencies.GetCurrency(currency), Convert.ToDouble(productPrice.ToList()[0].Amount, formatProvider)); 424 //string priceFormated = Dynamicweb.Ecommerce.Services.Currencies.Format(Dynamicweb.Ecommerce.Services.Currencies.GetCurrency(currency), Convert.ToDouble(price, formatProvider)); 425 426 427 428 /*End Price variants*/ 429 430 <img class="theme thumbnail" data-stockstate="@WebUtility.HtmlEncode(stockState)" src="/Admin/Public/GetImage.ashx?image=@(lastImageUrl)&width=64&format=webp" onclick="selectVariant('@(product.Id)','/Admin/Public/GetImage.ashx?image=@(variantImg)&format=webp','@variantLink','@product.Id','@option.Id','@option.Name',this.dataset.stockstate,'@isNew','@isSale','@priceFormated','@cost')" /> 431 432 433 } 434 } 435 436 } 437 </div> 438 <button class="thumb-nav next" onclick="scrollThumbs('@sliderId', 1)"> 439 <svg width="20px" height="20px" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" fill="#1D98A5"> 440 441 <g stroke="none" stroke-width="1" fill="none" fill-rule="evenodd"> 442 <g transform="translate(-384.000000, 0.000000)"> 443 <g id="right_line" transform="translate(384.000000, 0.000000)"> 444 <path d="M24,0 L24,24 L0,24 L0,0 L24,0 Z M12.5934901,23.257841 L12.5819402,23.2595131 L12.5108777,23.2950439 L12.4918791,23.2987469 L12.4918791,23.2987469 L12.4767152,23.2950439 L12.4056548,23.2595131 C12.3958229,23.2563662 12.3870493,23.2590235 12.3821421,23.2649074 L12.3780323,23.275831 L12.360941,23.7031097 L12.3658947,23.7234994 L12.3769048,23.7357139 L12.4804777,23.8096931 L12.4953491,23.8136134 L12.4953491,23.8136134 L12.5071152,23.8096931 L12.6106902,23.7357139 L12.6232938,23.7196733 L12.6232938,23.7196733 L12.6266527,23.7031097 L12.609561,23.275831 C12.6075724,23.2657013 12.6010112,23.2592993 12.5934901,23.257841 L12.5934901,23.257841 Z M12.8583906,23.1452862 L12.8445485,23.1473072 L12.6598443,23.2396597 L12.6498822,23.2499052 L12.6498822,23.2499052 L12.6471943,23.2611114 L12.6650943,23.6906389 L12.6699349,23.7034178 L12.6699349,23.7034178 L12.678386,23.7104931 L12.8793402,23.8032389 C12.8914285,23.8068999 12.9022333,23.8029875 12.9078286,23.7952264 L12.9118235,23.7811639 L12.8776777,23.1665331 C12.8752882,23.1545897 12.8674102,23.1470016 12.8583906,23.1452862 L12.8583906,23.1452862 Z M12.1430473,23.1473072 C12.1332178,23.1423925 12.1221763,23.1452606 12.1156365,23.1525954 L12.1099173,23.1665331 L12.0757714,23.7811639 C12.0751323,23.7926639 12.0828099,23.8018602 12.0926481,23.8045676 L12.108256,23.8032389 L12.3092106,23.7104931 L12.3186497,23.7024347 L12.3186497,23.7024347 L12.3225043,23.6906389 L12.340401,23.2611114 L12.337245,23.2485176 L12.337245,23.2485176 L12.3277531,23.2396597 L12.1430473,23.1473072 Z" id="MingCute" fill-rule="nonzero"> </path> 445 <path d="M15.7072,11.2929 C16.0977,11.6834 16.0977,12.3166 15.7072,12.7071 L10.0503,18.364 C9.65982,18.7545 9.02666,18.7545 8.63613,18.364 C8.24561,17.9734 8.24561,17.3403 8.63613,16.9497 L13.5859,12 L8.63613,7.05025 C8.24561,6.65973 8.24561,6.02656 8.63613,5.63604 C9.02666,5.24551 9.65982,5.24551 10.0503,5.63604 L15.7072,11.2929 Z" id="路径" fill="#1D98A5"> </path> 446 </g> 447 </g> 448 449 </svg> 450 451 </button> 452 </div> 453 } 454 455 456 </div> 457 458 } 459 if ((fieldValueBlocked != null && !fieldValueBlocked.ToString().Contains(customerNumber)) || String.IsNullOrWhiteSpace(customerNumber)) 460 { 461 <div class="stock-state pt-2 mt-auto"> 462 @{ 463 464 /*stock state*/ 465 double MainvariantStock = MainVariant.Stock; 466 string MainsvgInStock = "<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"16\" height=\"16\" fill=\"#44B11A\" class=\"bi bi-check-lg\" viewBox=\"0 0 16 16\"><path d=\"M12.736 3.97a.733.733 0 0 1 1.047 0c.286.289.29.756.01 1.05L7.88 12.01a.733.733 0 0 1-1.065.02L3.217 8.384a.757.757 0 0 1 0-1.06.733.733 0 0 1 1.047 0l3.052 3.093 5.4-6.425z\"/></svg>"; 467 string MainsvgOutStock = "<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"25\" height=\"25\" fill=\"#CA0D0D\" class=\"bi bi-x-lg\" viewBox=\"0 0 16 16\"><path d=\"M4.646 4.646a.5.5 0 0 1 .708 0L8 7.293l2.646-2.647a.5.5 0 0 1 .708.708L8.707 8l2.647 2.646a.5.5 0 0 1-.708.708L8 8.707l-2.646 2.647a.5.5 0 0 1-.708-.708L7.293 8 4.646 5.354a.5.5 0 0 1 0-.708\"/></svg>"; 468 469 string MaininfoStock = "<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"16\" height=\"16\" fill=\"currentColor\" class=\"bi bi-info-circle-fill\" viewBox=\"0 0 16 16\"><path d=\"M8 16A8 8 0 1 0 8 0a8 8 0 0 0 0 16m.93-9.412-1 4.705c-.07.34.029.533.304.533.194 0 .487-.07.686-.246l-.088.416c-.287.346-.92.598-1.465.598-.703 0-1.002-.422-.808-1.319l.738-3.468c.064-.293.006-.399-.287-.47l-.451-.081.082-.381 2.29-.287zM8 5.5a1 1 0 1 1 0-2 1 1 0 0 1 0 2\" /></svg>"; 470 string MainisNew = MainVariant?.ProductFieldValues?.GetProductFieldValue("New")?.Value?.ToString().ToLower() ?? ""; 471 string MainisNewSvg = "<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"16\" height=\"16\" fill=\"#F2C400\" class=\"bi bi-star-fill\" viewBox=\"0 0 16 16\"><path d = \"M3.612 15.443c-.386.198-.824-.149-.746-.592l.83-4.73L.173 6.765c-.329-.314-.158-.888.283-.95l4.898-.696L7.538.792c.197-.39.73-.39.927 0l2.184 4.327 4.898.696c.441.062.612.636.282.95l-3.522 3.356.83 4.73c.078.443-.36.79-.746.592L8 13.187l-4.389 2.256z\" /></svg> "; 472 string MainstockState = ""; 473 string MainIsSale = MainVariant?.ProductFieldValues?.GetProductFieldValue("Sale")?.Value?.ToString().ToLower() ?? ""; 474 string MainIsSaleSvg = "<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"16\" height=\"16\" fill=\"#F03232\" class=\"bi bi-star-fill\" viewBox=\"0 0 16 16\"><path d = \"M3.612 15.443c-.386.198-.824-.149-.746-.592l.83-4.73L.173 6.765c-.329-.314-.158-.888.283-.95l4.898-.696L7.538.792c.197-.39.73-.39.927 0l2.184 4.327 4.898.696c.441.062.612.636.282.95l-3.522 3.356.83 4.73c.078.443-.36.79-.746.592L8 13.187l-4.389 2.256z\" /></svg> "; 475 string MainexpectedDeliveryDate = ""; 476 477 if (DateTime.Compare(MainVariant.ExpectedDelivery, new DateTime(1900, 1, 1)) != 0) //In DW, if the Date is not set, it is defaulted 01-01-1900 and not null.. 478 { 479 MainexpectedDeliveryDate = MainVariant.ExpectedDelivery.ToShortDateString(); 480 } 481 482 string MainexpectedDeliveryDateText = !String.IsNullOrWhiteSpace(MainexpectedDeliveryDate) ? Translate("Verwacht:") + "&nbsp;" + MainexpectedDeliveryDate : ""; 483 484 @if (!(bool?)MainVariant.ProductFieldValues.Where(o => o.ProductField.SystemName == "ProductToBeDiscontinued").SingleOrDefault()?.Value ?? false) 485 { 486 if (MainvariantStock > 0) 487 { 488 if (MainisNew == "true" || MainIsSale == "true") 489 { 490 if (MainIsSale == "true") 491 { 492 MainstockState += MainIsSaleSvg + "&nbsp; &nbsp;" + Translate("Sale!") + "<br/>"; 493 } 494 495 if (MainisNew == "true") 496 { 497 MainstockState += MainisNewSvg + "&nbsp; &nbsp;" + Translate("New!") + "<br/>"; 498 } 499 500 MainstockState += "&nbsp;" + Translate("Nu leverbaar"); 501 } 502 else 503 { 504 MainstockState = MainsvgInStock + "&nbsp; " + Translate("Op voorraad"); 505 506 } 507 } 508 else 509 { 510 MainstockState = MainsvgOutStock + "&nbsp;" + Translate("Geen voorraad") + "<br/>" + MainexpectedDeliveryDateText; 511 512 } 513 } 514 else 515 { 516 517 MainstockState = MainsvgOutStock + "&nbsp;" + Translate("Discontinued:") + "<br/>" + MainvariantStock + "&nbsp;" + @Translate("left in stock"); 518 519 } 520 /*End stock state*/ 521 522 523 @MainstockState 524 525 526 } 527 </div> 528 } 529 else 530 { 531 <div class="stock-state pt-2 mt-auto"> 532 @MainOutStock @Translate("Discontinued") 533 </div> 534 } 535 <div class="custom-price mt-auto"> 536 @{ 537 538 539 540 541 bool isErpConnectionDown = !Dynamicweb.Core.Converter.ToBoolean(Dynamicweb.Context.Current.Items["IsWebServiceConnectionAvailable"]); 542 bool hidePrice = anonymousUsersLimitations.Contains("price") && anonymousUser || Pageview.AreaSettings.GetBoolean("ErpDownHidePrices") && isErpConnectionDown; 543 544 bool productIsDiscontinued = product is object && product.Discontinued; 545 bool doNotShowPriceIfProductIsDiscontinued = Model.Item.GetBoolean("DoNotShowPriceIfProductIsDiscontinued"); 546 var isDiscontinued = productIsDiscontinued && doNotShowPriceIfProductIsDiscontinued; 547 } 548 549 @if (product is object && !hidePrice && !isDiscontinued) 550 { 551 string unitId = !string.IsNullOrEmpty(Dynamicweb.Context.Current.Request.Form.Get("UnitId")) ? Dynamicweb.Context.Current.Request.Form.Get("UnitId") : string.Empty; 552 553 string priceFontSize = Model.Item.GetRawValueString("PriceSize", "fs-4"); 554 string horizontalAlign = Model.Item.GetRawValueString("HorizontalAlignment", ""); 555 string layout = Model.Item.GetRawValueString("Layout", "horizontal"); 556 string textAlign = horizontalAlign == "center" ? "text-center" : string.Empty; 557 textAlign = horizontalAlign == "end" ? "text-end" : textAlign; 558 559 horizontalAlign = horizontalAlign == "center" && layout == "horizontal" ? "justify-content-center" : horizontalAlign; 560 horizontalAlign = horizontalAlign == "end" && layout == "horizontal" ? "justify-content-end" : horizontalAlign; 561 horizontalAlign = horizontalAlign == "center" && layout == "vertical" ? "align-items-center" : horizontalAlign; 562 horizontalAlign = horizontalAlign == "end" && layout == "vertical" ? "align-items-end" : horizontalAlign; 563 564 string flexDirection = layout == "horizontal" ? string.Empty : "flex-column"; 565 string flexGap = layout == "horizontal" ? "gap-3" : string.Empty; 566 string order = layout == "horizontal" ? string.Empty : "order-2"; 567 568 569 string contentPadding = Model.Item.GetRawValueString("ContentPadding", ""); 570 contentPadding = contentPadding == "none" ? "p-0" : contentPadding; 571 contentPadding = contentPadding == "small" ? "p-1 px-md-2 py-md-1" : contentPadding; 572 contentPadding = contentPadding == "large" ? "p-2 px-md-3 py-md-2" : contentPadding; 573 string liveInfoClass = ""; 574 575 576 577 578 579 580 if (isLazyLoadingForProductInfoEnabled) 581 { 582 if (Dynamicweb.Context.Current.Items.Contains("ProductInfoFeed")) 583 { 584 productInfoFeed = Dynamicweb.Context.Current.Items["ProductInfoFeed"]?.ToString(); 585 if (!string.IsNullOrEmpty(productInfoFeed)) 586 { 587 productInfoFeed = $"data-product-info-feed=\"{productInfoFeed}\""; 588 } 589 } 590 liveInfoClass = "js-live-info"; 591 } 592 593 <div class="@textAlign @liveInfoClass item_@Model.Item.SystemName.ToLower()" data-product-id="@product.Id" data-variant-id="@product.VariantId" @productInfoFeed> 594 @if (showInformativePrice && product.PriceInformative.Price != 0) 595 { 596 <div class="opacity-50"> 597 <span>@Translate("RRP") </span> 598 <span class="text-decoration-line-through text-price">@product.PriceInformative.PriceFormatted</span> 599 </div> 600 } 601 <div class="@priceFontSize m-0 d-flex flex-wrap @flexDirection @flexGap @horizontalAlign" style="row-gap: 0 !important" itemprop="offers" itemscope itemtype="https://schema.org/Offer"> 602 <span itemprop="priceCurrency" content="@product.Price.CurrencyCode" class="d-none"></span> 603 604 605 @if (showPricesWithVat == "false" && !neverShowVat) 606 { 607 if (isLazyLoadingForProductInfoEnabled && !Pageview.IsVisualEditorMode) 608 { 609 <span itemprop="price" content="" class="d-none"></span> 610 <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> 611 } 612 else 613 { 614 string beforePrice = !string.IsNullOrEmpty(unitId) ? product.GetPrice(unitId).PriceBeforeDiscount.PriceWithoutVatFormatted : product.PriceBeforeDiscount.PriceWithoutVatFormatted; 615 616 <span itemprop="price" content="@product.Price.PriceWithoutVat.ToString("0.00", System.Globalization.CultureInfo.InvariantCulture)" class="d-none"></span> 617 if (product.Price.Price != product.PriceBeforeDiscount.Price) 618 { 619 <span class="text-decoration-line-through opacity-75 @order">@beforePrice</span> 620 } 621 } 622 } 623 else 624 { 625 if (isLazyLoadingForProductInfoEnabled && !Pageview.IsVisualEditorMode) 626 { 627 <span itemprop="price" content="" class="d-none"></span> 628 <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> 629 } 630 else 631 { 632 string beforePrice = !string.IsNullOrEmpty(unitId) ? product.GetPrice(unitId).PriceBeforeDiscount.PriceFormatted : product.PriceBeforeDiscount.PriceFormatted; 633 634 <span itemprop="price" content="@product.Price.Price.ToString("0.00", System.Globalization.CultureInfo.InvariantCulture)" class="d-none"></span> 635 636 if (product.Price.Price != product.PriceBeforeDiscount.Price) 637 { 638 <span class="text-decoration-line-through opacity-75 @order"> 639 <span class="text-price">@beforePrice</span> 640 </span> 641 } 642 } 643 } 644 645 @if (showPricesWithVat == "false" && !neverShowVat) 646 { 647 if (isLazyLoadingForProductInfoEnabled && !Pageview.IsVisualEditorMode) 648 { 649 <span class="text-price js-text-price"> 650 <span class="spinner-border" role="status"></span> 651 </span> 652 } 653 else 654 { 655 string price = !string.IsNullOrEmpty(unitId) ? product.GetPrice(unitId).Price.PriceWithoutVatFormatted : product.Price.PriceWithoutVatFormatted; 656 657 if (product?.VariantInfo?.VariantInfo != null) 658 { 659 priceMin = product?.VariantInfo?.PriceMin?.PriceWithoutVatFormatted != null ? product.VariantInfo.PriceMin.PriceWithoutVatFormatted : ""; 660 priceMax = product?.VariantInfo?.PriceMax?.PriceWithoutVatFormatted != null ? product.VariantInfo.PriceMax.PriceWithoutVatFormatted : ""; 661 } 662 if (priceMin != priceMax) 663 { 664 price = priceMin + " - " + priceMax; 665 } 666 <span class="@theme @contentPadding"> 667 <span class="text-price">@price</span> 668 </span> 669 } 670 } 671 else 672 { 673 if (isLazyLoadingForProductInfoEnabled && !Pageview.IsVisualEditorMode) 674 { 675 <span class="text-price js-text-price"> 676 <span class="spinner-border" role="status"></span> 677 </span> 678 } 679 else 680 { 681 string price = !string.IsNullOrEmpty(unitId) ? product.GetPrice(unitId).Price.PriceFormatted : product.Price.PriceFormatted; 682 683 if (product?.VariantInfo?.VariantInfo != null) 684 { 685 priceMin = product?.VariantInfo?.PriceMin?.PriceFormatted != null ? product.VariantInfo.PriceMin.PriceFormatted : ""; 686 priceMax = product?.VariantInfo?.PriceMax?.PriceFormatted != null ? product.VariantInfo.PriceMax.PriceFormatted : ""; 687 } 688 if (priceMin != priceMax) 689 { 690 price = priceMin + " - " + priceMax; 691 } 692 <span class="@theme @contentPadding"> 693 <span class="text-price">@price</span> 694 </span> 695 } 696 } 697 698 @* Stock state for Schema.org, start *@ 699 @{ 700 Uri url = Dynamicweb.Context.Current.Request.Url; 701 } 702 703 <link itemprop="url" href="@url"> 704 705 @{ 706 bool IsNeverOutOfStock = product.NeverOutOfstock; 707 } 708 709 @if (IsNeverOutOfStock) 710 { 711 <span itemprop="availability" class="d-none">@Translate("Available in stock")</span> 712 } 713 else 714 { 715 if (product.StockLevel > 0) 716 { 717 <span itemprop="availability" class="d-none">InStock</span> 718 } 719 else 720 { 721 <span itemprop="availability" class="d-none">OutOfStock</span> 722 } 723 } 724 @* Stock state for Schema.org, stop *@ 725 726 </div> 727 728 @if (showPricesWithVat == "false" && !neverShowVat) 729 { 730 if (isLazyLoadingForProductInfoEnabled && !Pageview.IsVisualEditorMode) 731 { 732 <small class="opacity-85 fst-normal js-text-price-with-vat d-none" data-suffix="@Translate("Incl. VAT")"></small> 733 } 734 else 735 { 736 string price = !string.IsNullOrEmpty(unitId) ? product.GetPrice(unitId).Price.PriceWithVatFormatted : product.Price.PriceWithVatFormatted; 737 738 if (product?.VariantInfo?.VariantInfo != null) 739 { 740 priceMin = product?.VariantInfo?.PriceMin?.PriceWithVatFormatted != null ? product.VariantInfo.PriceMin.PriceWithVatFormatted : ""; 741 priceMax = product?.VariantInfo?.PriceMax?.PriceWithVatFormatted != null ? product.VariantInfo.PriceMax.PriceWithVatFormatted : ""; 742 } 743 if (priceMin != priceMax) 744 { 745 price = priceMin + " - " + priceMax; 746 } 747 <!-- <small class="opacity-85 fst-normal">@price @Translate("Incl. VAT")</small> --> 748 } 749 } 750 </div> 751 } 752 else if (Pageview.IsVisualEditorMode) 753 { 754 <div class="alert alert-dark m-0" role="alert"> 755 <span>@Translate("No products available")</span> 756 </div> 757 } 758 759 </div> 760 } 761 } 762
TIschlampe Arch XL
Error executing template "Designs/Swift/Paragraph/CustomProductSlider.cshtml"
System.NullReferenceException: Object reference not set to an instance of an object.
   at CompiledRazorTemplates.Dynamic.RazorEngine_3562354021b44d5c892fe73dc2806e4f.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 Dynamicweb.Ecommerce.ProductCatalog 3 @using Dynamicweb.Ecommerce.CustomerExperienceCenter.Favorites 4 @using Dynamicweb.Files 5 @using System.IO 6 @using System.Net 7 @using Dynamicweb.Security.UserManagement 8 9 10 @{ 11 ProductViewModel product = null; 12 if (Dynamicweb.Context.Current.Items.Contains("ProductDetails")) 13 { 14 product = (ProductViewModel)Dynamicweb.Context.Current.Items["ProductDetails"]; 15 } 16 else if (Pageview.Page.Item["DummyProduct"] != null && Pageview.IsVisualEditorMode) 17 { 18 var pageViewModel = Dynamicweb.Frontend.ContentViewModelFactory.CreatePageInfoViewModel(Pageview.Page); 19 ProductListViewModel productList = pageViewModel.Item.GetValue("DummyProduct") != null ? pageViewModel.Item.GetValue("DummyProduct") as ProductListViewModel : new ProductListViewModel(); 20 21 if (productList?.Products is object) 22 { 23 product = productList.Products[0]; 24 } 25 } 26 } 27 28 @{ 29 var currentUser = Pageview?.User; 30 var customerNumber = !string.IsNullOrEmpty(currentUser?.CustomerNumber) 31 ? currentUser.CustomerNumber 32 : ""; 33 } 34 @if (product is object) 35 { 36 string imagePath = product?.DefaultImage?.Value ?? ""; 37 string imagePathUrlEncoded = Dynamicweb.Context.Current.Server.UrlEncode(imagePath); 38 39 string ratio = Model.Item.GetRawValueString("ImageAspectRatio", ""); 40 ratio = ratio != "0" ? ratio : ""; 41 string ratioCssClass = ratio != "" ? " ratio" : ""; 42 string ratioVariable = ratio != "" ? "--bs-aspect-ratio: " + ratio + ";" : ""; 43 44 string width = Model.Item.GetRawValueString("Width", "auto"); 45 int smallImageSize = 640; 46 int largeImageSize = width == "auto" ? 1280 : Convert.ToInt32(width); 47 48 string ImageObjectFit = Model.Item.GetRawValueString("ImageObjectFit", "contain"); 49 50 string imagePathXs = "/Admin/Public/GetImage.ashx?width=" + smallImageSize + "&image=" + imagePathUrlEncoded + "&format=webp"; 51 string imagePathS = "/Admin/Public/GetImage.ashx?width=" + largeImageSize + "&image=" + imagePathUrlEncoded + "&format=webp"; 52 string imagePathFallBack = "/Admin/Public/GetImage.ashx?width=" + largeImageSize + "&image=" + imagePathUrlEncoded + "&format=webp"; 53 54 var badgeParms = new Dictionary<string, object>(); 55 badgeParms.Add("size", "h7"); 56 badgeParms.Add("saleBadgeType", Model.Item.GetRawValue("SaleBadgeType")); 57 badgeParms.Add("saleBadgeCssClassName", Model.Item.GetRawValue("SaleBadgeDesign")); 58 badgeParms.Add("newBadgeCssClassName", Model.Item.GetRawValue("NewBadgeDesign")); 59 badgeParms.Add("newPublicationDays", Model.Item.GetInt32("NewPublicationDays")); 60 badgeParms.Add("campaignBadgesValues", Model.Item.GetList("CampaignBadges")?.GetRawValue().OfType<string>().ToList()); 61 62 string badgeSize = Model.Item.GetRawValueString("BadgeSize", "fs-2"); 63 bool saleBadgeEnabled = !string.IsNullOrWhiteSpace(Model.Item.GetRawValueString("SaleBadgeDesign")) && Model.Item.GetRawValueString("SaleBadgeDesign") != "none" ? true : false; 64 bool newBadgeEnabled = !string.IsNullOrWhiteSpace(Model.Item.GetRawValueString("NewBadgeDesign")) && Model.Item.GetRawValueString("NewBadgeDesign") != "none" ? true : false; 65 66 /*Custom badge*/ 67 var productService = new Dynamicweb.Ecommerce.Products.ProductService(); 68 var currency = Dynamicweb.Ecommerce.Common.Context.Currency.Code; 69 var formatProvider = new System.Globalization.NumberFormatInfo(); 70 formatProvider.NumberDecimalSeparator = "."; 71 formatProvider.NumberGroupSeparator = ","; 72 var MainVariant = productService.GetProductById(product.Id, product.VariantId, false); 73 var fieldValueBlocked = MainVariant?.ProductFieldValues?.GetProductFieldValue("BlockedCustomerList")?.Value; 74 75 76 string isNewProduct = MainVariant?.ProductFieldValues?.GetProductFieldValue("New")?.Value?.ToString().ToLower() ?? ""; 77 string MainisSale = MainVariant?.ProductFieldValues?.GetProductFieldValue("Sale")?.Value?.ToString().ToLower() ?? ""; 78 bool showNewBadge = isNewProduct == "true" ? true : false; 79 bool showSaleBadge = MainisSale == "true" ? true : false; 80 string showNewSaleBadge = "d-none"; 81 if (showSaleBadge) 82 { 83 badgeParms.Add("isSale", "true"); 84 85 } 86 else 87 { 88 badgeParms.Add("isSale", "false"); 89 } 90 if (showNewBadge) 91 { 92 badgeParms.Add("isNew", "true"); 93 } 94 else 95 { 96 badgeParms.Add("isNew", "false"); 97 } 98 /*End Custom badge*/ 99 if (showSaleBadge || showNewBadge) 100 { 101 showNewSaleBadge = ""; 102 } 103 DateTime createdDate = product.Created.Value; 104 bool showBadges = saleBadgeEnabled && product.Discount.Price != 0 ? true : false; 105 106 bool showFavoritesSelector = !string.IsNullOrEmpty(Model.Item.GetString("ShowAddToFavorites")) ? Model.Item.GetBoolean("ShowAddToFavorites") : false; 107 string anonymousUsersLimitations = Pageview.AreaSettings.GetRawValueString("AnonymousUsers", ""); 108 bool anonymousUser = Pageview.User == null; 109 110 var favoriteParameters = new Dictionary<string, object>(); 111 if (!anonymousUser && showFavoritesSelector) 112 { 113 int defaultFavoriteListId = 0; 114 115 IEnumerable<FavoriteList> favoreiteLists = Pageview.User.GetFavoriteLists(); 116 if (favoreiteLists.Count() == 1) 117 { 118 foreach (FavoriteList list in favoreiteLists) 119 { 120 defaultFavoriteListId = list.ListId; 121 } 122 } 123 124 favoriteParameters.Add("ListId", defaultFavoriteListId); 125 } 126 127 MediaViewModel alternativeImage = new MediaViewModel(); 128 if (Model.Item.GetBoolean("ShowAlternativeImageOnHover")) 129 { 130 var selectedImageCategories = Model.Item.GetList("GetAlternativeImageFrom")?.GetRawValue().OfType<string>().ToList(); 131 List<MediaViewModel> allAssetsImages = product.AssetCategories.Where(x => selectedImageCategories.Contains(x.SystemName)).SelectMany(x => x.Assets).ToList(); 132 allAssetsImages.RemoveAll(x => x.Value == product.DefaultImage.Value); 133 alternativeImage = allAssetsImages.FirstOrDefault(); 134 } 135 136 string altImagePathXs = string.Empty; 137 string altImagePathS = string.Empty; 138 139 if (!string.IsNullOrEmpty(alternativeImage?.Value)) 140 { 141 altImagePathXs = "/Admin/Public/GetImage.ashx?width=" + smallImageSize + "&image=" + Dynamicweb.Context.Current.Server.UrlEncode(alternativeImage.Value) + "&format=webp"; 142 altImagePathS = "/Admin/Public/GetImage.ashx?width=" + largeImageSize + "&image=" + Dynamicweb.Context.Current.Server.UrlEncode(alternativeImage.Value) + "&format=webp"; 143 } 144 145 @* Theme settings *@ 146 string theme = !string.IsNullOrWhiteSpace(Model.Item.GetRawValueString("Theme")) ? " theme " + Model.Item.GetRawValueString("Theme").Replace(" ", "").Trim().ToLower() : ""; 147 string themeBorder = !string.IsNullOrWhiteSpace(theme) ? "border: 1px solid rgba(0,0,0,0)" : ""; 148 string themePadding = !string.IsNullOrWhiteSpace(theme) ? "p-2 p-lg-3" : ""; 149 150 string imageId = "ProductImage_" + product.Id; 151 152 153 154 string fullWidth = width == "auto" ? "w-100" : ""; 155 string customWidth = width != "auto" ? "style=\"width: " + width + "px\"" : "style=\"min-width: 60px\""; 156 157 string altImageZindex = Model.Item.GetBoolean("ShowAlternativeImageOnHover") && !string.IsNullOrEmpty(alternativeImage?.Value) ? " z-index: 1" : string.Empty; 158 string groupid = !string.IsNullOrEmpty(Dynamicweb.Context.Current.Request.QueryString.Get("GroupID")) ? Dynamicweb.Context.Current.Request.QueryString.Get("GroupID"):"" ; 159 string link = product.GetProductLink(GetPageIdByNavigationTag("Shop"), false); 160 var productVariantGroups = product.VariantGroups(); 161 string MainOutStock = "<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"25\" height=\"25\" fill=\"#CA0D0D\" class=\"bi bi-x-lg\" viewBox=\"0 0 16 16\"><path d=\"M4.646 4.646a.5.5 0 0 1 .708 0L8 7.293l2.646-2.647a.5.5 0 0 1 .708.708L8.707 8l2.647 2.646a.5.5 0 0 1-.708.708L8 8.707l-2.646 2.647a.5.5 0 0 1-.708-.708L7.293 8 4.646 5.354a.5.5 0 0 1 0-.708\"/></svg>"; 162 163 @if (!string.IsNullOrEmpty(imagePath)) 164 { 165 <div class="@fullWidth @theme position-relative item_@Model.Item.SystemName.ToLower() main-image-container" @customWidth> 166 <div class="" style="@(ratioVariable)@(altImageZindex)"> 167 <div class="d-flex justify-content-center align-items-center"> 168 <a class="main-link-link" href="@link"> 169 @if (imagePath.StartsWith("/Files/", StringComparison.OrdinalIgnoreCase)) 170 { 171 <img id="@imageId" 172 srcset=" 173 @imagePathXs @(smallImageSize)w, 174 @imagePathS @(largeImageSize)w" 175 sizes="(max-width: 992px) 50vw, 25vw" 176 src="@imagePathFallBack" 177 loading="lazy" 178 decoding="async" 179 class="h-100 w-100 @themePadding main-image" 180 style="object-fit: @ImageObjectFit; @themeBorder " 181 alt="@product.Name" 182 itemprop="image"> 183 } 184 else 185 { 186 <img src="@product.DefaultImage.Value" 187 loading="lazy" 188 class="h-100 w-100 @themePadding main-image" 189 style="object-fit: contain; @themeBorder" 190 alt="@product.Name" 191 itemprop="image"> 192 } 193 </a> 194 </div> 195 </div> 196 197 <div class="position-absolute top-0 left-0 p-2 pb-0 custom-badge-product-list @showNewSaleBadge"> 198 @{ 199 @RenderPartial("Components/Custom_EcommerceBadge.cshtml", product, badgeParms) 200 } 201 </div> 202 203 204 </div> 205 } 206 207 <div class="product-info h-100"> 208 <div class="fs-7 pt-1 opacity-85 start item_@Model.Item.SystemName.ToLower() product-number" itemprop="sku">@product.Id / @product.VariantId - @product.VariantName</div> 209 <div class="py-2" data-col-size="12"> 210 <h2 class="h6 start m-0 item_swift_productheader product-name" itemprop="name"><b>@product.Name</b></h2> 211 </div> 212 </div> 213 var sliderId = $"thumb-scroll-{product.Id}"; 214 if (productVariantGroups.Any() && product?.VariantInfo?.VariantInfo != null) 215 216 { 217 @using Dynamicweb.Ecommerce.Prices 218 @{ 219 string[] variantId = product.VariantId.Split('.'); 220 string showPricesWithVat = Pageview.Area.EcomPricesWithVat.ToLower(); 221 bool neverShowVat = string.IsNullOrEmpty(showPricesWithVat); 222 bool showInformativePrice = Model.Item.GetBoolean("ShowInformativePrice"); 223 string productInfoFeed = ""; 224 bool isLazyLoadingForProductInfoEnabled = Dynamicweb.Core.Converter.ToBoolean(Dynamicweb.Context.Current.Items["IsLazyLoadingForProductInfoEnabled"]); 225 if (isLazyLoadingForProductInfoEnabled) 226 { 227 if (Dynamicweb.Context.Current.Items.Contains("ProductInfoFeed")) 228 { 229 productInfoFeed = Dynamicweb.Context.Current.Items["ProductInfoFeed"]?.ToString(); 230 if (!string.IsNullOrEmpty(productInfoFeed)) 231 { 232 productInfoFeed =productInfoFeed; 233 } 234 } 235 236 } 237 string priceMin = ""; 238 string priceMax = ""; 239 int groupNumber = 1; 240 241 242 243 244 string baseUrl = $"Default.aspx?ID={GetPageIdByNavigationTag("Shop")}&GroupID={product.PrimaryOrDefaultGroup.Id}&ProductID={product.Id}"; 245 if (!string.IsNullOrEmpty(baseUrl)) 246 { 247 baseUrl = $"/{baseUrl.TrimStart('/')}"; 248 } 249 string variantUrl = string.Empty; 250 251 252 Dictionary<string, string> 253 variantImages = new Dictionary<string, string> 254 (); 255 <div class="last-row mt-auto"> 256 257 @foreach (var variantGroup in productVariantGroups) 258 { 259 <div class="thumbnail-wrapper"> 260 <button class="thumb-nav prev" onclick="scrollThumbs('@sliderId', -1)"> 261 <svg width="20px" height="20px" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" fill="#1D98A5"> 262 263 <g stroke="none" stroke-width="1" fill="none" fill-rule="evenodd"> 264 <g transform="translate(-336.000000, 0.000000)"> 265 <g id="left_line" transform="translate(336.000000, 0.000000)"> 266 <path d="M24,0 L24,24 L0,24 L0,0 L24,0 Z M12.5934901,23.257841 L12.5819402,23.2595131 L12.5108777,23.2950439 L12.4918791,23.2987469 L12.4918791,23.2987469 L12.4767152,23.2950439 L12.4056548,23.2595131 C12.3958229,23.2563662 12.3870493,23.2590235 12.3821421,23.2649074 L12.3780323,23.275831 L12.360941,23.7031097 L12.3658947,23.7234994 L12.3769048,23.7357139 L12.4804777,23.8096931 L12.4953491,23.8136134 L12.4953491,23.8136134 L12.5071152,23.8096931 L12.6106902,23.7357139 L12.6232938,23.7196733 L12.6232938,23.7196733 L12.6266527,23.7031097 L12.609561,23.275831 C12.6075724,23.2657013 12.6010112,23.2592993 12.5934901,23.257841 L12.5934901,23.257841 Z M12.8583906,23.1452862 L12.8445485,23.1473072 L12.6598443,23.2396597 L12.6498822,23.2499052 L12.6498822,23.2499052 L12.6471943,23.2611114 L12.6650943,23.6906389 L12.6699349,23.7034178 L12.6699349,23.7034178 L12.678386,23.7104931 L12.8793402,23.8032389 C12.8914285,23.8068999 12.9022333,23.8029875 12.9078286,23.7952264 L12.9118235,23.7811639 L12.8776777,23.1665331 C12.8752882,23.1545897 12.8674102,23.1470016 12.8583906,23.1452862 L12.8583906,23.1452862 Z M12.1430473,23.1473072 C12.1332178,23.1423925 12.1221763,23.1452606 12.1156365,23.1525954 L12.1099173,23.1665331 L12.0757714,23.7811639 C12.0751323,23.7926639 12.0828099,23.8018602 12.0926481,23.8045676 L12.108256,23.8032389 L12.3092106,23.7104931 L12.3186497,23.7024347 L12.3186497,23.7024347 L12.3225043,23.6906389 L12.340401,23.2611114 L12.337245,23.2485176 L12.337245,23.2485176 L12.3277531,23.2396597 L12.1430473,23.1473072 Z" id="MingCute" fill-rule="nonzero"> </path> 267 <path d="M8.29292,12.7071 C7.9024,12.3166 7.9024,11.6834 8.29292,11.2929 L13.9498,5.63604 C14.3403,5.24551 14.9735,5.24551 15.364,5.63604 C15.7545,6.02656 15.7545,6.65973 15.364,7.05025 L10.4142,12 L15.364,16.9497 C15.7545,17.3403 15.7545,17.9734 15.364,18.364 C14.9735,18.7545 14.3403,18.7545 13.9498,18.364 L8.29292,12.7071 Z" id="路径" fill="#1D98A5"> </path> 268 </g> 269 </g> 270 </g> 271 </svg> 272 273 </button> 274 <div class="thumbnail-scroll" id="@sliderId"> 275 @{ 276 VariantGroupViewModel group = variantGroup; 277 foreach (var option in group.Options.OrderBy(o => o.Id)) 278 { 279 var productVariant = productService.GetProductById(product.Id, option.Id, false); 280 281 var productSelection = new PriceProductSelection(productVariant, null, 0); 282 283 var currencyCode = string.IsNullOrWhiteSpace(Pageview.User.Currency) ? Pageview.Area.EcomCurrencyId : Pageview.User.Currency; 284 var countryCode = string.IsNullOrWhiteSpace(Pageview.User.CountryCode) ? Pageview.Area.EcomCountryCode : Pageview.User.CountryCode; 285 286 var userCurrency = Dynamicweb.Ecommerce.Services.Currencies.GetCurrency(currencyCode); 287 var userCountry = Dynamicweb.Ecommerce.Services.Countries.GetCountry(countryCode); 288 289 var priceContext = new PriceContext(userCurrency, userCountry, null, Pageview.User, false, null); 290 var productPrice = Dynamicweb.Ecommerce.Services.Prices.FindPrices(priceContext, productSelection, false); 291 292 //throw new Exception(System.Text.Json.JsonSerializer.Serialize(productPrice)); 293 294 var fieldValue = productVariant?.ProductFieldValues?.GetProductFieldValue("BlockedCustomerList")?.Value; 295 296 if ((fieldValue != null && !fieldValue.ToString().Contains(customerNumber)) || String.IsNullOrWhiteSpace(customerNumber)) 297 { 298 299 300 string active = variantId != null && variantId.Contains(option.Id) ? "active" : string.Empty; 301 string buttonId = $"{product.Id}_{option.Id}_{Pageview.CurrentParagraph.ID}"; 302 string contrastColor = string.Empty; 303 304 string searchKey = $"{product.Id}_{option.Id}_"; 305 /*Images*/ 306 var imagePathVariant = option.Image?.Value ?? ""; 307 308 309 var folderPath = Path.GetDirectoryName(imagePathVariant); 310 311 string physicalFolderPath = Dynamicweb.Context.Current.Server.MapPath(folderPath); 312 313 string lastImage = null; 314 315 if (Directory.Exists(physicalFolderPath)) 316 { 317 318 var fileWith15 = Directory.GetFiles(physicalFolderPath) 319 .FirstOrDefault(f => Path.GetFileName(f).Contains($"{product.Id}_{option.Id}_9")); 320 321 if (fileWith15 != null) 322 { 323 lastImage = fileWith15; 324 } 325 else 326 { 327 var files = Directory.GetFiles(physicalFolderPath) 328 .Where(f => Path.GetFileName(f).StartsWith($"{product.Id}_{option.Id}_")) 329 .OrderByDescending(f => 330 { 331 var filename = Path.GetFileNameWithoutExtension(f); 332 var match = System.Text.RegularExpressions.Regex.Match(filename, @"_(\d+)$"); 333 if (match.Success && int.TryParse(match.Groups[1].Value, out int index)) 334 { 335 return index; 336 } 337 return 0; 338 }) 339 .ToList(); 340 341 if (files.Any()) 342 { 343 lastImage = files.First(); 344 } 345 } 346 } 347 348 var lastImageUrl = lastImage != null ? lastImage : "/Files/Images/zijlstra/Afbeeldingen_overig/Coming_Soon.jpg"; 349 int index = lastImageUrl.IndexOf("Files"); 350 string relativePath = index >= 0 ? lastImageUrl.Substring(index).Replace("\\", "/") : lastImageUrl.Replace("\\", "/"); 351 lastImageUrl = "/" + relativePath; 352 lastImageUrl = Dynamicweb.Context.Current.Server.UrlEncode(lastImageUrl); 353 var variantImg = option.Image is object ? Dynamicweb.Context.Current.Server.UrlEncode(option.Image.Value) : null; 354 var variantLink = "/Default.aspx?ID=" + GetPageIdByNavigationTag("Shop") + "&GroupID=" + product.PrimaryOrDefaultGroup.Id + "&ProductID=" + product.Id + "&VariantID=" + option.Id; 355 356 string variantImage = string.Empty; 357 variantImages.TryGetValue(option.Id, out variantImage); 358 /*End Images*/ 359 360 /*stock state*/ 361 double variantStock = productVariant.Stock; 362 string svgInStock = "<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"16\" height=\"16\" fill=\"#44B11A\" class=\"bi bi-check-lg\" viewBox=\"0 0 16 16\"><path d=\"M12.736 3.97a.733.733 0 0 1 1.047 0c.286.289.29.756.01 1.05L7.88 12.01a.733.733 0 0 1-1.065.02L3.217 8.384a.757.757 0 0 1 0-1.06.733.733 0 0 1 1.047 0l3.052 3.093 5.4-6.425z\"/></svg>"; 363 string svgOutStock = "<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"25\" height=\"25\" fill=\"#CA0D0D\" class=\"bi bi-x-lg\" viewBox=\"0 0 16 16\"><path d=\"M4.646 4.646a.5.5 0 0 1 .708 0L8 7.293l2.646-2.647a.5.5 0 0 1 .708.708L8.707 8l2.647 2.646a.5.5 0 0 1-.708.708L8 8.707l-2.646 2.647a.5.5 0 0 1-.708-.708L7.293 8 4.646 5.354a.5.5 0 0 1 0-.708\"/></svg>"; 364 365 string infoStock = "<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"16\" height=\"16\" fill=\"currentColor\" class=\"bi bi-info-circle-fill\" viewBox=\"0 0 16 16\"><path d=\"M8 16A8 8 0 1 0 8 0a8 8 0 0 0 0 16m.93-9.412-1 4.705c-.07.34.029.533.304.533.194 0 .487-.07.686-.246l-.088.416c-.287.346-.92.598-1.465.598-.703 0-1.002-.422-.808-1.319l.738-3.468c.064-.293.006-.399-.287-.47l-.451-.081.082-.381 2.29-.287zM8 5.5a1 1 0 1 1 0-2 1 1 0 0 1 0 2\" /></svg>"; 366 string isNew = productVariant?.ProductFieldValues?.GetProductFieldValue("New")?.Value?.ToString().ToLower() ?? ""; 367 string isNewSvg = "<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"16\" height=\"16\" fill=\"#F2C400\" class=\"bi bi-star-fill\" viewBox=\"0 0 16 16\"><path d = \"M3.612 15.443c-.386.198-.824-.149-.746-.592l.83-4.73L.173 6.765c-.329-.314-.158-.888.283-.95l4.898-.696L7.538.792c.197-.39.73-.39.927 0l2.184 4.327 4.898.696c.441.062.612.636.282.95l-3.522 3.356.83 4.73c.078.443-.36.79-.746.592L8 13.187l-4.389 2.256z\" /></svg> "; 368 string stockState = ""; 369 370 string isSale = productVariant?.ProductFieldValues?.GetProductFieldValue("Sale")?.Value?.ToString().ToLower() ?? ""; 371 string isSaleSvg = "<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"16\" height=\"16\" fill=\"#F03232\" class=\"bi bi-star-fill\" viewBox=\"0 0 16 16\"><path d = \"M3.612 15.443c-.386.198-.824-.149-.746-.592l.83-4.73L.173 6.765c-.329-.314-.158-.888.283-.95l4.898-.696L7.538.792c.197-.39.73-.39.927 0l2.184 4.327 4.898.696c.441.062.612.636.282.95l-3.522 3.356.83 4.73c.078.443-.36.79-.746.592L8 13.187l-4.389 2.256z\" /></svg> "; 372 373 string expectedDeliveryDate = ""; 374 375 if (DateTime.Compare(productVariant.ExpectedDelivery, new DateTime(1900, 1, 1)) != 0) //In DW, if the Date is not set, it is defaulted 01-01-1900 and not null.. 376 { 377 expectedDeliveryDate = productVariant.ExpectedDelivery.ToShortDateString(); 378 } 379 380 string expectedDeliveryDateText = !String.IsNullOrWhiteSpace(expectedDeliveryDate) ? Translate("Verwacht:") + "&nbsp;" + expectedDeliveryDate : ""; 381 382 @if (!(bool?)productVariant.ProductFieldValues.Where(o => o.ProductField.SystemName == "ProductToBeDiscontinued").SingleOrDefault()?.Value ?? false) 383 { 384 if (variantStock > 0) 385 { 386 if (isNew == "true" || isSale == "true") 387 { 388 if (isSale == "true") 389 { 390 stockState += isSaleSvg + "&nbsp; &nbsp;" + Translate("Sale!") + "<br/>"; 391 } 392 393 if (isNew == "true") 394 { 395 stockState += isNewSvg + "&nbsp; &nbsp;" + Translate("New!") + "<br/>"; 396 } 397 398 stockState += "&nbsp;" + Translate("Nu leverbaar"); 399 } 400 else 401 { 402 stockState = svgInStock + "&nbsp; " + Translate("Op voorraad"); 403 404 } 405 } 406 else 407 { 408 stockState = svgOutStock + "&nbsp;" + Translate("Geen voorraad") + "<br/>" + expectedDeliveryDateText; 409 410 } 411 } 412 else 413 { 414 415 stockState = svgOutStock + "&nbsp;" + Translate("Discontinued:") + "<br/>" + variantStock + "&nbsp;" + @Translate("left in stock"); 416 417 } 418 /*End stock state*/ 419 /*Price variants*/ 420 double price = productVariant.DefaultPrice; 421 double cost = productVariant.Cost; 422 423 string priceFormated = Dynamicweb.Ecommerce.Services.Currencies.Format(Dynamicweb.Ecommerce.Services.Currencies.GetCurrency(currency), Convert.ToDouble(productPrice.ToList()[0].Amount, formatProvider)); 424 //string priceFormated = Dynamicweb.Ecommerce.Services.Currencies.Format(Dynamicweb.Ecommerce.Services.Currencies.GetCurrency(currency), Convert.ToDouble(price, formatProvider)); 425 426 427 428 /*End Price variants*/ 429 430 <img class="theme thumbnail" data-stockstate="@WebUtility.HtmlEncode(stockState)" src="/Admin/Public/GetImage.ashx?image=@(lastImageUrl)&width=64&format=webp" onclick="selectVariant('@(product.Id)','/Admin/Public/GetImage.ashx?image=@(variantImg)&format=webp','@variantLink','@product.Id','@option.Id','@option.Name',this.dataset.stockstate,'@isNew','@isSale','@priceFormated','@cost')" /> 431 432 433 } 434 } 435 436 } 437 </div> 438 <button class="thumb-nav next" onclick="scrollThumbs('@sliderId', 1)"> 439 <svg width="20px" height="20px" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" fill="#1D98A5"> 440 441 <g stroke="none" stroke-width="1" fill="none" fill-rule="evenodd"> 442 <g transform="translate(-384.000000, 0.000000)"> 443 <g id="right_line" transform="translate(384.000000, 0.000000)"> 444 <path d="M24,0 L24,24 L0,24 L0,0 L24,0 Z M12.5934901,23.257841 L12.5819402,23.2595131 L12.5108777,23.2950439 L12.4918791,23.2987469 L12.4918791,23.2987469 L12.4767152,23.2950439 L12.4056548,23.2595131 C12.3958229,23.2563662 12.3870493,23.2590235 12.3821421,23.2649074 L12.3780323,23.275831 L12.360941,23.7031097 L12.3658947,23.7234994 L12.3769048,23.7357139 L12.4804777,23.8096931 L12.4953491,23.8136134 L12.4953491,23.8136134 L12.5071152,23.8096931 L12.6106902,23.7357139 L12.6232938,23.7196733 L12.6232938,23.7196733 L12.6266527,23.7031097 L12.609561,23.275831 C12.6075724,23.2657013 12.6010112,23.2592993 12.5934901,23.257841 L12.5934901,23.257841 Z M12.8583906,23.1452862 L12.8445485,23.1473072 L12.6598443,23.2396597 L12.6498822,23.2499052 L12.6498822,23.2499052 L12.6471943,23.2611114 L12.6650943,23.6906389 L12.6699349,23.7034178 L12.6699349,23.7034178 L12.678386,23.7104931 L12.8793402,23.8032389 C12.8914285,23.8068999 12.9022333,23.8029875 12.9078286,23.7952264 L12.9118235,23.7811639 L12.8776777,23.1665331 C12.8752882,23.1545897 12.8674102,23.1470016 12.8583906,23.1452862 L12.8583906,23.1452862 Z M12.1430473,23.1473072 C12.1332178,23.1423925 12.1221763,23.1452606 12.1156365,23.1525954 L12.1099173,23.1665331 L12.0757714,23.7811639 C12.0751323,23.7926639 12.0828099,23.8018602 12.0926481,23.8045676 L12.108256,23.8032389 L12.3092106,23.7104931 L12.3186497,23.7024347 L12.3186497,23.7024347 L12.3225043,23.6906389 L12.340401,23.2611114 L12.337245,23.2485176 L12.337245,23.2485176 L12.3277531,23.2396597 L12.1430473,23.1473072 Z" id="MingCute" fill-rule="nonzero"> </path> 445 <path d="M15.7072,11.2929 C16.0977,11.6834 16.0977,12.3166 15.7072,12.7071 L10.0503,18.364 C9.65982,18.7545 9.02666,18.7545 8.63613,18.364 C8.24561,17.9734 8.24561,17.3403 8.63613,16.9497 L13.5859,12 L8.63613,7.05025 C8.24561,6.65973 8.24561,6.02656 8.63613,5.63604 C9.02666,5.24551 9.65982,5.24551 10.0503,5.63604 L15.7072,11.2929 Z" id="路径" fill="#1D98A5"> </path> 446 </g> 447 </g> 448 449 </svg> 450 451 </button> 452 </div> 453 } 454 455 456 </div> 457 458 } 459 if ((fieldValueBlocked != null && !fieldValueBlocked.ToString().Contains(customerNumber)) || String.IsNullOrWhiteSpace(customerNumber)) 460 { 461 <div class="stock-state pt-2 mt-auto"> 462 @{ 463 464 /*stock state*/ 465 double MainvariantStock = MainVariant.Stock; 466 string MainsvgInStock = "<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"16\" height=\"16\" fill=\"#44B11A\" class=\"bi bi-check-lg\" viewBox=\"0 0 16 16\"><path d=\"M12.736 3.97a.733.733 0 0 1 1.047 0c.286.289.29.756.01 1.05L7.88 12.01a.733.733 0 0 1-1.065.02L3.217 8.384a.757.757 0 0 1 0-1.06.733.733 0 0 1 1.047 0l3.052 3.093 5.4-6.425z\"/></svg>"; 467 string MainsvgOutStock = "<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"25\" height=\"25\" fill=\"#CA0D0D\" class=\"bi bi-x-lg\" viewBox=\"0 0 16 16\"><path d=\"M4.646 4.646a.5.5 0 0 1 .708 0L8 7.293l2.646-2.647a.5.5 0 0 1 .708.708L8.707 8l2.647 2.646a.5.5 0 0 1-.708.708L8 8.707l-2.646 2.647a.5.5 0 0 1-.708-.708L7.293 8 4.646 5.354a.5.5 0 0 1 0-.708\"/></svg>"; 468 469 string MaininfoStock = "<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"16\" height=\"16\" fill=\"currentColor\" class=\"bi bi-info-circle-fill\" viewBox=\"0 0 16 16\"><path d=\"M8 16A8 8 0 1 0 8 0a8 8 0 0 0 0 16m.93-9.412-1 4.705c-.07.34.029.533.304.533.194 0 .487-.07.686-.246l-.088.416c-.287.346-.92.598-1.465.598-.703 0-1.002-.422-.808-1.319l.738-3.468c.064-.293.006-.399-.287-.47l-.451-.081.082-.381 2.29-.287zM8 5.5a1 1 0 1 1 0-2 1 1 0 0 1 0 2\" /></svg>"; 470 string MainisNew = MainVariant?.ProductFieldValues?.GetProductFieldValue("New")?.Value?.ToString().ToLower() ?? ""; 471 string MainisNewSvg = "<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"16\" height=\"16\" fill=\"#F2C400\" class=\"bi bi-star-fill\" viewBox=\"0 0 16 16\"><path d = \"M3.612 15.443c-.386.198-.824-.149-.746-.592l.83-4.73L.173 6.765c-.329-.314-.158-.888.283-.95l4.898-.696L7.538.792c.197-.39.73-.39.927 0l2.184 4.327 4.898.696c.441.062.612.636.282.95l-3.522 3.356.83 4.73c.078.443-.36.79-.746.592L8 13.187l-4.389 2.256z\" /></svg> "; 472 string MainstockState = ""; 473 string MainIsSale = MainVariant?.ProductFieldValues?.GetProductFieldValue("Sale")?.Value?.ToString().ToLower() ?? ""; 474 string MainIsSaleSvg = "<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"16\" height=\"16\" fill=\"#F03232\" class=\"bi bi-star-fill\" viewBox=\"0 0 16 16\"><path d = \"M3.612 15.443c-.386.198-.824-.149-.746-.592l.83-4.73L.173 6.765c-.329-.314-.158-.888.283-.95l4.898-.696L7.538.792c.197-.39.73-.39.927 0l2.184 4.327 4.898.696c.441.062.612.636.282.95l-3.522 3.356.83 4.73c.078.443-.36.79-.746.592L8 13.187l-4.389 2.256z\" /></svg> "; 475 string MainexpectedDeliveryDate = ""; 476 477 if (DateTime.Compare(MainVariant.ExpectedDelivery, new DateTime(1900, 1, 1)) != 0) //In DW, if the Date is not set, it is defaulted 01-01-1900 and not null.. 478 { 479 MainexpectedDeliveryDate = MainVariant.ExpectedDelivery.ToShortDateString(); 480 } 481 482 string MainexpectedDeliveryDateText = !String.IsNullOrWhiteSpace(MainexpectedDeliveryDate) ? Translate("Verwacht:") + "&nbsp;" + MainexpectedDeliveryDate : ""; 483 484 @if (!(bool?)MainVariant.ProductFieldValues.Where(o => o.ProductField.SystemName == "ProductToBeDiscontinued").SingleOrDefault()?.Value ?? false) 485 { 486 if (MainvariantStock > 0) 487 { 488 if (MainisNew == "true" || MainIsSale == "true") 489 { 490 if (MainIsSale == "true") 491 { 492 MainstockState += MainIsSaleSvg + "&nbsp; &nbsp;" + Translate("Sale!") + "<br/>"; 493 } 494 495 if (MainisNew == "true") 496 { 497 MainstockState += MainisNewSvg + "&nbsp; &nbsp;" + Translate("New!") + "<br/>"; 498 } 499 500 MainstockState += "&nbsp;" + Translate("Nu leverbaar"); 501 } 502 else 503 { 504 MainstockState = MainsvgInStock + "&nbsp; " + Translate("Op voorraad"); 505 506 } 507 } 508 else 509 { 510 MainstockState = MainsvgOutStock + "&nbsp;" + Translate("Geen voorraad") + "<br/>" + MainexpectedDeliveryDateText; 511 512 } 513 } 514 else 515 { 516 517 MainstockState = MainsvgOutStock + "&nbsp;" + Translate("Discontinued:") + "<br/>" + MainvariantStock + "&nbsp;" + @Translate("left in stock"); 518 519 } 520 /*End stock state*/ 521 522 523 @MainstockState 524 525 526 } 527 </div> 528 } 529 else 530 { 531 <div class="stock-state pt-2 mt-auto"> 532 @MainOutStock @Translate("Discontinued") 533 </div> 534 } 535 <div class="custom-price mt-auto"> 536 @{ 537 538 539 540 541 bool isErpConnectionDown = !Dynamicweb.Core.Converter.ToBoolean(Dynamicweb.Context.Current.Items["IsWebServiceConnectionAvailable"]); 542 bool hidePrice = anonymousUsersLimitations.Contains("price") && anonymousUser || Pageview.AreaSettings.GetBoolean("ErpDownHidePrices") && isErpConnectionDown; 543 544 bool productIsDiscontinued = product is object && product.Discontinued; 545 bool doNotShowPriceIfProductIsDiscontinued = Model.Item.GetBoolean("DoNotShowPriceIfProductIsDiscontinued"); 546 var isDiscontinued = productIsDiscontinued && doNotShowPriceIfProductIsDiscontinued; 547 } 548 549 @if (product is object && !hidePrice && !isDiscontinued) 550 { 551 string unitId = !string.IsNullOrEmpty(Dynamicweb.Context.Current.Request.Form.Get("UnitId")) ? Dynamicweb.Context.Current.Request.Form.Get("UnitId") : string.Empty; 552 553 string priceFontSize = Model.Item.GetRawValueString("PriceSize", "fs-4"); 554 string horizontalAlign = Model.Item.GetRawValueString("HorizontalAlignment", ""); 555 string layout = Model.Item.GetRawValueString("Layout", "horizontal"); 556 string textAlign = horizontalAlign == "center" ? "text-center" : string.Empty; 557 textAlign = horizontalAlign == "end" ? "text-end" : textAlign; 558 559 horizontalAlign = horizontalAlign == "center" && layout == "horizontal" ? "justify-content-center" : horizontalAlign; 560 horizontalAlign = horizontalAlign == "end" && layout == "horizontal" ? "justify-content-end" : horizontalAlign; 561 horizontalAlign = horizontalAlign == "center" && layout == "vertical" ? "align-items-center" : horizontalAlign; 562 horizontalAlign = horizontalAlign == "end" && layout == "vertical" ? "align-items-end" : horizontalAlign; 563 564 string flexDirection = layout == "horizontal" ? string.Empty : "flex-column"; 565 string flexGap = layout == "horizontal" ? "gap-3" : string.Empty; 566 string order = layout == "horizontal" ? string.Empty : "order-2"; 567 568 569 string contentPadding = Model.Item.GetRawValueString("ContentPadding", ""); 570 contentPadding = contentPadding == "none" ? "p-0" : contentPadding; 571 contentPadding = contentPadding == "small" ? "p-1 px-md-2 py-md-1" : contentPadding; 572 contentPadding = contentPadding == "large" ? "p-2 px-md-3 py-md-2" : contentPadding; 573 string liveInfoClass = ""; 574 575 576 577 578 579 580 if (isLazyLoadingForProductInfoEnabled) 581 { 582 if (Dynamicweb.Context.Current.Items.Contains("ProductInfoFeed")) 583 { 584 productInfoFeed = Dynamicweb.Context.Current.Items["ProductInfoFeed"]?.ToString(); 585 if (!string.IsNullOrEmpty(productInfoFeed)) 586 { 587 productInfoFeed = $"data-product-info-feed=\"{productInfoFeed}\""; 588 } 589 } 590 liveInfoClass = "js-live-info"; 591 } 592 593 <div class="@textAlign @liveInfoClass item_@Model.Item.SystemName.ToLower()" data-product-id="@product.Id" data-variant-id="@product.VariantId" @productInfoFeed> 594 @if (showInformativePrice && product.PriceInformative.Price != 0) 595 { 596 <div class="opacity-50"> 597 <span>@Translate("RRP") </span> 598 <span class="text-decoration-line-through text-price">@product.PriceInformative.PriceFormatted</span> 599 </div> 600 } 601 <div class="@priceFontSize m-0 d-flex flex-wrap @flexDirection @flexGap @horizontalAlign" style="row-gap: 0 !important" itemprop="offers" itemscope itemtype="https://schema.org/Offer"> 602 <span itemprop="priceCurrency" content="@product.Price.CurrencyCode" class="d-none"></span> 603 604 605 @if (showPricesWithVat == "false" && !neverShowVat) 606 { 607 if (isLazyLoadingForProductInfoEnabled && !Pageview.IsVisualEditorMode) 608 { 609 <span itemprop="price" content="" class="d-none"></span> 610 <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> 611 } 612 else 613 { 614 string beforePrice = !string.IsNullOrEmpty(unitId) ? product.GetPrice(unitId).PriceBeforeDiscount.PriceWithoutVatFormatted : product.PriceBeforeDiscount.PriceWithoutVatFormatted; 615 616 <span itemprop="price" content="@product.Price.PriceWithoutVat.ToString("0.00", System.Globalization.CultureInfo.InvariantCulture)" class="d-none"></span> 617 if (product.Price.Price != product.PriceBeforeDiscount.Price) 618 { 619 <span class="text-decoration-line-through opacity-75 @order">@beforePrice</span> 620 } 621 } 622 } 623 else 624 { 625 if (isLazyLoadingForProductInfoEnabled && !Pageview.IsVisualEditorMode) 626 { 627 <span itemprop="price" content="" class="d-none"></span> 628 <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> 629 } 630 else 631 { 632 string beforePrice = !string.IsNullOrEmpty(unitId) ? product.GetPrice(unitId).PriceBeforeDiscount.PriceFormatted : product.PriceBeforeDiscount.PriceFormatted; 633 634 <span itemprop="price" content="@product.Price.Price.ToString("0.00", System.Globalization.CultureInfo.InvariantCulture)" class="d-none"></span> 635 636 if (product.Price.Price != product.PriceBeforeDiscount.Price) 637 { 638 <span class="text-decoration-line-through opacity-75 @order"> 639 <span class="text-price">@beforePrice</span> 640 </span> 641 } 642 } 643 } 644 645 @if (showPricesWithVat == "false" && !neverShowVat) 646 { 647 if (isLazyLoadingForProductInfoEnabled && !Pageview.IsVisualEditorMode) 648 { 649 <span class="text-price js-text-price"> 650 <span class="spinner-border" role="status"></span> 651 </span> 652 } 653 else 654 { 655 string price = !string.IsNullOrEmpty(unitId) ? product.GetPrice(unitId).Price.PriceWithoutVatFormatted : product.Price.PriceWithoutVatFormatted; 656 657 if (product?.VariantInfo?.VariantInfo != null) 658 { 659 priceMin = product?.VariantInfo?.PriceMin?.PriceWithoutVatFormatted != null ? product.VariantInfo.PriceMin.PriceWithoutVatFormatted : ""; 660 priceMax = product?.VariantInfo?.PriceMax?.PriceWithoutVatFormatted != null ? product.VariantInfo.PriceMax.PriceWithoutVatFormatted : ""; 661 } 662 if (priceMin != priceMax) 663 { 664 price = priceMin + " - " + priceMax; 665 } 666 <span class="@theme @contentPadding"> 667 <span class="text-price">@price</span> 668 </span> 669 } 670 } 671 else 672 { 673 if (isLazyLoadingForProductInfoEnabled && !Pageview.IsVisualEditorMode) 674 { 675 <span class="text-price js-text-price"> 676 <span class="spinner-border" role="status"></span> 677 </span> 678 } 679 else 680 { 681 string price = !string.IsNullOrEmpty(unitId) ? product.GetPrice(unitId).Price.PriceFormatted : product.Price.PriceFormatted; 682 683 if (product?.VariantInfo?.VariantInfo != null) 684 { 685 priceMin = product?.VariantInfo?.PriceMin?.PriceFormatted != null ? product.VariantInfo.PriceMin.PriceFormatted : ""; 686 priceMax = product?.VariantInfo?.PriceMax?.PriceFormatted != null ? product.VariantInfo.PriceMax.PriceFormatted : ""; 687 } 688 if (priceMin != priceMax) 689 { 690 price = priceMin + " - " + priceMax; 691 } 692 <span class="@theme @contentPadding"> 693 <span class="text-price">@price</span> 694 </span> 695 } 696 } 697 698 @* Stock state for Schema.org, start *@ 699 @{ 700 Uri url = Dynamicweb.Context.Current.Request.Url; 701 } 702 703 <link itemprop="url" href="@url"> 704 705 @{ 706 bool IsNeverOutOfStock = product.NeverOutOfstock; 707 } 708 709 @if (IsNeverOutOfStock) 710 { 711 <span itemprop="availability" class="d-none">@Translate("Available in stock")</span> 712 } 713 else 714 { 715 if (product.StockLevel > 0) 716 { 717 <span itemprop="availability" class="d-none">InStock</span> 718 } 719 else 720 { 721 <span itemprop="availability" class="d-none">OutOfStock</span> 722 } 723 } 724 @* Stock state for Schema.org, stop *@ 725 726 </div> 727 728 @if (showPricesWithVat == "false" && !neverShowVat) 729 { 730 if (isLazyLoadingForProductInfoEnabled && !Pageview.IsVisualEditorMode) 731 { 732 <small class="opacity-85 fst-normal js-text-price-with-vat d-none" data-suffix="@Translate("Incl. VAT")"></small> 733 } 734 else 735 { 736 string price = !string.IsNullOrEmpty(unitId) ? product.GetPrice(unitId).Price.PriceWithVatFormatted : product.Price.PriceWithVatFormatted; 737 738 if (product?.VariantInfo?.VariantInfo != null) 739 { 740 priceMin = product?.VariantInfo?.PriceMin?.PriceWithVatFormatted != null ? product.VariantInfo.PriceMin.PriceWithVatFormatted : ""; 741 priceMax = product?.VariantInfo?.PriceMax?.PriceWithVatFormatted != null ? product.VariantInfo.PriceMax.PriceWithVatFormatted : ""; 742 } 743 if (priceMin != priceMax) 744 { 745 price = priceMin + " - " + priceMax; 746 } 747 <!-- <small class="opacity-85 fst-normal">@price @Translate("Incl. VAT")</small> --> 748 } 749 } 750 </div> 751 } 752 else if (Pageview.IsVisualEditorMode) 753 { 754 <div class="alert alert-dark m-0" role="alert"> 755 <span>@Translate("No products available")</span> 756 </div> 757 } 758 759 </div> 760 } 761 } 762
Tischlampe rock chromed
Error executing template "Designs/Swift/Paragraph/CustomProductSlider.cshtml"
System.NullReferenceException: Object reference not set to an instance of an object.
   at CompiledRazorTemplates.Dynamic.RazorEngine_3562354021b44d5c892fe73dc2806e4f.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 Dynamicweb.Ecommerce.ProductCatalog 3 @using Dynamicweb.Ecommerce.CustomerExperienceCenter.Favorites 4 @using Dynamicweb.Files 5 @using System.IO 6 @using System.Net 7 @using Dynamicweb.Security.UserManagement 8 9 10 @{ 11 ProductViewModel product = null; 12 if (Dynamicweb.Context.Current.Items.Contains("ProductDetails")) 13 { 14 product = (ProductViewModel)Dynamicweb.Context.Current.Items["ProductDetails"]; 15 } 16 else if (Pageview.Page.Item["DummyProduct"] != null && Pageview.IsVisualEditorMode) 17 { 18 var pageViewModel = Dynamicweb.Frontend.ContentViewModelFactory.CreatePageInfoViewModel(Pageview.Page); 19 ProductListViewModel productList = pageViewModel.Item.GetValue("DummyProduct") != null ? pageViewModel.Item.GetValue("DummyProduct") as ProductListViewModel : new ProductListViewModel(); 20 21 if (productList?.Products is object) 22 { 23 product = productList.Products[0]; 24 } 25 } 26 } 27 28 @{ 29 var currentUser = Pageview?.User; 30 var customerNumber = !string.IsNullOrEmpty(currentUser?.CustomerNumber) 31 ? currentUser.CustomerNumber 32 : ""; 33 } 34 @if (product is object) 35 { 36 string imagePath = product?.DefaultImage?.Value ?? ""; 37 string imagePathUrlEncoded = Dynamicweb.Context.Current.Server.UrlEncode(imagePath); 38 39 string ratio = Model.Item.GetRawValueString("ImageAspectRatio", ""); 40 ratio = ratio != "0" ? ratio : ""; 41 string ratioCssClass = ratio != "" ? " ratio" : ""; 42 string ratioVariable = ratio != "" ? "--bs-aspect-ratio: " + ratio + ";" : ""; 43 44 string width = Model.Item.GetRawValueString("Width", "auto"); 45 int smallImageSize = 640; 46 int largeImageSize = width == "auto" ? 1280 : Convert.ToInt32(width); 47 48 string ImageObjectFit = Model.Item.GetRawValueString("ImageObjectFit", "contain"); 49 50 string imagePathXs = "/Admin/Public/GetImage.ashx?width=" + smallImageSize + "&image=" + imagePathUrlEncoded + "&format=webp"; 51 string imagePathS = "/Admin/Public/GetImage.ashx?width=" + largeImageSize + "&image=" + imagePathUrlEncoded + "&format=webp"; 52 string imagePathFallBack = "/Admin/Public/GetImage.ashx?width=" + largeImageSize + "&image=" + imagePathUrlEncoded + "&format=webp"; 53 54 var badgeParms = new Dictionary<string, object>(); 55 badgeParms.Add("size", "h7"); 56 badgeParms.Add("saleBadgeType", Model.Item.GetRawValue("SaleBadgeType")); 57 badgeParms.Add("saleBadgeCssClassName", Model.Item.GetRawValue("SaleBadgeDesign")); 58 badgeParms.Add("newBadgeCssClassName", Model.Item.GetRawValue("NewBadgeDesign")); 59 badgeParms.Add("newPublicationDays", Model.Item.GetInt32("NewPublicationDays")); 60 badgeParms.Add("campaignBadgesValues", Model.Item.GetList("CampaignBadges")?.GetRawValue().OfType<string>().ToList()); 61 62 string badgeSize = Model.Item.GetRawValueString("BadgeSize", "fs-2"); 63 bool saleBadgeEnabled = !string.IsNullOrWhiteSpace(Model.Item.GetRawValueString("SaleBadgeDesign")) && Model.Item.GetRawValueString("SaleBadgeDesign") != "none" ? true : false; 64 bool newBadgeEnabled = !string.IsNullOrWhiteSpace(Model.Item.GetRawValueString("NewBadgeDesign")) && Model.Item.GetRawValueString("NewBadgeDesign") != "none" ? true : false; 65 66 /*Custom badge*/ 67 var productService = new Dynamicweb.Ecommerce.Products.ProductService(); 68 var currency = Dynamicweb.Ecommerce.Common.Context.Currency.Code; 69 var formatProvider = new System.Globalization.NumberFormatInfo(); 70 formatProvider.NumberDecimalSeparator = "."; 71 formatProvider.NumberGroupSeparator = ","; 72 var MainVariant = productService.GetProductById(product.Id, product.VariantId, false); 73 var fieldValueBlocked = MainVariant?.ProductFieldValues?.GetProductFieldValue("BlockedCustomerList")?.Value; 74 75 76 string isNewProduct = MainVariant?.ProductFieldValues?.GetProductFieldValue("New")?.Value?.ToString().ToLower() ?? ""; 77 string MainisSale = MainVariant?.ProductFieldValues?.GetProductFieldValue("Sale")?.Value?.ToString().ToLower() ?? ""; 78 bool showNewBadge = isNewProduct == "true" ? true : false; 79 bool showSaleBadge = MainisSale == "true" ? true : false; 80 string showNewSaleBadge = "d-none"; 81 if (showSaleBadge) 82 { 83 badgeParms.Add("isSale", "true"); 84 85 } 86 else 87 { 88 badgeParms.Add("isSale", "false"); 89 } 90 if (showNewBadge) 91 { 92 badgeParms.Add("isNew", "true"); 93 } 94 else 95 { 96 badgeParms.Add("isNew", "false"); 97 } 98 /*End Custom badge*/ 99 if (showSaleBadge || showNewBadge) 100 { 101 showNewSaleBadge = ""; 102 } 103 DateTime createdDate = product.Created.Value; 104 bool showBadges = saleBadgeEnabled && product.Discount.Price != 0 ? true : false; 105 106 bool showFavoritesSelector = !string.IsNullOrEmpty(Model.Item.GetString("ShowAddToFavorites")) ? Model.Item.GetBoolean("ShowAddToFavorites") : false; 107 string anonymousUsersLimitations = Pageview.AreaSettings.GetRawValueString("AnonymousUsers", ""); 108 bool anonymousUser = Pageview.User == null; 109 110 var favoriteParameters = new Dictionary<string, object>(); 111 if (!anonymousUser && showFavoritesSelector) 112 { 113 int defaultFavoriteListId = 0; 114 115 IEnumerable<FavoriteList> favoreiteLists = Pageview.User.GetFavoriteLists(); 116 if (favoreiteLists.Count() == 1) 117 { 118 foreach (FavoriteList list in favoreiteLists) 119 { 120 defaultFavoriteListId = list.ListId; 121 } 122 } 123 124 favoriteParameters.Add("ListId", defaultFavoriteListId); 125 } 126 127 MediaViewModel alternativeImage = new MediaViewModel(); 128 if (Model.Item.GetBoolean("ShowAlternativeImageOnHover")) 129 { 130 var selectedImageCategories = Model.Item.GetList("GetAlternativeImageFrom")?.GetRawValue().OfType<string>().ToList(); 131 List<MediaViewModel> allAssetsImages = product.AssetCategories.Where(x => selectedImageCategories.Contains(x.SystemName)).SelectMany(x => x.Assets).ToList(); 132 allAssetsImages.RemoveAll(x => x.Value == product.DefaultImage.Value); 133 alternativeImage = allAssetsImages.FirstOrDefault(); 134 } 135 136 string altImagePathXs = string.Empty; 137 string altImagePathS = string.Empty; 138 139 if (!string.IsNullOrEmpty(alternativeImage?.Value)) 140 { 141 altImagePathXs = "/Admin/Public/GetImage.ashx?width=" + smallImageSize + "&image=" + Dynamicweb.Context.Current.Server.UrlEncode(alternativeImage.Value) + "&format=webp"; 142 altImagePathS = "/Admin/Public/GetImage.ashx?width=" + largeImageSize + "&image=" + Dynamicweb.Context.Current.Server.UrlEncode(alternativeImage.Value) + "&format=webp"; 143 } 144 145 @* Theme settings *@ 146 string theme = !string.IsNullOrWhiteSpace(Model.Item.GetRawValueString("Theme")) ? " theme " + Model.Item.GetRawValueString("Theme").Replace(" ", "").Trim().ToLower() : ""; 147 string themeBorder = !string.IsNullOrWhiteSpace(theme) ? "border: 1px solid rgba(0,0,0,0)" : ""; 148 string themePadding = !string.IsNullOrWhiteSpace(theme) ? "p-2 p-lg-3" : ""; 149 150 string imageId = "ProductImage_" + product.Id; 151 152 153 154 string fullWidth = width == "auto" ? "w-100" : ""; 155 string customWidth = width != "auto" ? "style=\"width: " + width + "px\"" : "style=\"min-width: 60px\""; 156 157 string altImageZindex = Model.Item.GetBoolean("ShowAlternativeImageOnHover") && !string.IsNullOrEmpty(alternativeImage?.Value) ? " z-index: 1" : string.Empty; 158 string groupid = !string.IsNullOrEmpty(Dynamicweb.Context.Current.Request.QueryString.Get("GroupID")) ? Dynamicweb.Context.Current.Request.QueryString.Get("GroupID"):"" ; 159 string link = product.GetProductLink(GetPageIdByNavigationTag("Shop"), false); 160 var productVariantGroups = product.VariantGroups(); 161 string MainOutStock = "<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"25\" height=\"25\" fill=\"#CA0D0D\" class=\"bi bi-x-lg\" viewBox=\"0 0 16 16\"><path d=\"M4.646 4.646a.5.5 0 0 1 .708 0L8 7.293l2.646-2.647a.5.5 0 0 1 .708.708L8.707 8l2.647 2.646a.5.5 0 0 1-.708.708L8 8.707l-2.646 2.647a.5.5 0 0 1-.708-.708L7.293 8 4.646 5.354a.5.5 0 0 1 0-.708\"/></svg>"; 162 163 @if (!string.IsNullOrEmpty(imagePath)) 164 { 165 <div class="@fullWidth @theme position-relative item_@Model.Item.SystemName.ToLower() main-image-container" @customWidth> 166 <div class="" style="@(ratioVariable)@(altImageZindex)"> 167 <div class="d-flex justify-content-center align-items-center"> 168 <a class="main-link-link" href="@link"> 169 @if (imagePath.StartsWith("/Files/", StringComparison.OrdinalIgnoreCase)) 170 { 171 <img id="@imageId" 172 srcset=" 173 @imagePathXs @(smallImageSize)w, 174 @imagePathS @(largeImageSize)w" 175 sizes="(max-width: 992px) 50vw, 25vw" 176 src="@imagePathFallBack" 177 loading="lazy" 178 decoding="async" 179 class="h-100 w-100 @themePadding main-image" 180 style="object-fit: @ImageObjectFit; @themeBorder " 181 alt="@product.Name" 182 itemprop="image"> 183 } 184 else 185 { 186 <img src="@product.DefaultImage.Value" 187 loading="lazy" 188 class="h-100 w-100 @themePadding main-image" 189 style="object-fit: contain; @themeBorder" 190 alt="@product.Name" 191 itemprop="image"> 192 } 193 </a> 194 </div> 195 </div> 196 197 <div class="position-absolute top-0 left-0 p-2 pb-0 custom-badge-product-list @showNewSaleBadge"> 198 @{ 199 @RenderPartial("Components/Custom_EcommerceBadge.cshtml", product, badgeParms) 200 } 201 </div> 202 203 204 </div> 205 } 206 207 <div class="product-info h-100"> 208 <div class="fs-7 pt-1 opacity-85 start item_@Model.Item.SystemName.ToLower() product-number" itemprop="sku">@product.Id / @product.VariantId - @product.VariantName</div> 209 <div class="py-2" data-col-size="12"> 210 <h2 class="h6 start m-0 item_swift_productheader product-name" itemprop="name"><b>@product.Name</b></h2> 211 </div> 212 </div> 213 var sliderId = $"thumb-scroll-{product.Id}"; 214 if (productVariantGroups.Any() && product?.VariantInfo?.VariantInfo != null) 215 216 { 217 @using Dynamicweb.Ecommerce.Prices 218 @{ 219 string[] variantId = product.VariantId.Split('.'); 220 string showPricesWithVat = Pageview.Area.EcomPricesWithVat.ToLower(); 221 bool neverShowVat = string.IsNullOrEmpty(showPricesWithVat); 222 bool showInformativePrice = Model.Item.GetBoolean("ShowInformativePrice"); 223 string productInfoFeed = ""; 224 bool isLazyLoadingForProductInfoEnabled = Dynamicweb.Core.Converter.ToBoolean(Dynamicweb.Context.Current.Items["IsLazyLoadingForProductInfoEnabled"]); 225 if (isLazyLoadingForProductInfoEnabled) 226 { 227 if (Dynamicweb.Context.Current.Items.Contains("ProductInfoFeed")) 228 { 229 productInfoFeed = Dynamicweb.Context.Current.Items["ProductInfoFeed"]?.ToString(); 230 if (!string.IsNullOrEmpty(productInfoFeed)) 231 { 232 productInfoFeed =productInfoFeed; 233 } 234 } 235 236 } 237 string priceMin = ""; 238 string priceMax = ""; 239 int groupNumber = 1; 240 241 242 243 244 string baseUrl = $"Default.aspx?ID={GetPageIdByNavigationTag("Shop")}&GroupID={product.PrimaryOrDefaultGroup.Id}&ProductID={product.Id}"; 245 if (!string.IsNullOrEmpty(baseUrl)) 246 { 247 baseUrl = $"/{baseUrl.TrimStart('/')}"; 248 } 249 string variantUrl = string.Empty; 250 251 252 Dictionary<string, string> 253 variantImages = new Dictionary<string, string> 254 (); 255 <div class="last-row mt-auto"> 256 257 @foreach (var variantGroup in productVariantGroups) 258 { 259 <div class="thumbnail-wrapper"> 260 <button class="thumb-nav prev" onclick="scrollThumbs('@sliderId', -1)"> 261 <svg width="20px" height="20px" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" fill="#1D98A5"> 262 263 <g stroke="none" stroke-width="1" fill="none" fill-rule="evenodd"> 264 <g transform="translate(-336.000000, 0.000000)"> 265 <g id="left_line" transform="translate(336.000000, 0.000000)"> 266 <path d="M24,0 L24,24 L0,24 L0,0 L24,0 Z M12.5934901,23.257841 L12.5819402,23.2595131 L12.5108777,23.2950439 L12.4918791,23.2987469 L12.4918791,23.2987469 L12.4767152,23.2950439 L12.4056548,23.2595131 C12.3958229,23.2563662 12.3870493,23.2590235 12.3821421,23.2649074 L12.3780323,23.275831 L12.360941,23.7031097 L12.3658947,23.7234994 L12.3769048,23.7357139 L12.4804777,23.8096931 L12.4953491,23.8136134 L12.4953491,23.8136134 L12.5071152,23.8096931 L12.6106902,23.7357139 L12.6232938,23.7196733 L12.6232938,23.7196733 L12.6266527,23.7031097 L12.609561,23.275831 C12.6075724,23.2657013 12.6010112,23.2592993 12.5934901,23.257841 L12.5934901,23.257841 Z M12.8583906,23.1452862 L12.8445485,23.1473072 L12.6598443,23.2396597 L12.6498822,23.2499052 L12.6498822,23.2499052 L12.6471943,23.2611114 L12.6650943,23.6906389 L12.6699349,23.7034178 L12.6699349,23.7034178 L12.678386,23.7104931 L12.8793402,23.8032389 C12.8914285,23.8068999 12.9022333,23.8029875 12.9078286,23.7952264 L12.9118235,23.7811639 L12.8776777,23.1665331 C12.8752882,23.1545897 12.8674102,23.1470016 12.8583906,23.1452862 L12.8583906,23.1452862 Z M12.1430473,23.1473072 C12.1332178,23.1423925 12.1221763,23.1452606 12.1156365,23.1525954 L12.1099173,23.1665331 L12.0757714,23.7811639 C12.0751323,23.7926639 12.0828099,23.8018602 12.0926481,23.8045676 L12.108256,23.8032389 L12.3092106,23.7104931 L12.3186497,23.7024347 L12.3186497,23.7024347 L12.3225043,23.6906389 L12.340401,23.2611114 L12.337245,23.2485176 L12.337245,23.2485176 L12.3277531,23.2396597 L12.1430473,23.1473072 Z" id="MingCute" fill-rule="nonzero"> </path> 267 <path d="M8.29292,12.7071 C7.9024,12.3166 7.9024,11.6834 8.29292,11.2929 L13.9498,5.63604 C14.3403,5.24551 14.9735,5.24551 15.364,5.63604 C15.7545,6.02656 15.7545,6.65973 15.364,7.05025 L10.4142,12 L15.364,16.9497 C15.7545,17.3403 15.7545,17.9734 15.364,18.364 C14.9735,18.7545 14.3403,18.7545 13.9498,18.364 L8.29292,12.7071 Z" id="路径" fill="#1D98A5"> </path> 268 </g> 269 </g> 270 </g> 271 </svg> 272 273 </button> 274 <div class="thumbnail-scroll" id="@sliderId"> 275 @{ 276 VariantGroupViewModel group = variantGroup; 277 foreach (var option in group.Options.OrderBy(o => o.Id)) 278 { 279 var productVariant = productService.GetProductById(product.Id, option.Id, false); 280 281 var productSelection = new PriceProductSelection(productVariant, null, 0); 282 283 var currencyCode = string.IsNullOrWhiteSpace(Pageview.User.Currency) ? Pageview.Area.EcomCurrencyId : Pageview.User.Currency; 284 var countryCode = string.IsNullOrWhiteSpace(Pageview.User.CountryCode) ? Pageview.Area.EcomCountryCode : Pageview.User.CountryCode; 285 286 var userCurrency = Dynamicweb.Ecommerce.Services.Currencies.GetCurrency(currencyCode); 287 var userCountry = Dynamicweb.Ecommerce.Services.Countries.GetCountry(countryCode); 288 289 var priceContext = new PriceContext(userCurrency, userCountry, null, Pageview.User, false, null); 290 var productPrice = Dynamicweb.Ecommerce.Services.Prices.FindPrices(priceContext, productSelection, false); 291 292 //throw new Exception(System.Text.Json.JsonSerializer.Serialize(productPrice)); 293 294 var fieldValue = productVariant?.ProductFieldValues?.GetProductFieldValue("BlockedCustomerList")?.Value; 295 296 if ((fieldValue != null && !fieldValue.ToString().Contains(customerNumber)) || String.IsNullOrWhiteSpace(customerNumber)) 297 { 298 299 300 string active = variantId != null && variantId.Contains(option.Id) ? "active" : string.Empty; 301 string buttonId = $"{product.Id}_{option.Id}_{Pageview.CurrentParagraph.ID}"; 302 string contrastColor = string.Empty; 303 304 string searchKey = $"{product.Id}_{option.Id}_"; 305 /*Images*/ 306 var imagePathVariant = option.Image?.Value ?? ""; 307 308 309 var folderPath = Path.GetDirectoryName(imagePathVariant); 310 311 string physicalFolderPath = Dynamicweb.Context.Current.Server.MapPath(folderPath); 312 313 string lastImage = null; 314 315 if (Directory.Exists(physicalFolderPath)) 316 { 317 318 var fileWith15 = Directory.GetFiles(physicalFolderPath) 319 .FirstOrDefault(f => Path.GetFileName(f).Contains($"{product.Id}_{option.Id}_9")); 320 321 if (fileWith15 != null) 322 { 323 lastImage = fileWith15; 324 } 325 else 326 { 327 var files = Directory.GetFiles(physicalFolderPath) 328 .Where(f => Path.GetFileName(f).StartsWith($"{product.Id}_{option.Id}_")) 329 .OrderByDescending(f => 330 { 331 var filename = Path.GetFileNameWithoutExtension(f); 332 var match = System.Text.RegularExpressions.Regex.Match(filename, @"_(\d+)$"); 333 if (match.Success && int.TryParse(match.Groups[1].Value, out int index)) 334 { 335 return index; 336 } 337 return 0; 338 }) 339 .ToList(); 340 341 if (files.Any()) 342 { 343 lastImage = files.First(); 344 } 345 } 346 } 347 348 var lastImageUrl = lastImage != null ? lastImage : "/Files/Images/zijlstra/Afbeeldingen_overig/Coming_Soon.jpg"; 349 int index = lastImageUrl.IndexOf("Files"); 350 string relativePath = index >= 0 ? lastImageUrl.Substring(index).Replace("\\", "/") : lastImageUrl.Replace("\\", "/"); 351 lastImageUrl = "/" + relativePath; 352 lastImageUrl = Dynamicweb.Context.Current.Server.UrlEncode(lastImageUrl); 353 var variantImg = option.Image is object ? Dynamicweb.Context.Current.Server.UrlEncode(option.Image.Value) : null; 354 var variantLink = "/Default.aspx?ID=" + GetPageIdByNavigationTag("Shop") + "&GroupID=" + product.PrimaryOrDefaultGroup.Id + "&ProductID=" + product.Id + "&VariantID=" + option.Id; 355 356 string variantImage = string.Empty; 357 variantImages.TryGetValue(option.Id, out variantImage); 358 /*End Images*/ 359 360 /*stock state*/ 361 double variantStock = productVariant.Stock; 362 string svgInStock = "<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"16\" height=\"16\" fill=\"#44B11A\" class=\"bi bi-check-lg\" viewBox=\"0 0 16 16\"><path d=\"M12.736 3.97a.733.733 0 0 1 1.047 0c.286.289.29.756.01 1.05L7.88 12.01a.733.733 0 0 1-1.065.02L3.217 8.384a.757.757 0 0 1 0-1.06.733.733 0 0 1 1.047 0l3.052 3.093 5.4-6.425z\"/></svg>"; 363 string svgOutStock = "<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"25\" height=\"25\" fill=\"#CA0D0D\" class=\"bi bi-x-lg\" viewBox=\"0 0 16 16\"><path d=\"M4.646 4.646a.5.5 0 0 1 .708 0L8 7.293l2.646-2.647a.5.5 0 0 1 .708.708L8.707 8l2.647 2.646a.5.5 0 0 1-.708.708L8 8.707l-2.646 2.647a.5.5 0 0 1-.708-.708L7.293 8 4.646 5.354a.5.5 0 0 1 0-.708\"/></svg>"; 364 365 string infoStock = "<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"16\" height=\"16\" fill=\"currentColor\" class=\"bi bi-info-circle-fill\" viewBox=\"0 0 16 16\"><path d=\"M8 16A8 8 0 1 0 8 0a8 8 0 0 0 0 16m.93-9.412-1 4.705c-.07.34.029.533.304.533.194 0 .487-.07.686-.246l-.088.416c-.287.346-.92.598-1.465.598-.703 0-1.002-.422-.808-1.319l.738-3.468c.064-.293.006-.399-.287-.47l-.451-.081.082-.381 2.29-.287zM8 5.5a1 1 0 1 1 0-2 1 1 0 0 1 0 2\" /></svg>"; 366 string isNew = productVariant?.ProductFieldValues?.GetProductFieldValue("New")?.Value?.ToString().ToLower() ?? ""; 367 string isNewSvg = "<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"16\" height=\"16\" fill=\"#F2C400\" class=\"bi bi-star-fill\" viewBox=\"0 0 16 16\"><path d = \"M3.612 15.443c-.386.198-.824-.149-.746-.592l.83-4.73L.173 6.765c-.329-.314-.158-.888.283-.95l4.898-.696L7.538.792c.197-.39.73-.39.927 0l2.184 4.327 4.898.696c.441.062.612.636.282.95l-3.522 3.356.83 4.73c.078.443-.36.79-.746.592L8 13.187l-4.389 2.256z\" /></svg> "; 368 string stockState = ""; 369 370 string isSale = productVariant?.ProductFieldValues?.GetProductFieldValue("Sale")?.Value?.ToString().ToLower() ?? ""; 371 string isSaleSvg = "<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"16\" height=\"16\" fill=\"#F03232\" class=\"bi bi-star-fill\" viewBox=\"0 0 16 16\"><path d = \"M3.612 15.443c-.386.198-.824-.149-.746-.592l.83-4.73L.173 6.765c-.329-.314-.158-.888.283-.95l4.898-.696L7.538.792c.197-.39.73-.39.927 0l2.184 4.327 4.898.696c.441.062.612.636.282.95l-3.522 3.356.83 4.73c.078.443-.36.79-.746.592L8 13.187l-4.389 2.256z\" /></svg> "; 372 373 string expectedDeliveryDate = ""; 374 375 if (DateTime.Compare(productVariant.ExpectedDelivery, new DateTime(1900, 1, 1)) != 0) //In DW, if the Date is not set, it is defaulted 01-01-1900 and not null.. 376 { 377 expectedDeliveryDate = productVariant.ExpectedDelivery.ToShortDateString(); 378 } 379 380 string expectedDeliveryDateText = !String.IsNullOrWhiteSpace(expectedDeliveryDate) ? Translate("Verwacht:") + "&nbsp;" + expectedDeliveryDate : ""; 381 382 @if (!(bool?)productVariant.ProductFieldValues.Where(o => o.ProductField.SystemName == "ProductToBeDiscontinued").SingleOrDefault()?.Value ?? false) 383 { 384 if (variantStock > 0) 385 { 386 if (isNew == "true" || isSale == "true") 387 { 388 if (isSale == "true") 389 { 390 stockState += isSaleSvg + "&nbsp; &nbsp;" + Translate("Sale!") + "<br/>"; 391 } 392 393 if (isNew == "true") 394 { 395 stockState += isNewSvg + "&nbsp; &nbsp;" + Translate("New!") + "<br/>"; 396 } 397 398 stockState += "&nbsp;" + Translate("Nu leverbaar"); 399 } 400 else 401 { 402 stockState = svgInStock + "&nbsp; " + Translate("Op voorraad"); 403 404 } 405 } 406 else 407 { 408 stockState = svgOutStock + "&nbsp;" + Translate("Geen voorraad") + "<br/>" + expectedDeliveryDateText; 409 410 } 411 } 412 else 413 { 414 415 stockState = svgOutStock + "&nbsp;" + Translate("Discontinued:") + "<br/>" + variantStock + "&nbsp;" + @Translate("left in stock"); 416 417 } 418 /*End stock state*/ 419 /*Price variants*/ 420 double price = productVariant.DefaultPrice; 421 double cost = productVariant.Cost; 422 423 string priceFormated = Dynamicweb.Ecommerce.Services.Currencies.Format(Dynamicweb.Ecommerce.Services.Currencies.GetCurrency(currency), Convert.ToDouble(productPrice.ToList()[0].Amount, formatProvider)); 424 //string priceFormated = Dynamicweb.Ecommerce.Services.Currencies.Format(Dynamicweb.Ecommerce.Services.Currencies.GetCurrency(currency), Convert.ToDouble(price, formatProvider)); 425 426 427 428 /*End Price variants*/ 429 430 <img class="theme thumbnail" data-stockstate="@WebUtility.HtmlEncode(stockState)" src="/Admin/Public/GetImage.ashx?image=@(lastImageUrl)&width=64&format=webp" onclick="selectVariant('@(product.Id)','/Admin/Public/GetImage.ashx?image=@(variantImg)&format=webp','@variantLink','@product.Id','@option.Id','@option.Name',this.dataset.stockstate,'@isNew','@isSale','@priceFormated','@cost')" /> 431 432 433 } 434 } 435 436 } 437 </div> 438 <button class="thumb-nav next" onclick="scrollThumbs('@sliderId', 1)"> 439 <svg width="20px" height="20px" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" fill="#1D98A5"> 440 441 <g stroke="none" stroke-width="1" fill="none" fill-rule="evenodd"> 442 <g transform="translate(-384.000000, 0.000000)"> 443 <g id="right_line" transform="translate(384.000000, 0.000000)"> 444 <path d="M24,0 L24,24 L0,24 L0,0 L24,0 Z M12.5934901,23.257841 L12.5819402,23.2595131 L12.5108777,23.2950439 L12.4918791,23.2987469 L12.4918791,23.2987469 L12.4767152,23.2950439 L12.4056548,23.2595131 C12.3958229,23.2563662 12.3870493,23.2590235 12.3821421,23.2649074 L12.3780323,23.275831 L12.360941,23.7031097 L12.3658947,23.7234994 L12.3769048,23.7357139 L12.4804777,23.8096931 L12.4953491,23.8136134 L12.4953491,23.8136134 L12.5071152,23.8096931 L12.6106902,23.7357139 L12.6232938,23.7196733 L12.6232938,23.7196733 L12.6266527,23.7031097 L12.609561,23.275831 C12.6075724,23.2657013 12.6010112,23.2592993 12.5934901,23.257841 L12.5934901,23.257841 Z M12.8583906,23.1452862 L12.8445485,23.1473072 L12.6598443,23.2396597 L12.6498822,23.2499052 L12.6498822,23.2499052 L12.6471943,23.2611114 L12.6650943,23.6906389 L12.6699349,23.7034178 L12.6699349,23.7034178 L12.678386,23.7104931 L12.8793402,23.8032389 C12.8914285,23.8068999 12.9022333,23.8029875 12.9078286,23.7952264 L12.9118235,23.7811639 L12.8776777,23.1665331 C12.8752882,23.1545897 12.8674102,23.1470016 12.8583906,23.1452862 L12.8583906,23.1452862 Z M12.1430473,23.1473072 C12.1332178,23.1423925 12.1221763,23.1452606 12.1156365,23.1525954 L12.1099173,23.1665331 L12.0757714,23.7811639 C12.0751323,23.7926639 12.0828099,23.8018602 12.0926481,23.8045676 L12.108256,23.8032389 L12.3092106,23.7104931 L12.3186497,23.7024347 L12.3186497,23.7024347 L12.3225043,23.6906389 L12.340401,23.2611114 L12.337245,23.2485176 L12.337245,23.2485176 L12.3277531,23.2396597 L12.1430473,23.1473072 Z" id="MingCute" fill-rule="nonzero"> </path> 445 <path d="M15.7072,11.2929 C16.0977,11.6834 16.0977,12.3166 15.7072,12.7071 L10.0503,18.364 C9.65982,18.7545 9.02666,18.7545 8.63613,18.364 C8.24561,17.9734 8.24561,17.3403 8.63613,16.9497 L13.5859,12 L8.63613,7.05025 C8.24561,6.65973 8.24561,6.02656 8.63613,5.63604 C9.02666,5.24551 9.65982,5.24551 10.0503,5.63604 L15.7072,11.2929 Z" id="路径" fill="#1D98A5"> </path> 446 </g> 447 </g> 448 449 </svg> 450 451 </button> 452 </div> 453 } 454 455 456 </div> 457 458 } 459 if ((fieldValueBlocked != null && !fieldValueBlocked.ToString().Contains(customerNumber)) || String.IsNullOrWhiteSpace(customerNumber)) 460 { 461 <div class="stock-state pt-2 mt-auto"> 462 @{ 463 464 /*stock state*/ 465 double MainvariantStock = MainVariant.Stock; 466 string MainsvgInStock = "<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"16\" height=\"16\" fill=\"#44B11A\" class=\"bi bi-check-lg\" viewBox=\"0 0 16 16\"><path d=\"M12.736 3.97a.733.733 0 0 1 1.047 0c.286.289.29.756.01 1.05L7.88 12.01a.733.733 0 0 1-1.065.02L3.217 8.384a.757.757 0 0 1 0-1.06.733.733 0 0 1 1.047 0l3.052 3.093 5.4-6.425z\"/></svg>"; 467 string MainsvgOutStock = "<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"25\" height=\"25\" fill=\"#CA0D0D\" class=\"bi bi-x-lg\" viewBox=\"0 0 16 16\"><path d=\"M4.646 4.646a.5.5 0 0 1 .708 0L8 7.293l2.646-2.647a.5.5 0 0 1 .708.708L8.707 8l2.647 2.646a.5.5 0 0 1-.708.708L8 8.707l-2.646 2.647a.5.5 0 0 1-.708-.708L7.293 8 4.646 5.354a.5.5 0 0 1 0-.708\"/></svg>"; 468 469 string MaininfoStock = "<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"16\" height=\"16\" fill=\"currentColor\" class=\"bi bi-info-circle-fill\" viewBox=\"0 0 16 16\"><path d=\"M8 16A8 8 0 1 0 8 0a8 8 0 0 0 0 16m.93-9.412-1 4.705c-.07.34.029.533.304.533.194 0 .487-.07.686-.246l-.088.416c-.287.346-.92.598-1.465.598-.703 0-1.002-.422-.808-1.319l.738-3.468c.064-.293.006-.399-.287-.47l-.451-.081.082-.381 2.29-.287zM8 5.5a1 1 0 1 1 0-2 1 1 0 0 1 0 2\" /></svg>"; 470 string MainisNew = MainVariant?.ProductFieldValues?.GetProductFieldValue("New")?.Value?.ToString().ToLower() ?? ""; 471 string MainisNewSvg = "<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"16\" height=\"16\" fill=\"#F2C400\" class=\"bi bi-star-fill\" viewBox=\"0 0 16 16\"><path d = \"M3.612 15.443c-.386.198-.824-.149-.746-.592l.83-4.73L.173 6.765c-.329-.314-.158-.888.283-.95l4.898-.696L7.538.792c.197-.39.73-.39.927 0l2.184 4.327 4.898.696c.441.062.612.636.282.95l-3.522 3.356.83 4.73c.078.443-.36.79-.746.592L8 13.187l-4.389 2.256z\" /></svg> "; 472 string MainstockState = ""; 473 string MainIsSale = MainVariant?.ProductFieldValues?.GetProductFieldValue("Sale")?.Value?.ToString().ToLower() ?? ""; 474 string MainIsSaleSvg = "<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"16\" height=\"16\" fill=\"#F03232\" class=\"bi bi-star-fill\" viewBox=\"0 0 16 16\"><path d = \"M3.612 15.443c-.386.198-.824-.149-.746-.592l.83-4.73L.173 6.765c-.329-.314-.158-.888.283-.95l4.898-.696L7.538.792c.197-.39.73-.39.927 0l2.184 4.327 4.898.696c.441.062.612.636.282.95l-3.522 3.356.83 4.73c.078.443-.36.79-.746.592L8 13.187l-4.389 2.256z\" /></svg> "; 475 string MainexpectedDeliveryDate = ""; 476 477 if (DateTime.Compare(MainVariant.ExpectedDelivery, new DateTime(1900, 1, 1)) != 0) //In DW, if the Date is not set, it is defaulted 01-01-1900 and not null.. 478 { 479 MainexpectedDeliveryDate = MainVariant.ExpectedDelivery.ToShortDateString(); 480 } 481 482 string MainexpectedDeliveryDateText = !String.IsNullOrWhiteSpace(MainexpectedDeliveryDate) ? Translate("Verwacht:") + "&nbsp;" + MainexpectedDeliveryDate : ""; 483 484 @if (!(bool?)MainVariant.ProductFieldValues.Where(o => o.ProductField.SystemName == "ProductToBeDiscontinued").SingleOrDefault()?.Value ?? false) 485 { 486 if (MainvariantStock > 0) 487 { 488 if (MainisNew == "true" || MainIsSale == "true") 489 { 490 if (MainIsSale == "true") 491 { 492 MainstockState += MainIsSaleSvg + "&nbsp; &nbsp;" + Translate("Sale!") + "<br/>"; 493 } 494 495 if (MainisNew == "true") 496 { 497 MainstockState += MainisNewSvg + "&nbsp; &nbsp;" + Translate("New!") + "<br/>"; 498 } 499 500 MainstockState += "&nbsp;" + Translate("Nu leverbaar"); 501 } 502 else 503 { 504 MainstockState = MainsvgInStock + "&nbsp; " + Translate("Op voorraad"); 505 506 } 507 } 508 else 509 { 510 MainstockState = MainsvgOutStock + "&nbsp;" + Translate("Geen voorraad") + "<br/>" + MainexpectedDeliveryDateText; 511 512 } 513 } 514 else 515 { 516 517 MainstockState = MainsvgOutStock + "&nbsp;" + Translate("Discontinued:") + "<br/>" + MainvariantStock + "&nbsp;" + @Translate("left in stock"); 518 519 } 520 /*End stock state*/ 521 522 523 @MainstockState 524 525 526 } 527 </div> 528 } 529 else 530 { 531 <div class="stock-state pt-2 mt-auto"> 532 @MainOutStock @Translate("Discontinued") 533 </div> 534 } 535 <div class="custom-price mt-auto"> 536 @{ 537 538 539 540 541 bool isErpConnectionDown = !Dynamicweb.Core.Converter.ToBoolean(Dynamicweb.Context.Current.Items["IsWebServiceConnectionAvailable"]); 542 bool hidePrice = anonymousUsersLimitations.Contains("price") && anonymousUser || Pageview.AreaSettings.GetBoolean("ErpDownHidePrices") && isErpConnectionDown; 543 544 bool productIsDiscontinued = product is object && product.Discontinued; 545 bool doNotShowPriceIfProductIsDiscontinued = Model.Item.GetBoolean("DoNotShowPriceIfProductIsDiscontinued"); 546 var isDiscontinued = productIsDiscontinued && doNotShowPriceIfProductIsDiscontinued; 547 } 548 549 @if (product is object && !hidePrice && !isDiscontinued) 550 { 551 string unitId = !string.IsNullOrEmpty(Dynamicweb.Context.Current.Request.Form.Get("UnitId")) ? Dynamicweb.Context.Current.Request.Form.Get("UnitId") : string.Empty; 552 553 string priceFontSize = Model.Item.GetRawValueString("PriceSize", "fs-4"); 554 string horizontalAlign = Model.Item.GetRawValueString("HorizontalAlignment", ""); 555 string layout = Model.Item.GetRawValueString("Layout", "horizontal"); 556 string textAlign = horizontalAlign == "center" ? "text-center" : string.Empty; 557 textAlign = horizontalAlign == "end" ? "text-end" : textAlign; 558 559 horizontalAlign = horizontalAlign == "center" && layout == "horizontal" ? "justify-content-center" : horizontalAlign; 560 horizontalAlign = horizontalAlign == "end" && layout == "horizontal" ? "justify-content-end" : horizontalAlign; 561 horizontalAlign = horizontalAlign == "center" && layout == "vertical" ? "align-items-center" : horizontalAlign; 562 horizontalAlign = horizontalAlign == "end" && layout == "vertical" ? "align-items-end" : horizontalAlign; 563 564 string flexDirection = layout == "horizontal" ? string.Empty : "flex-column"; 565 string flexGap = layout == "horizontal" ? "gap-3" : string.Empty; 566 string order = layout == "horizontal" ? string.Empty : "order-2"; 567 568 569 string contentPadding = Model.Item.GetRawValueString("ContentPadding", ""); 570 contentPadding = contentPadding == "none" ? "p-0" : contentPadding; 571 contentPadding = contentPadding == "small" ? "p-1 px-md-2 py-md-1" : contentPadding; 572 contentPadding = contentPadding == "large" ? "p-2 px-md-3 py-md-2" : contentPadding; 573 string liveInfoClass = ""; 574 575 576 577 578 579 580 if (isLazyLoadingForProductInfoEnabled) 581 { 582 if (Dynamicweb.Context.Current.Items.Contains("ProductInfoFeed")) 583 { 584 productInfoFeed = Dynamicweb.Context.Current.Items["ProductInfoFeed"]?.ToString(); 585 if (!string.IsNullOrEmpty(productInfoFeed)) 586 { 587 productInfoFeed = $"data-product-info-feed=\"{productInfoFeed}\""; 588 } 589 } 590 liveInfoClass = "js-live-info"; 591 } 592 593 <div class="@textAlign @liveInfoClass item_@Model.Item.SystemName.ToLower()" data-product-id="@product.Id" data-variant-id="@product.VariantId" @productInfoFeed> 594 @if (showInformativePrice && product.PriceInformative.Price != 0) 595 { 596 <div class="opacity-50"> 597 <span>@Translate("RRP") </span> 598 <span class="text-decoration-line-through text-price">@product.PriceInformative.PriceFormatted</span> 599 </div> 600 } 601 <div class="@priceFontSize m-0 d-flex flex-wrap @flexDirection @flexGap @horizontalAlign" style="row-gap: 0 !important" itemprop="offers" itemscope itemtype="https://schema.org/Offer"> 602 <span itemprop="priceCurrency" content="@product.Price.CurrencyCode" class="d-none"></span> 603 604 605 @if (showPricesWithVat == "false" && !neverShowVat) 606 { 607 if (isLazyLoadingForProductInfoEnabled && !Pageview.IsVisualEditorMode) 608 { 609 <span itemprop="price" content="" class="d-none"></span> 610 <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> 611 } 612 else 613 { 614 string beforePrice = !string.IsNullOrEmpty(unitId) ? product.GetPrice(unitId).PriceBeforeDiscount.PriceWithoutVatFormatted : product.PriceBeforeDiscount.PriceWithoutVatFormatted; 615 616 <span itemprop="price" content="@product.Price.PriceWithoutVat.ToString("0.00", System.Globalization.CultureInfo.InvariantCulture)" class="d-none"></span> 617 if (product.Price.Price != product.PriceBeforeDiscount.Price) 618 { 619 <span class="text-decoration-line-through opacity-75 @order">@beforePrice</span> 620 } 621 } 622 } 623 else 624 { 625 if (isLazyLoadingForProductInfoEnabled && !Pageview.IsVisualEditorMode) 626 { 627 <span itemprop="price" content="" class="d-none"></span> 628 <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> 629 } 630 else 631 { 632 string beforePrice = !string.IsNullOrEmpty(unitId) ? product.GetPrice(unitId).PriceBeforeDiscount.PriceFormatted : product.PriceBeforeDiscount.PriceFormatted; 633 634 <span itemprop="price" content="@product.Price.Price.ToString("0.00", System.Globalization.CultureInfo.InvariantCulture)" class="d-none"></span> 635 636 if (product.Price.Price != product.PriceBeforeDiscount.Price) 637 { 638 <span class="text-decoration-line-through opacity-75 @order"> 639 <span class="text-price">@beforePrice</span> 640 </span> 641 } 642 } 643 } 644 645 @if (showPricesWithVat == "false" && !neverShowVat) 646 { 647 if (isLazyLoadingForProductInfoEnabled && !Pageview.IsVisualEditorMode) 648 { 649 <span class="text-price js-text-price"> 650 <span class="spinner-border" role="status"></span> 651 </span> 652 } 653 else 654 { 655 string price = !string.IsNullOrEmpty(unitId) ? product.GetPrice(unitId).Price.PriceWithoutVatFormatted : product.Price.PriceWithoutVatFormatted; 656 657 if (product?.VariantInfo?.VariantInfo != null) 658 { 659 priceMin = product?.VariantInfo?.PriceMin?.PriceWithoutVatFormatted != null ? product.VariantInfo.PriceMin.PriceWithoutVatFormatted : ""; 660 priceMax = product?.VariantInfo?.PriceMax?.PriceWithoutVatFormatted != null ? product.VariantInfo.PriceMax.PriceWithoutVatFormatted : ""; 661 } 662 if (priceMin != priceMax) 663 { 664 price = priceMin + " - " + priceMax; 665 } 666 <span class="@theme @contentPadding"> 667 <span class="text-price">@price</span> 668 </span> 669 } 670 } 671 else 672 { 673 if (isLazyLoadingForProductInfoEnabled && !Pageview.IsVisualEditorMode) 674 { 675 <span class="text-price js-text-price"> 676 <span class="spinner-border" role="status"></span> 677 </span> 678 } 679 else 680 { 681 string price = !string.IsNullOrEmpty(unitId) ? product.GetPrice(unitId).Price.PriceFormatted : product.Price.PriceFormatted; 682 683 if (product?.VariantInfo?.VariantInfo != null) 684 { 685 priceMin = product?.VariantInfo?.PriceMin?.PriceFormatted != null ? product.VariantInfo.PriceMin.PriceFormatted : ""; 686 priceMax = product?.VariantInfo?.PriceMax?.PriceFormatted != null ? product.VariantInfo.PriceMax.PriceFormatted : ""; 687 } 688 if (priceMin != priceMax) 689 { 690 price = priceMin + " - " + priceMax; 691 } 692 <span class="@theme @contentPadding"> 693 <span class="text-price">@price</span> 694 </span> 695 } 696 } 697 698 @* Stock state for Schema.org, start *@ 699 @{ 700 Uri url = Dynamicweb.Context.Current.Request.Url; 701 } 702 703 <link itemprop="url" href="@url"> 704 705 @{ 706 bool IsNeverOutOfStock = product.NeverOutOfstock; 707 } 708 709 @if (IsNeverOutOfStock) 710 { 711 <span itemprop="availability" class="d-none">@Translate("Available in stock")</span> 712 } 713 else 714 { 715 if (product.StockLevel > 0) 716 { 717 <span itemprop="availability" class="d-none">InStock</span> 718 } 719 else 720 { 721 <span itemprop="availability" class="d-none">OutOfStock</span> 722 } 723 } 724 @* Stock state for Schema.org, stop *@ 725 726 </div> 727 728 @if (showPricesWithVat == "false" && !neverShowVat) 729 { 730 if (isLazyLoadingForProductInfoEnabled && !Pageview.IsVisualEditorMode) 731 { 732 <small class="opacity-85 fst-normal js-text-price-with-vat d-none" data-suffix="@Translate("Incl. VAT")"></small> 733 } 734 else 735 { 736 string price = !string.IsNullOrEmpty(unitId) ? product.GetPrice(unitId).Price.PriceWithVatFormatted : product.Price.PriceWithVatFormatted; 737 738 if (product?.VariantInfo?.VariantInfo != null) 739 { 740 priceMin = product?.VariantInfo?.PriceMin?.PriceWithVatFormatted != null ? product.VariantInfo.PriceMin.PriceWithVatFormatted : ""; 741 priceMax = product?.VariantInfo?.PriceMax?.PriceWithVatFormatted != null ? product.VariantInfo.PriceMax.PriceWithVatFormatted : ""; 742 } 743 if (priceMin != priceMax) 744 { 745 price = priceMin + " - " + priceMax; 746 } 747 <!-- <small class="opacity-85 fst-normal">@price @Translate("Incl. VAT")</small> --> 748 } 749 } 750 </div> 751 } 752 else if (Pageview.IsVisualEditorMode) 753 { 754 <div class="alert alert-dark m-0" role="alert"> 755 <span>@Translate("No products available")</span> 756 </div> 757 } 758 759 </div> 760 } 761 } 762
Tischlampe 1L bray
Error executing template "Designs/Swift/Paragraph/CustomProductSlider.cshtml"
System.NullReferenceException: Object reference not set to an instance of an object.
   at CompiledRazorTemplates.Dynamic.RazorEngine_3562354021b44d5c892fe73dc2806e4f.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 Dynamicweb.Ecommerce.ProductCatalog 3 @using Dynamicweb.Ecommerce.CustomerExperienceCenter.Favorites 4 @using Dynamicweb.Files 5 @using System.IO 6 @using System.Net 7 @using Dynamicweb.Security.UserManagement 8 9 10 @{ 11 ProductViewModel product = null; 12 if (Dynamicweb.Context.Current.Items.Contains("ProductDetails")) 13 { 14 product = (ProductViewModel)Dynamicweb.Context.Current.Items["ProductDetails"]; 15 } 16 else if (Pageview.Page.Item["DummyProduct"] != null && Pageview.IsVisualEditorMode) 17 { 18 var pageViewModel = Dynamicweb.Frontend.ContentViewModelFactory.CreatePageInfoViewModel(Pageview.Page); 19 ProductListViewModel productList = pageViewModel.Item.GetValue("DummyProduct") != null ? pageViewModel.Item.GetValue("DummyProduct") as ProductListViewModel : new ProductListViewModel(); 20 21 if (productList?.Products is object) 22 { 23 product = productList.Products[0]; 24 } 25 } 26 } 27 28 @{ 29 var currentUser = Pageview?.User; 30 var customerNumber = !string.IsNullOrEmpty(currentUser?.CustomerNumber) 31 ? currentUser.CustomerNumber 32 : ""; 33 } 34 @if (product is object) 35 { 36 string imagePath = product?.DefaultImage?.Value ?? ""; 37 string imagePathUrlEncoded = Dynamicweb.Context.Current.Server.UrlEncode(imagePath); 38 39 string ratio = Model.Item.GetRawValueString("ImageAspectRatio", ""); 40 ratio = ratio != "0" ? ratio : ""; 41 string ratioCssClass = ratio != "" ? " ratio" : ""; 42 string ratioVariable = ratio != "" ? "--bs-aspect-ratio: " + ratio + ";" : ""; 43 44 string width = Model.Item.GetRawValueString("Width", "auto"); 45 int smallImageSize = 640; 46 int largeImageSize = width == "auto" ? 1280 : Convert.ToInt32(width); 47 48 string ImageObjectFit = Model.Item.GetRawValueString("ImageObjectFit", "contain"); 49 50 string imagePathXs = "/Admin/Public/GetImage.ashx?width=" + smallImageSize + "&image=" + imagePathUrlEncoded + "&format=webp"; 51 string imagePathS = "/Admin/Public/GetImage.ashx?width=" + largeImageSize + "&image=" + imagePathUrlEncoded + "&format=webp"; 52 string imagePathFallBack = "/Admin/Public/GetImage.ashx?width=" + largeImageSize + "&image=" + imagePathUrlEncoded + "&format=webp"; 53 54 var badgeParms = new Dictionary<string, object>(); 55 badgeParms.Add("size", "h7"); 56 badgeParms.Add("saleBadgeType", Model.Item.GetRawValue("SaleBadgeType")); 57 badgeParms.Add("saleBadgeCssClassName", Model.Item.GetRawValue("SaleBadgeDesign")); 58 badgeParms.Add("newBadgeCssClassName", Model.Item.GetRawValue("NewBadgeDesign")); 59 badgeParms.Add("newPublicationDays", Model.Item.GetInt32("NewPublicationDays")); 60 badgeParms.Add("campaignBadgesValues", Model.Item.GetList("CampaignBadges")?.GetRawValue().OfType<string>().ToList()); 61 62 string badgeSize = Model.Item.GetRawValueString("BadgeSize", "fs-2"); 63 bool saleBadgeEnabled = !string.IsNullOrWhiteSpace(Model.Item.GetRawValueString("SaleBadgeDesign")) && Model.Item.GetRawValueString("SaleBadgeDesign") != "none" ? true : false; 64 bool newBadgeEnabled = !string.IsNullOrWhiteSpace(Model.Item.GetRawValueString("NewBadgeDesign")) && Model.Item.GetRawValueString("NewBadgeDesign") != "none" ? true : false; 65 66 /*Custom badge*/ 67 var productService = new Dynamicweb.Ecommerce.Products.ProductService(); 68 var currency = Dynamicweb.Ecommerce.Common.Context.Currency.Code; 69 var formatProvider = new System.Globalization.NumberFormatInfo(); 70 formatProvider.NumberDecimalSeparator = "."; 71 formatProvider.NumberGroupSeparator = ","; 72 var MainVariant = productService.GetProductById(product.Id, product.VariantId, false); 73 var fieldValueBlocked = MainVariant?.ProductFieldValues?.GetProductFieldValue("BlockedCustomerList")?.Value; 74 75 76 string isNewProduct = MainVariant?.ProductFieldValues?.GetProductFieldValue("New")?.Value?.ToString().ToLower() ?? ""; 77 string MainisSale = MainVariant?.ProductFieldValues?.GetProductFieldValue("Sale")?.Value?.ToString().ToLower() ?? ""; 78 bool showNewBadge = isNewProduct == "true" ? true : false; 79 bool showSaleBadge = MainisSale == "true" ? true : false; 80 string showNewSaleBadge = "d-none"; 81 if (showSaleBadge) 82 { 83 badgeParms.Add("isSale", "true"); 84 85 } 86 else 87 { 88 badgeParms.Add("isSale", "false"); 89 } 90 if (showNewBadge) 91 { 92 badgeParms.Add("isNew", "true"); 93 } 94 else 95 { 96 badgeParms.Add("isNew", "false"); 97 } 98 /*End Custom badge*/ 99 if (showSaleBadge || showNewBadge) 100 { 101 showNewSaleBadge = ""; 102 } 103 DateTime createdDate = product.Created.Value; 104 bool showBadges = saleBadgeEnabled && product.Discount.Price != 0 ? true : false; 105 106 bool showFavoritesSelector = !string.IsNullOrEmpty(Model.Item.GetString("ShowAddToFavorites")) ? Model.Item.GetBoolean("ShowAddToFavorites") : false; 107 string anonymousUsersLimitations = Pageview.AreaSettings.GetRawValueString("AnonymousUsers", ""); 108 bool anonymousUser = Pageview.User == null; 109 110 var favoriteParameters = new Dictionary<string, object>(); 111 if (!anonymousUser && showFavoritesSelector) 112 { 113 int defaultFavoriteListId = 0; 114 115 IEnumerable<FavoriteList> favoreiteLists = Pageview.User.GetFavoriteLists(); 116 if (favoreiteLists.Count() == 1) 117 { 118 foreach (FavoriteList list in favoreiteLists) 119 { 120 defaultFavoriteListId = list.ListId; 121 } 122 } 123 124 favoriteParameters.Add("ListId", defaultFavoriteListId); 125 } 126 127 MediaViewModel alternativeImage = new MediaViewModel(); 128 if (Model.Item.GetBoolean("ShowAlternativeImageOnHover")) 129 { 130 var selectedImageCategories = Model.Item.GetList("GetAlternativeImageFrom")?.GetRawValue().OfType<string>().ToList(); 131 List<MediaViewModel> allAssetsImages = product.AssetCategories.Where(x => selectedImageCategories.Contains(x.SystemName)).SelectMany(x => x.Assets).ToList(); 132 allAssetsImages.RemoveAll(x => x.Value == product.DefaultImage.Value); 133 alternativeImage = allAssetsImages.FirstOrDefault(); 134 } 135 136 string altImagePathXs = string.Empty; 137 string altImagePathS = string.Empty; 138 139 if (!string.IsNullOrEmpty(alternativeImage?.Value)) 140 { 141 altImagePathXs = "/Admin/Public/GetImage.ashx?width=" + smallImageSize + "&image=" + Dynamicweb.Context.Current.Server.UrlEncode(alternativeImage.Value) + "&format=webp"; 142 altImagePathS = "/Admin/Public/GetImage.ashx?width=" + largeImageSize + "&image=" + Dynamicweb.Context.Current.Server.UrlEncode(alternativeImage.Value) + "&format=webp"; 143 } 144 145 @* Theme settings *@ 146 string theme = !string.IsNullOrWhiteSpace(Model.Item.GetRawValueString("Theme")) ? " theme " + Model.Item.GetRawValueString("Theme").Replace(" ", "").Trim().ToLower() : ""; 147 string themeBorder = !string.IsNullOrWhiteSpace(theme) ? "border: 1px solid rgba(0,0,0,0)" : ""; 148 string themePadding = !string.IsNullOrWhiteSpace(theme) ? "p-2 p-lg-3" : ""; 149 150 string imageId = "ProductImage_" + product.Id; 151 152 153 154 string fullWidth = width == "auto" ? "w-100" : ""; 155 string customWidth = width != "auto" ? "style=\"width: " + width + "px\"" : "style=\"min-width: 60px\""; 156 157 string altImageZindex = Model.Item.GetBoolean("ShowAlternativeImageOnHover") && !string.IsNullOrEmpty(alternativeImage?.Value) ? " z-index: 1" : string.Empty; 158 string groupid = !string.IsNullOrEmpty(Dynamicweb.Context.Current.Request.QueryString.Get("GroupID")) ? Dynamicweb.Context.Current.Request.QueryString.Get("GroupID"):"" ; 159 string link = product.GetProductLink(GetPageIdByNavigationTag("Shop"), false); 160 var productVariantGroups = product.VariantGroups(); 161 string MainOutStock = "<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"25\" height=\"25\" fill=\"#CA0D0D\" class=\"bi bi-x-lg\" viewBox=\"0 0 16 16\"><path d=\"M4.646 4.646a.5.5 0 0 1 .708 0L8 7.293l2.646-2.647a.5.5 0 0 1 .708.708L8.707 8l2.647 2.646a.5.5 0 0 1-.708.708L8 8.707l-2.646 2.647a.5.5 0 0 1-.708-.708L7.293 8 4.646 5.354a.5.5 0 0 1 0-.708\"/></svg>"; 162 163 @if (!string.IsNullOrEmpty(imagePath)) 164 { 165 <div class="@fullWidth @theme position-relative item_@Model.Item.SystemName.ToLower() main-image-container" @customWidth> 166 <div class="" style="@(ratioVariable)@(altImageZindex)"> 167 <div class="d-flex justify-content-center align-items-center"> 168 <a class="main-link-link" href="@link"> 169 @if (imagePath.StartsWith("/Files/", StringComparison.OrdinalIgnoreCase)) 170 { 171 <img id="@imageId" 172 srcset=" 173 @imagePathXs @(smallImageSize)w, 174 @imagePathS @(largeImageSize)w" 175 sizes="(max-width: 992px) 50vw, 25vw" 176 src="@imagePathFallBack" 177 loading="lazy" 178 decoding="async" 179 class="h-100 w-100 @themePadding main-image" 180 style="object-fit: @ImageObjectFit; @themeBorder " 181 alt="@product.Name" 182 itemprop="image"> 183 } 184 else 185 { 186 <img src="@product.DefaultImage.Value" 187 loading="lazy" 188 class="h-100 w-100 @themePadding main-image" 189 style="object-fit: contain; @themeBorder" 190 alt="@product.Name" 191 itemprop="image"> 192 } 193 </a> 194 </div> 195 </div> 196 197 <div class="position-absolute top-0 left-0 p-2 pb-0 custom-badge-product-list @showNewSaleBadge"> 198 @{ 199 @RenderPartial("Components/Custom_EcommerceBadge.cshtml", product, badgeParms) 200 } 201 </div> 202 203 204 </div> 205 } 206 207 <div class="product-info h-100"> 208 <div class="fs-7 pt-1 opacity-85 start item_@Model.Item.SystemName.ToLower() product-number" itemprop="sku">@product.Id / @product.VariantId - @product.VariantName</div> 209 <div class="py-2" data-col-size="12"> 210 <h2 class="h6 start m-0 item_swift_productheader product-name" itemprop="name"><b>@product.Name</b></h2> 211 </div> 212 </div> 213 var sliderId = $"thumb-scroll-{product.Id}"; 214 if (productVariantGroups.Any() && product?.VariantInfo?.VariantInfo != null) 215 216 { 217 @using Dynamicweb.Ecommerce.Prices 218 @{ 219 string[] variantId = product.VariantId.Split('.'); 220 string showPricesWithVat = Pageview.Area.EcomPricesWithVat.ToLower(); 221 bool neverShowVat = string.IsNullOrEmpty(showPricesWithVat); 222 bool showInformativePrice = Model.Item.GetBoolean("ShowInformativePrice"); 223 string productInfoFeed = ""; 224 bool isLazyLoadingForProductInfoEnabled = Dynamicweb.Core.Converter.ToBoolean(Dynamicweb.Context.Current.Items["IsLazyLoadingForProductInfoEnabled"]); 225 if (isLazyLoadingForProductInfoEnabled) 226 { 227 if (Dynamicweb.Context.Current.Items.Contains("ProductInfoFeed")) 228 { 229 productInfoFeed = Dynamicweb.Context.Current.Items["ProductInfoFeed"]?.ToString(); 230 if (!string.IsNullOrEmpty(productInfoFeed)) 231 { 232 productInfoFeed =productInfoFeed; 233 } 234 } 235 236 } 237 string priceMin = ""; 238 string priceMax = ""; 239 int groupNumber = 1; 240 241 242 243 244 string baseUrl = $"Default.aspx?ID={GetPageIdByNavigationTag("Shop")}&GroupID={product.PrimaryOrDefaultGroup.Id}&ProductID={product.Id}"; 245 if (!string.IsNullOrEmpty(baseUrl)) 246 { 247 baseUrl = $"/{baseUrl.TrimStart('/')}"; 248 } 249 string variantUrl = string.Empty; 250 251 252 Dictionary<string, string> 253 variantImages = new Dictionary<string, string> 254 (); 255 <div class="last-row mt-auto"> 256 257 @foreach (var variantGroup in productVariantGroups) 258 { 259 <div class="thumbnail-wrapper"> 260 <button class="thumb-nav prev" onclick="scrollThumbs('@sliderId', -1)"> 261 <svg width="20px" height="20px" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" fill="#1D98A5"> 262 263 <g stroke="none" stroke-width="1" fill="none" fill-rule="evenodd"> 264 <g transform="translate(-336.000000, 0.000000)"> 265 <g id="left_line" transform="translate(336.000000, 0.000000)"> 266 <path d="M24,0 L24,24 L0,24 L0,0 L24,0 Z M12.5934901,23.257841 L12.5819402,23.2595131 L12.5108777,23.2950439 L12.4918791,23.2987469 L12.4918791,23.2987469 L12.4767152,23.2950439 L12.4056548,23.2595131 C12.3958229,23.2563662 12.3870493,23.2590235 12.3821421,23.2649074 L12.3780323,23.275831 L12.360941,23.7031097 L12.3658947,23.7234994 L12.3769048,23.7357139 L12.4804777,23.8096931 L12.4953491,23.8136134 L12.4953491,23.8136134 L12.5071152,23.8096931 L12.6106902,23.7357139 L12.6232938,23.7196733 L12.6232938,23.7196733 L12.6266527,23.7031097 L12.609561,23.275831 C12.6075724,23.2657013 12.6010112,23.2592993 12.5934901,23.257841 L12.5934901,23.257841 Z M12.8583906,23.1452862 L12.8445485,23.1473072 L12.6598443,23.2396597 L12.6498822,23.2499052 L12.6498822,23.2499052 L12.6471943,23.2611114 L12.6650943,23.6906389 L12.6699349,23.7034178 L12.6699349,23.7034178 L12.678386,23.7104931 L12.8793402,23.8032389 C12.8914285,23.8068999 12.9022333,23.8029875 12.9078286,23.7952264 L12.9118235,23.7811639 L12.8776777,23.1665331 C12.8752882,23.1545897 12.8674102,23.1470016 12.8583906,23.1452862 L12.8583906,23.1452862 Z M12.1430473,23.1473072 C12.1332178,23.1423925 12.1221763,23.1452606 12.1156365,23.1525954 L12.1099173,23.1665331 L12.0757714,23.7811639 C12.0751323,23.7926639 12.0828099,23.8018602 12.0926481,23.8045676 L12.108256,23.8032389 L12.3092106,23.7104931 L12.3186497,23.7024347 L12.3186497,23.7024347 L12.3225043,23.6906389 L12.340401,23.2611114 L12.337245,23.2485176 L12.337245,23.2485176 L12.3277531,23.2396597 L12.1430473,23.1473072 Z" id="MingCute" fill-rule="nonzero"> </path> 267 <path d="M8.29292,12.7071 C7.9024,12.3166 7.9024,11.6834 8.29292,11.2929 L13.9498,5.63604 C14.3403,5.24551 14.9735,5.24551 15.364,5.63604 C15.7545,6.02656 15.7545,6.65973 15.364,7.05025 L10.4142,12 L15.364,16.9497 C15.7545,17.3403 15.7545,17.9734 15.364,18.364 C14.9735,18.7545 14.3403,18.7545 13.9498,18.364 L8.29292,12.7071 Z" id="路径" fill="#1D98A5"> </path> 268 </g> 269 </g> 270 </g> 271 </svg> 272 273 </button> 274 <div class="thumbnail-scroll" id="@sliderId"> 275 @{ 276 VariantGroupViewModel group = variantGroup; 277 foreach (var option in group.Options.OrderBy(o => o.Id)) 278 { 279 var productVariant = productService.GetProductById(product.Id, option.Id, false); 280 281 var productSelection = new PriceProductSelection(productVariant, null, 0); 282 283 var currencyCode = string.IsNullOrWhiteSpace(Pageview.User.Currency) ? Pageview.Area.EcomCurrencyId : Pageview.User.Currency; 284 var countryCode = string.IsNullOrWhiteSpace(Pageview.User.CountryCode) ? Pageview.Area.EcomCountryCode : Pageview.User.CountryCode; 285 286 var userCurrency = Dynamicweb.Ecommerce.Services.Currencies.GetCurrency(currencyCode); 287 var userCountry = Dynamicweb.Ecommerce.Services.Countries.GetCountry(countryCode); 288 289 var priceContext = new PriceContext(userCurrency, userCountry, null, Pageview.User, false, null); 290 var productPrice = Dynamicweb.Ecommerce.Services.Prices.FindPrices(priceContext, productSelection, false); 291 292 //throw new Exception(System.Text.Json.JsonSerializer.Serialize(productPrice)); 293 294 var fieldValue = productVariant?.ProductFieldValues?.GetProductFieldValue("BlockedCustomerList")?.Value; 295 296 if ((fieldValue != null && !fieldValue.ToString().Contains(customerNumber)) || String.IsNullOrWhiteSpace(customerNumber)) 297 { 298 299 300 string active = variantId != null && variantId.Contains(option.Id) ? "active" : string.Empty; 301 string buttonId = $"{product.Id}_{option.Id}_{Pageview.CurrentParagraph.ID}"; 302 string contrastColor = string.Empty; 303 304 string searchKey = $"{product.Id}_{option.Id}_"; 305 /*Images*/ 306 var imagePathVariant = option.Image?.Value ?? ""; 307 308 309 var folderPath = Path.GetDirectoryName(imagePathVariant); 310 311 string physicalFolderPath = Dynamicweb.Context.Current.Server.MapPath(folderPath); 312 313 string lastImage = null; 314 315 if (Directory.Exists(physicalFolderPath)) 316 { 317 318 var fileWith15 = Directory.GetFiles(physicalFolderPath) 319 .FirstOrDefault(f => Path.GetFileName(f).Contains($"{product.Id}_{option.Id}_9")); 320 321 if (fileWith15 != null) 322 { 323 lastImage = fileWith15; 324 } 325 else 326 { 327 var files = Directory.GetFiles(physicalFolderPath) 328 .Where(f => Path.GetFileName(f).StartsWith($"{product.Id}_{option.Id}_")) 329 .OrderByDescending(f => 330 { 331 var filename = Path.GetFileNameWithoutExtension(f); 332 var match = System.Text.RegularExpressions.Regex.Match(filename, @"_(\d+)$"); 333 if (match.Success && int.TryParse(match.Groups[1].Value, out int index)) 334 { 335 return index; 336 } 337 return 0; 338 }) 339 .ToList(); 340 341 if (files.Any()) 342 { 343 lastImage = files.First(); 344 } 345 } 346 } 347 348 var lastImageUrl = lastImage != null ? lastImage : "/Files/Images/zijlstra/Afbeeldingen_overig/Coming_Soon.jpg"; 349 int index = lastImageUrl.IndexOf("Files"); 350 string relativePath = index >= 0 ? lastImageUrl.Substring(index).Replace("\\", "/") : lastImageUrl.Replace("\\", "/"); 351 lastImageUrl = "/" + relativePath; 352 lastImageUrl = Dynamicweb.Context.Current.Server.UrlEncode(lastImageUrl); 353 var variantImg = option.Image is object ? Dynamicweb.Context.Current.Server.UrlEncode(option.Image.Value) : null; 354 var variantLink = "/Default.aspx?ID=" + GetPageIdByNavigationTag("Shop") + "&GroupID=" + product.PrimaryOrDefaultGroup.Id + "&ProductID=" + product.Id + "&VariantID=" + option.Id; 355 356 string variantImage = string.Empty; 357 variantImages.TryGetValue(option.Id, out variantImage); 358 /*End Images*/ 359 360 /*stock state*/ 361 double variantStock = productVariant.Stock; 362 string svgInStock = "<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"16\" height=\"16\" fill=\"#44B11A\" class=\"bi bi-check-lg\" viewBox=\"0 0 16 16\"><path d=\"M12.736 3.97a.733.733 0 0 1 1.047 0c.286.289.29.756.01 1.05L7.88 12.01a.733.733 0 0 1-1.065.02L3.217 8.384a.757.757 0 0 1 0-1.06.733.733 0 0 1 1.047 0l3.052 3.093 5.4-6.425z\"/></svg>"; 363 string svgOutStock = "<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"25\" height=\"25\" fill=\"#CA0D0D\" class=\"bi bi-x-lg\" viewBox=\"0 0 16 16\"><path d=\"M4.646 4.646a.5.5 0 0 1 .708 0L8 7.293l2.646-2.647a.5.5 0 0 1 .708.708L8.707 8l2.647 2.646a.5.5 0 0 1-.708.708L8 8.707l-2.646 2.647a.5.5 0 0 1-.708-.708L7.293 8 4.646 5.354a.5.5 0 0 1 0-.708\"/></svg>"; 364 365 string infoStock = "<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"16\" height=\"16\" fill=\"currentColor\" class=\"bi bi-info-circle-fill\" viewBox=\"0 0 16 16\"><path d=\"M8 16A8 8 0 1 0 8 0a8 8 0 0 0 0 16m.93-9.412-1 4.705c-.07.34.029.533.304.533.194 0 .487-.07.686-.246l-.088.416c-.287.346-.92.598-1.465.598-.703 0-1.002-.422-.808-1.319l.738-3.468c.064-.293.006-.399-.287-.47l-.451-.081.082-.381 2.29-.287zM8 5.5a1 1 0 1 1 0-2 1 1 0 0 1 0 2\" /></svg>"; 366 string isNew = productVariant?.ProductFieldValues?.GetProductFieldValue("New")?.Value?.ToString().ToLower() ?? ""; 367 string isNewSvg = "<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"16\" height=\"16\" fill=\"#F2C400\" class=\"bi bi-star-fill\" viewBox=\"0 0 16 16\"><path d = \"M3.612 15.443c-.386.198-.824-.149-.746-.592l.83-4.73L.173 6.765c-.329-.314-.158-.888.283-.95l4.898-.696L7.538.792c.197-.39.73-.39.927 0l2.184 4.327 4.898.696c.441.062.612.636.282.95l-3.522 3.356.83 4.73c.078.443-.36.79-.746.592L8 13.187l-4.389 2.256z\" /></svg> "; 368 string stockState = ""; 369 370 string isSale = productVariant?.ProductFieldValues?.GetProductFieldValue("Sale")?.Value?.ToString().ToLower() ?? ""; 371 string isSaleSvg = "<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"16\" height=\"16\" fill=\"#F03232\" class=\"bi bi-star-fill\" viewBox=\"0 0 16 16\"><path d = \"M3.612 15.443c-.386.198-.824-.149-.746-.592l.83-4.73L.173 6.765c-.329-.314-.158-.888.283-.95l4.898-.696L7.538.792c.197-.39.73-.39.927 0l2.184 4.327 4.898.696c.441.062.612.636.282.95l-3.522 3.356.83 4.73c.078.443-.36.79-.746.592L8 13.187l-4.389 2.256z\" /></svg> "; 372 373 string expectedDeliveryDate = ""; 374 375 if (DateTime.Compare(productVariant.ExpectedDelivery, new DateTime(1900, 1, 1)) != 0) //In DW, if the Date is not set, it is defaulted 01-01-1900 and not null.. 376 { 377 expectedDeliveryDate = productVariant.ExpectedDelivery.ToShortDateString(); 378 } 379 380 string expectedDeliveryDateText = !String.IsNullOrWhiteSpace(expectedDeliveryDate) ? Translate("Verwacht:") + "&nbsp;" + expectedDeliveryDate : ""; 381 382 @if (!(bool?)productVariant.ProductFieldValues.Where(o => o.ProductField.SystemName == "ProductToBeDiscontinued").SingleOrDefault()?.Value ?? false) 383 { 384 if (variantStock > 0) 385 { 386 if (isNew == "true" || isSale == "true") 387 { 388 if (isSale == "true") 389 { 390 stockState += isSaleSvg + "&nbsp; &nbsp;" + Translate("Sale!") + "<br/>"; 391 } 392 393 if (isNew == "true") 394 { 395 stockState += isNewSvg + "&nbsp; &nbsp;" + Translate("New!") + "<br/>"; 396 } 397 398 stockState += "&nbsp;" + Translate("Nu leverbaar"); 399 } 400 else 401 { 402 stockState = svgInStock + "&nbsp; " + Translate("Op voorraad"); 403 404 } 405 } 406 else 407 { 408 stockState = svgOutStock + "&nbsp;" + Translate("Geen voorraad") + "<br/>" + expectedDeliveryDateText; 409 410 } 411 } 412 else 413 { 414 415 stockState = svgOutStock + "&nbsp;" + Translate("Discontinued:") + "<br/>" + variantStock + "&nbsp;" + @Translate("left in stock"); 416 417 } 418 /*End stock state*/ 419 /*Price variants*/ 420 double price = productVariant.DefaultPrice; 421 double cost = productVariant.Cost; 422 423 string priceFormated = Dynamicweb.Ecommerce.Services.Currencies.Format(Dynamicweb.Ecommerce.Services.Currencies.GetCurrency(currency), Convert.ToDouble(productPrice.ToList()[0].Amount, formatProvider)); 424 //string priceFormated = Dynamicweb.Ecommerce.Services.Currencies.Format(Dynamicweb.Ecommerce.Services.Currencies.GetCurrency(currency), Convert.ToDouble(price, formatProvider)); 425 426 427 428 /*End Price variants*/ 429 430 <img class="theme thumbnail" data-stockstate="@WebUtility.HtmlEncode(stockState)" src="/Admin/Public/GetImage.ashx?image=@(lastImageUrl)&width=64&format=webp" onclick="selectVariant('@(product.Id)','/Admin/Public/GetImage.ashx?image=@(variantImg)&format=webp','@variantLink','@product.Id','@option.Id','@option.Name',this.dataset.stockstate,'@isNew','@isSale','@priceFormated','@cost')" /> 431 432 433 } 434 } 435 436 } 437 </div> 438 <button class="thumb-nav next" onclick="scrollThumbs('@sliderId', 1)"> 439 <svg width="20px" height="20px" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" fill="#1D98A5"> 440 441 <g stroke="none" stroke-width="1" fill="none" fill-rule="evenodd"> 442 <g transform="translate(-384.000000, 0.000000)"> 443 <g id="right_line" transform="translate(384.000000, 0.000000)"> 444 <path d="M24,0 L24,24 L0,24 L0,0 L24,0 Z M12.5934901,23.257841 L12.5819402,23.2595131 L12.5108777,23.2950439 L12.4918791,23.2987469 L12.4918791,23.2987469 L12.4767152,23.2950439 L12.4056548,23.2595131 C12.3958229,23.2563662 12.3870493,23.2590235 12.3821421,23.2649074 L12.3780323,23.275831 L12.360941,23.7031097 L12.3658947,23.7234994 L12.3769048,23.7357139 L12.4804777,23.8096931 L12.4953491,23.8136134 L12.4953491,23.8136134 L12.5071152,23.8096931 L12.6106902,23.7357139 L12.6232938,23.7196733 L12.6232938,23.7196733 L12.6266527,23.7031097 L12.609561,23.275831 C12.6075724,23.2657013 12.6010112,23.2592993 12.5934901,23.257841 L12.5934901,23.257841 Z M12.8583906,23.1452862 L12.8445485,23.1473072 L12.6598443,23.2396597 L12.6498822,23.2499052 L12.6498822,23.2499052 L12.6471943,23.2611114 L12.6650943,23.6906389 L12.6699349,23.7034178 L12.6699349,23.7034178 L12.678386,23.7104931 L12.8793402,23.8032389 C12.8914285,23.8068999 12.9022333,23.8029875 12.9078286,23.7952264 L12.9118235,23.7811639 L12.8776777,23.1665331 C12.8752882,23.1545897 12.8674102,23.1470016 12.8583906,23.1452862 L12.8583906,23.1452862 Z M12.1430473,23.1473072 C12.1332178,23.1423925 12.1221763,23.1452606 12.1156365,23.1525954 L12.1099173,23.1665331 L12.0757714,23.7811639 C12.0751323,23.7926639 12.0828099,23.8018602 12.0926481,23.8045676 L12.108256,23.8032389 L12.3092106,23.7104931 L12.3186497,23.7024347 L12.3186497,23.7024347 L12.3225043,23.6906389 L12.340401,23.2611114 L12.337245,23.2485176 L12.337245,23.2485176 L12.3277531,23.2396597 L12.1430473,23.1473072 Z" id="MingCute" fill-rule="nonzero"> </path> 445 <path d="M15.7072,11.2929 C16.0977,11.6834 16.0977,12.3166 15.7072,12.7071 L10.0503,18.364 C9.65982,18.7545 9.02666,18.7545 8.63613,18.364 C8.24561,17.9734 8.24561,17.3403 8.63613,16.9497 L13.5859,12 L8.63613,7.05025 C8.24561,6.65973 8.24561,6.02656 8.63613,5.63604 C9.02666,5.24551 9.65982,5.24551 10.0503,5.63604 L15.7072,11.2929 Z" id="路径" fill="#1D98A5"> </path> 446 </g> 447 </g> 448 449 </svg> 450 451 </button> 452 </div> 453 } 454 455 456 </div> 457 458 } 459 if ((fieldValueBlocked != null && !fieldValueBlocked.ToString().Contains(customerNumber)) || String.IsNullOrWhiteSpace(customerNumber)) 460 { 461 <div class="stock-state pt-2 mt-auto"> 462 @{ 463 464 /*stock state*/ 465 double MainvariantStock = MainVariant.Stock; 466 string MainsvgInStock = "<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"16\" height=\"16\" fill=\"#44B11A\" class=\"bi bi-check-lg\" viewBox=\"0 0 16 16\"><path d=\"M12.736 3.97a.733.733 0 0 1 1.047 0c.286.289.29.756.01 1.05L7.88 12.01a.733.733 0 0 1-1.065.02L3.217 8.384a.757.757 0 0 1 0-1.06.733.733 0 0 1 1.047 0l3.052 3.093 5.4-6.425z\"/></svg>"; 467 string MainsvgOutStock = "<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"25\" height=\"25\" fill=\"#CA0D0D\" class=\"bi bi-x-lg\" viewBox=\"0 0 16 16\"><path d=\"M4.646 4.646a.5.5 0 0 1 .708 0L8 7.293l2.646-2.647a.5.5 0 0 1 .708.708L8.707 8l2.647 2.646a.5.5 0 0 1-.708.708L8 8.707l-2.646 2.647a.5.5 0 0 1-.708-.708L7.293 8 4.646 5.354a.5.5 0 0 1 0-.708\"/></svg>"; 468 469 string MaininfoStock = "<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"16\" height=\"16\" fill=\"currentColor\" class=\"bi bi-info-circle-fill\" viewBox=\"0 0 16 16\"><path d=\"M8 16A8 8 0 1 0 8 0a8 8 0 0 0 0 16m.93-9.412-1 4.705c-.07.34.029.533.304.533.194 0 .487-.07.686-.246l-.088.416c-.287.346-.92.598-1.465.598-.703 0-1.002-.422-.808-1.319l.738-3.468c.064-.293.006-.399-.287-.47l-.451-.081.082-.381 2.29-.287zM8 5.5a1 1 0 1 1 0-2 1 1 0 0 1 0 2\" /></svg>"; 470 string MainisNew = MainVariant?.ProductFieldValues?.GetProductFieldValue("New")?.Value?.ToString().ToLower() ?? ""; 471 string MainisNewSvg = "<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"16\" height=\"16\" fill=\"#F2C400\" class=\"bi bi-star-fill\" viewBox=\"0 0 16 16\"><path d = \"M3.612 15.443c-.386.198-.824-.149-.746-.592l.83-4.73L.173 6.765c-.329-.314-.158-.888.283-.95l4.898-.696L7.538.792c.197-.39.73-.39.927 0l2.184 4.327 4.898.696c.441.062.612.636.282.95l-3.522 3.356.83 4.73c.078.443-.36.79-.746.592L8 13.187l-4.389 2.256z\" /></svg> "; 472 string MainstockState = ""; 473 string MainIsSale = MainVariant?.ProductFieldValues?.GetProductFieldValue("Sale")?.Value?.ToString().ToLower() ?? ""; 474 string MainIsSaleSvg = "<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"16\" height=\"16\" fill=\"#F03232\" class=\"bi bi-star-fill\" viewBox=\"0 0 16 16\"><path d = \"M3.612 15.443c-.386.198-.824-.149-.746-.592l.83-4.73L.173 6.765c-.329-.314-.158-.888.283-.95l4.898-.696L7.538.792c.197-.39.73-.39.927 0l2.184 4.327 4.898.696c.441.062.612.636.282.95l-3.522 3.356.83 4.73c.078.443-.36.79-.746.592L8 13.187l-4.389 2.256z\" /></svg> "; 475 string MainexpectedDeliveryDate = ""; 476 477 if (DateTime.Compare(MainVariant.ExpectedDelivery, new DateTime(1900, 1, 1)) != 0) //In DW, if the Date is not set, it is defaulted 01-01-1900 and not null.. 478 { 479 MainexpectedDeliveryDate = MainVariant.ExpectedDelivery.ToShortDateString(); 480 } 481 482 string MainexpectedDeliveryDateText = !String.IsNullOrWhiteSpace(MainexpectedDeliveryDate) ? Translate("Verwacht:") + "&nbsp;" + MainexpectedDeliveryDate : ""; 483 484 @if (!(bool?)MainVariant.ProductFieldValues.Where(o => o.ProductField.SystemName == "ProductToBeDiscontinued").SingleOrDefault()?.Value ?? false) 485 { 486 if (MainvariantStock > 0) 487 { 488 if (MainisNew == "true" || MainIsSale == "true") 489 { 490 if (MainIsSale == "true") 491 { 492 MainstockState += MainIsSaleSvg + "&nbsp; &nbsp;" + Translate("Sale!") + "<br/>"; 493 } 494 495 if (MainisNew == "true") 496 { 497 MainstockState += MainisNewSvg + "&nbsp; &nbsp;" + Translate("New!") + "<br/>"; 498 } 499 500 MainstockState += "&nbsp;" + Translate("Nu leverbaar"); 501 } 502 else 503 { 504 MainstockState = MainsvgInStock + "&nbsp; " + Translate("Op voorraad"); 505 506 } 507 } 508 else 509 { 510 MainstockState = MainsvgOutStock + "&nbsp;" + Translate("Geen voorraad") + "<br/>" + MainexpectedDeliveryDateText; 511 512 } 513 } 514 else 515 { 516 517 MainstockState = MainsvgOutStock + "&nbsp;" + Translate("Discontinued:") + "<br/>" + MainvariantStock + "&nbsp;" + @Translate("left in stock"); 518 519 } 520 /*End stock state*/ 521 522 523 @MainstockState 524 525 526 } 527 </div> 528 } 529 else 530 { 531 <div class="stock-state pt-2 mt-auto"> 532 @MainOutStock @Translate("Discontinued") 533 </div> 534 } 535 <div class="custom-price mt-auto"> 536 @{ 537 538 539 540 541 bool isErpConnectionDown = !Dynamicweb.Core.Converter.ToBoolean(Dynamicweb.Context.Current.Items["IsWebServiceConnectionAvailable"]); 542 bool hidePrice = anonymousUsersLimitations.Contains("price") && anonymousUser || Pageview.AreaSettings.GetBoolean("ErpDownHidePrices") && isErpConnectionDown; 543 544 bool productIsDiscontinued = product is object && product.Discontinued; 545 bool doNotShowPriceIfProductIsDiscontinued = Model.Item.GetBoolean("DoNotShowPriceIfProductIsDiscontinued"); 546 var isDiscontinued = productIsDiscontinued && doNotShowPriceIfProductIsDiscontinued; 547 } 548 549 @if (product is object && !hidePrice && !isDiscontinued) 550 { 551 string unitId = !string.IsNullOrEmpty(Dynamicweb.Context.Current.Request.Form.Get("UnitId")) ? Dynamicweb.Context.Current.Request.Form.Get("UnitId") : string.Empty; 552 553 string priceFontSize = Model.Item.GetRawValueString("PriceSize", "fs-4"); 554 string horizontalAlign = Model.Item.GetRawValueString("HorizontalAlignment", ""); 555 string layout = Model.Item.GetRawValueString("Layout", "horizontal"); 556 string textAlign = horizontalAlign == "center" ? "text-center" : string.Empty; 557 textAlign = horizontalAlign == "end" ? "text-end" : textAlign; 558 559 horizontalAlign = horizontalAlign == "center" && layout == "horizontal" ? "justify-content-center" : horizontalAlign; 560 horizontalAlign = horizontalAlign == "end" && layout == "horizontal" ? "justify-content-end" : horizontalAlign; 561 horizontalAlign = horizontalAlign == "center" && layout == "vertical" ? "align-items-center" : horizontalAlign; 562 horizontalAlign = horizontalAlign == "end" && layout == "vertical" ? "align-items-end" : horizontalAlign; 563 564 string flexDirection = layout == "horizontal" ? string.Empty : "flex-column"; 565 string flexGap = layout == "horizontal" ? "gap-3" : string.Empty; 566 string order = layout == "horizontal" ? string.Empty : "order-2"; 567 568 569 string contentPadding = Model.Item.GetRawValueString("ContentPadding", ""); 570 contentPadding = contentPadding == "none" ? "p-0" : contentPadding; 571 contentPadding = contentPadding == "small" ? "p-1 px-md-2 py-md-1" : contentPadding; 572 contentPadding = contentPadding == "large" ? "p-2 px-md-3 py-md-2" : contentPadding; 573 string liveInfoClass = ""; 574 575 576 577 578 579 580 if (isLazyLoadingForProductInfoEnabled) 581 { 582 if (Dynamicweb.Context.Current.Items.Contains("ProductInfoFeed")) 583 { 584 productInfoFeed = Dynamicweb.Context.Current.Items["ProductInfoFeed"]?.ToString(); 585 if (!string.IsNullOrEmpty(productInfoFeed)) 586 { 587 productInfoFeed = $"data-product-info-feed=\"{productInfoFeed}\""; 588 } 589 } 590 liveInfoClass = "js-live-info"; 591 } 592 593 <div class="@textAlign @liveInfoClass item_@Model.Item.SystemName.ToLower()" data-product-id="@product.Id" data-variant-id="@product.VariantId" @productInfoFeed> 594 @if (showInformativePrice && product.PriceInformative.Price != 0) 595 { 596 <div class="opacity-50"> 597 <span>@Translate("RRP") </span> 598 <span class="text-decoration-line-through text-price">@product.PriceInformative.PriceFormatted</span> 599 </div> 600 } 601 <div class="@priceFontSize m-0 d-flex flex-wrap @flexDirection @flexGap @horizontalAlign" style="row-gap: 0 !important" itemprop="offers" itemscope itemtype="https://schema.org/Offer"> 602 <span itemprop="priceCurrency" content="@product.Price.CurrencyCode" class="d-none"></span> 603 604 605 @if (showPricesWithVat == "false" && !neverShowVat) 606 { 607 if (isLazyLoadingForProductInfoEnabled && !Pageview.IsVisualEditorMode) 608 { 609 <span itemprop="price" content="" class="d-none"></span> 610 <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> 611 } 612 else 613 { 614 string beforePrice = !string.IsNullOrEmpty(unitId) ? product.GetPrice(unitId).PriceBeforeDiscount.PriceWithoutVatFormatted : product.PriceBeforeDiscount.PriceWithoutVatFormatted; 615 616 <span itemprop="price" content="@product.Price.PriceWithoutVat.ToString("0.00", System.Globalization.CultureInfo.InvariantCulture)" class="d-none"></span> 617 if (product.Price.Price != product.PriceBeforeDiscount.Price) 618 { 619 <span class="text-decoration-line-through opacity-75 @order">@beforePrice</span> 620 } 621 } 622 } 623 else 624 { 625 if (isLazyLoadingForProductInfoEnabled && !Pageview.IsVisualEditorMode) 626 { 627 <span itemprop="price" content="" class="d-none"></span> 628 <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> 629 } 630 else 631 { 632 string beforePrice = !string.IsNullOrEmpty(unitId) ? product.GetPrice(unitId).PriceBeforeDiscount.PriceFormatted : product.PriceBeforeDiscount.PriceFormatted; 633 634 <span itemprop="price" content="@product.Price.Price.ToString("0.00", System.Globalization.CultureInfo.InvariantCulture)" class="d-none"></span> 635 636 if (product.Price.Price != product.PriceBeforeDiscount.Price) 637 { 638 <span class="text-decoration-line-through opacity-75 @order"> 639 <span class="text-price">@beforePrice</span> 640 </span> 641 } 642 } 643 } 644 645 @if (showPricesWithVat == "false" && !neverShowVat) 646 { 647 if (isLazyLoadingForProductInfoEnabled && !Pageview.IsVisualEditorMode) 648 { 649 <span class="text-price js-text-price"> 650 <span class="spinner-border" role="status"></span> 651 </span> 652 } 653 else 654 { 655 string price = !string.IsNullOrEmpty(unitId) ? product.GetPrice(unitId).Price.PriceWithoutVatFormatted : product.Price.PriceWithoutVatFormatted; 656 657 if (product?.VariantInfo?.VariantInfo != null) 658 { 659 priceMin = product?.VariantInfo?.PriceMin?.PriceWithoutVatFormatted != null ? product.VariantInfo.PriceMin.PriceWithoutVatFormatted : ""; 660 priceMax = product?.VariantInfo?.PriceMax?.PriceWithoutVatFormatted != null ? product.VariantInfo.PriceMax.PriceWithoutVatFormatted : ""; 661 } 662 if (priceMin != priceMax) 663 { 664 price = priceMin + " - " + priceMax; 665 } 666 <span class="@theme @contentPadding"> 667 <span class="text-price">@price</span> 668 </span> 669 } 670 } 671 else 672 { 673 if (isLazyLoadingForProductInfoEnabled && !Pageview.IsVisualEditorMode) 674 { 675 <span class="text-price js-text-price"> 676 <span class="spinner-border" role="status"></span> 677 </span> 678 } 679 else 680 { 681 string price = !string.IsNullOrEmpty(unitId) ? product.GetPrice(unitId).Price.PriceFormatted : product.Price.PriceFormatted; 682 683 if (product?.VariantInfo?.VariantInfo != null) 684 { 685 priceMin = product?.VariantInfo?.PriceMin?.PriceFormatted != null ? product.VariantInfo.PriceMin.PriceFormatted : ""; 686 priceMax = product?.VariantInfo?.PriceMax?.PriceFormatted != null ? product.VariantInfo.PriceMax.PriceFormatted : ""; 687 } 688 if (priceMin != priceMax) 689 { 690 price = priceMin + " - " + priceMax; 691 } 692 <span class="@theme @contentPadding"> 693 <span class="text-price">@price</span> 694 </span> 695 } 696 } 697 698 @* Stock state for Schema.org, start *@ 699 @{ 700 Uri url = Dynamicweb.Context.Current.Request.Url; 701 } 702 703 <link itemprop="url" href="@url"> 704 705 @{ 706 bool IsNeverOutOfStock = product.NeverOutOfstock; 707 } 708 709 @if (IsNeverOutOfStock) 710 { 711 <span itemprop="availability" class="d-none">@Translate("Available in stock")</span> 712 } 713 else 714 { 715 if (product.StockLevel > 0) 716 { 717 <span itemprop="availability" class="d-none">InStock</span> 718 } 719 else 720 { 721 <span itemprop="availability" class="d-none">OutOfStock</span> 722 } 723 } 724 @* Stock state for Schema.org, stop *@ 725 726 </div> 727 728 @if (showPricesWithVat == "false" && !neverShowVat) 729 { 730 if (isLazyLoadingForProductInfoEnabled && !Pageview.IsVisualEditorMode) 731 { 732 <small class="opacity-85 fst-normal js-text-price-with-vat d-none" data-suffix="@Translate("Incl. VAT")"></small> 733 } 734 else 735 { 736 string price = !string.IsNullOrEmpty(unitId) ? product.GetPrice(unitId).Price.PriceWithVatFormatted : product.Price.PriceWithVatFormatted; 737 738 if (product?.VariantInfo?.VariantInfo != null) 739 { 740 priceMin = product?.VariantInfo?.PriceMin?.PriceWithVatFormatted != null ? product.VariantInfo.PriceMin.PriceWithVatFormatted : ""; 741 priceMax = product?.VariantInfo?.PriceMax?.PriceWithVatFormatted != null ? product.VariantInfo.PriceMax.PriceWithVatFormatted : ""; 742 } 743 if (priceMin != priceMax) 744 { 745 price = priceMin + " - " + priceMax; 746 } 747 <!-- <small class="opacity-85 fst-normal">@price @Translate("Incl. VAT")</small> --> 748 } 749 } 750 </div> 751 } 752 else if (Pageview.IsVisualEditorMode) 753 { 754 <div class="alert alert-dark m-0" role="alert"> 755 <span>@Translate("No products available")</span> 756 </div> 757 } 758 759 </div> 760 } 761 } 762
Tischlampe 1L Arch wood
Error executing template "Designs/Swift/Paragraph/CustomProductSlider.cshtml"
System.NullReferenceException: Object reference not set to an instance of an object.
   at CompiledRazorTemplates.Dynamic.RazorEngine_3562354021b44d5c892fe73dc2806e4f.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 Dynamicweb.Ecommerce.ProductCatalog 3 @using Dynamicweb.Ecommerce.CustomerExperienceCenter.Favorites 4 @using Dynamicweb.Files 5 @using System.IO 6 @using System.Net 7 @using Dynamicweb.Security.UserManagement 8 9 10 @{ 11 ProductViewModel product = null; 12 if (Dynamicweb.Context.Current.Items.Contains("ProductDetails")) 13 { 14 product = (ProductViewModel)Dynamicweb.Context.Current.Items["ProductDetails"]; 15 } 16 else if (Pageview.Page.Item["DummyProduct"] != null && Pageview.IsVisualEditorMode) 17 { 18 var pageViewModel = Dynamicweb.Frontend.ContentViewModelFactory.CreatePageInfoViewModel(Pageview.Page); 19 ProductListViewModel productList = pageViewModel.Item.GetValue("DummyProduct") != null ? pageViewModel.Item.GetValue("DummyProduct") as ProductListViewModel : new ProductListViewModel(); 20 21 if (productList?.Products is object) 22 { 23 product = productList.Products[0]; 24 } 25 } 26 } 27 28 @{ 29 var currentUser = Pageview?.User; 30 var customerNumber = !string.IsNullOrEmpty(currentUser?.CustomerNumber) 31 ? currentUser.CustomerNumber 32 : ""; 33 } 34 @if (product is object) 35 { 36 string imagePath = product?.DefaultImage?.Value ?? ""; 37 string imagePathUrlEncoded = Dynamicweb.Context.Current.Server.UrlEncode(imagePath); 38 39 string ratio = Model.Item.GetRawValueString("ImageAspectRatio", ""); 40 ratio = ratio != "0" ? ratio : ""; 41 string ratioCssClass = ratio != "" ? " ratio" : ""; 42 string ratioVariable = ratio != "" ? "--bs-aspect-ratio: " + ratio + ";" : ""; 43 44 string width = Model.Item.GetRawValueString("Width", "auto"); 45 int smallImageSize = 640; 46 int largeImageSize = width == "auto" ? 1280 : Convert.ToInt32(width); 47 48 string ImageObjectFit = Model.Item.GetRawValueString("ImageObjectFit", "contain"); 49 50 string imagePathXs = "/Admin/Public/GetImage.ashx?width=" + smallImageSize + "&image=" + imagePathUrlEncoded + "&format=webp"; 51 string imagePathS = "/Admin/Public/GetImage.ashx?width=" + largeImageSize + "&image=" + imagePathUrlEncoded + "&format=webp"; 52 string imagePathFallBack = "/Admin/Public/GetImage.ashx?width=" + largeImageSize + "&image=" + imagePathUrlEncoded + "&format=webp"; 53 54 var badgeParms = new Dictionary<string, object>(); 55 badgeParms.Add("size", "h7"); 56 badgeParms.Add("saleBadgeType", Model.Item.GetRawValue("SaleBadgeType")); 57 badgeParms.Add("saleBadgeCssClassName", Model.Item.GetRawValue("SaleBadgeDesign")); 58 badgeParms.Add("newBadgeCssClassName", Model.Item.GetRawValue("NewBadgeDesign")); 59 badgeParms.Add("newPublicationDays", Model.Item.GetInt32("NewPublicationDays")); 60 badgeParms.Add("campaignBadgesValues", Model.Item.GetList("CampaignBadges")?.GetRawValue().OfType<string>().ToList()); 61 62 string badgeSize = Model.Item.GetRawValueString("BadgeSize", "fs-2"); 63 bool saleBadgeEnabled = !string.IsNullOrWhiteSpace(Model.Item.GetRawValueString("SaleBadgeDesign")) && Model.Item.GetRawValueString("SaleBadgeDesign") != "none" ? true : false; 64 bool newBadgeEnabled = !string.IsNullOrWhiteSpace(Model.Item.GetRawValueString("NewBadgeDesign")) && Model.Item.GetRawValueString("NewBadgeDesign") != "none" ? true : false; 65 66 /*Custom badge*/ 67 var productService = new Dynamicweb.Ecommerce.Products.ProductService(); 68 var currency = Dynamicweb.Ecommerce.Common.Context.Currency.Code; 69 var formatProvider = new System.Globalization.NumberFormatInfo(); 70 formatProvider.NumberDecimalSeparator = "."; 71 formatProvider.NumberGroupSeparator = ","; 72 var MainVariant = productService.GetProductById(product.Id, product.VariantId, false); 73 var fieldValueBlocked = MainVariant?.ProductFieldValues?.GetProductFieldValue("BlockedCustomerList")?.Value; 74 75 76 string isNewProduct = MainVariant?.ProductFieldValues?.GetProductFieldValue("New")?.Value?.ToString().ToLower() ?? ""; 77 string MainisSale = MainVariant?.ProductFieldValues?.GetProductFieldValue("Sale")?.Value?.ToString().ToLower() ?? ""; 78 bool showNewBadge = isNewProduct == "true" ? true : false; 79 bool showSaleBadge = MainisSale == "true" ? true : false; 80 string showNewSaleBadge = "d-none"; 81 if (showSaleBadge) 82 { 83 badgeParms.Add("isSale", "true"); 84 85 } 86 else 87 { 88 badgeParms.Add("isSale", "false"); 89 } 90 if (showNewBadge) 91 { 92 badgeParms.Add("isNew", "true"); 93 } 94 else 95 { 96 badgeParms.Add("isNew", "false"); 97 } 98 /*End Custom badge*/ 99 if (showSaleBadge || showNewBadge) 100 { 101 showNewSaleBadge = ""; 102 } 103 DateTime createdDate = product.Created.Value; 104 bool showBadges = saleBadgeEnabled && product.Discount.Price != 0 ? true : false; 105 106 bool showFavoritesSelector = !string.IsNullOrEmpty(Model.Item.GetString("ShowAddToFavorites")) ? Model.Item.GetBoolean("ShowAddToFavorites") : false; 107 string anonymousUsersLimitations = Pageview.AreaSettings.GetRawValueString("AnonymousUsers", ""); 108 bool anonymousUser = Pageview.User == null; 109 110 var favoriteParameters = new Dictionary<string, object>(); 111 if (!anonymousUser && showFavoritesSelector) 112 { 113 int defaultFavoriteListId = 0; 114 115 IEnumerable<FavoriteList> favoreiteLists = Pageview.User.GetFavoriteLists(); 116 if (favoreiteLists.Count() == 1) 117 { 118 foreach (FavoriteList list in favoreiteLists) 119 { 120 defaultFavoriteListId = list.ListId; 121 } 122 } 123 124 favoriteParameters.Add("ListId", defaultFavoriteListId); 125 } 126 127 MediaViewModel alternativeImage = new MediaViewModel(); 128 if (Model.Item.GetBoolean("ShowAlternativeImageOnHover")) 129 { 130 var selectedImageCategories = Model.Item.GetList("GetAlternativeImageFrom")?.GetRawValue().OfType<string>().ToList(); 131 List<MediaViewModel> allAssetsImages = product.AssetCategories.Where(x => selectedImageCategories.Contains(x.SystemName)).SelectMany(x => x.Assets).ToList(); 132 allAssetsImages.RemoveAll(x => x.Value == product.DefaultImage.Value); 133 alternativeImage = allAssetsImages.FirstOrDefault(); 134 } 135 136 string altImagePathXs = string.Empty; 137 string altImagePathS = string.Empty; 138 139 if (!string.IsNullOrEmpty(alternativeImage?.Value)) 140 { 141 altImagePathXs = "/Admin/Public/GetImage.ashx?width=" + smallImageSize + "&image=" + Dynamicweb.Context.Current.Server.UrlEncode(alternativeImage.Value) + "&format=webp"; 142 altImagePathS = "/Admin/Public/GetImage.ashx?width=" + largeImageSize + "&image=" + Dynamicweb.Context.Current.Server.UrlEncode(alternativeImage.Value) + "&format=webp"; 143 } 144 145 @* Theme settings *@ 146 string theme = !string.IsNullOrWhiteSpace(Model.Item.GetRawValueString("Theme")) ? " theme " + Model.Item.GetRawValueString("Theme").Replace(" ", "").Trim().ToLower() : ""; 147 string themeBorder = !string.IsNullOrWhiteSpace(theme) ? "border: 1px solid rgba(0,0,0,0)" : ""; 148 string themePadding = !string.IsNullOrWhiteSpace(theme) ? "p-2 p-lg-3" : ""; 149 150 string imageId = "ProductImage_" + product.Id; 151 152 153 154 string fullWidth = width == "auto" ? "w-100" : ""; 155 string customWidth = width != "auto" ? "style=\"width: " + width + "px\"" : "style=\"min-width: 60px\""; 156 157 string altImageZindex = Model.Item.GetBoolean("ShowAlternativeImageOnHover") && !string.IsNullOrEmpty(alternativeImage?.Value) ? " z-index: 1" : string.Empty; 158 string groupid = !string.IsNullOrEmpty(Dynamicweb.Context.Current.Request.QueryString.Get("GroupID")) ? Dynamicweb.Context.Current.Request.QueryString.Get("GroupID"):"" ; 159 string link = product.GetProductLink(GetPageIdByNavigationTag("Shop"), false); 160 var productVariantGroups = product.VariantGroups(); 161 string MainOutStock = "<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"25\" height=\"25\" fill=\"#CA0D0D\" class=\"bi bi-x-lg\" viewBox=\"0 0 16 16\"><path d=\"M4.646 4.646a.5.5 0 0 1 .708 0L8 7.293l2.646-2.647a.5.5 0 0 1 .708.708L8.707 8l2.647 2.646a.5.5 0 0 1-.708.708L8 8.707l-2.646 2.647a.5.5 0 0 1-.708-.708L7.293 8 4.646 5.354a.5.5 0 0 1 0-.708\"/></svg>"; 162 163 @if (!string.IsNullOrEmpty(imagePath)) 164 { 165 <div class="@fullWidth @theme position-relative item_@Model.Item.SystemName.ToLower() main-image-container" @customWidth> 166 <div class="" style="@(ratioVariable)@(altImageZindex)"> 167 <div class="d-flex justify-content-center align-items-center"> 168 <a class="main-link-link" href="@link"> 169 @if (imagePath.StartsWith("/Files/", StringComparison.OrdinalIgnoreCase)) 170 { 171 <img id="@imageId" 172 srcset=" 173 @imagePathXs @(smallImageSize)w, 174 @imagePathS @(largeImageSize)w" 175 sizes="(max-width: 992px) 50vw, 25vw" 176 src="@imagePathFallBack" 177 loading="lazy" 178 decoding="async" 179 class="h-100 w-100 @themePadding main-image" 180 style="object-fit: @ImageObjectFit; @themeBorder " 181 alt="@product.Name" 182 itemprop="image"> 183 } 184 else 185 { 186 <img src="@product.DefaultImage.Value" 187 loading="lazy" 188 class="h-100 w-100 @themePadding main-image" 189 style="object-fit: contain; @themeBorder" 190 alt="@product.Name" 191 itemprop="image"> 192 } 193 </a> 194 </div> 195 </div> 196 197 <div class="position-absolute top-0 left-0 p-2 pb-0 custom-badge-product-list @showNewSaleBadge"> 198 @{ 199 @RenderPartial("Components/Custom_EcommerceBadge.cshtml", product, badgeParms) 200 } 201 </div> 202 203 204 </div> 205 } 206 207 <div class="product-info h-100"> 208 <div class="fs-7 pt-1 opacity-85 start item_@Model.Item.SystemName.ToLower() product-number" itemprop="sku">@product.Id / @product.VariantId - @product.VariantName</div> 209 <div class="py-2" data-col-size="12"> 210 <h2 class="h6 start m-0 item_swift_productheader product-name" itemprop="name"><b>@product.Name</b></h2> 211 </div> 212 </div> 213 var sliderId = $"thumb-scroll-{product.Id}"; 214 if (productVariantGroups.Any() && product?.VariantInfo?.VariantInfo != null) 215 216 { 217 @using Dynamicweb.Ecommerce.Prices 218 @{ 219 string[] variantId = product.VariantId.Split('.'); 220 string showPricesWithVat = Pageview.Area.EcomPricesWithVat.ToLower(); 221 bool neverShowVat = string.IsNullOrEmpty(showPricesWithVat); 222 bool showInformativePrice = Model.Item.GetBoolean("ShowInformativePrice"); 223 string productInfoFeed = ""; 224 bool isLazyLoadingForProductInfoEnabled = Dynamicweb.Core.Converter.ToBoolean(Dynamicweb.Context.Current.Items["IsLazyLoadingForProductInfoEnabled"]); 225 if (isLazyLoadingForProductInfoEnabled) 226 { 227 if (Dynamicweb.Context.Current.Items.Contains("ProductInfoFeed")) 228 { 229 productInfoFeed = Dynamicweb.Context.Current.Items["ProductInfoFeed"]?.ToString(); 230 if (!string.IsNullOrEmpty(productInfoFeed)) 231 { 232 productInfoFeed =productInfoFeed; 233 } 234 } 235 236 } 237 string priceMin = ""; 238 string priceMax = ""; 239 int groupNumber = 1; 240 241 242 243 244 string baseUrl = $"Default.aspx?ID={GetPageIdByNavigationTag("Shop")}&GroupID={product.PrimaryOrDefaultGroup.Id}&ProductID={product.Id}"; 245 if (!string.IsNullOrEmpty(baseUrl)) 246 { 247 baseUrl = $"/{baseUrl.TrimStart('/')}"; 248 } 249 string variantUrl = string.Empty; 250 251 252 Dictionary<string, string> 253 variantImages = new Dictionary<string, string> 254 (); 255 <div class="last-row mt-auto"> 256 257 @foreach (var variantGroup in productVariantGroups) 258 { 259 <div class="thumbnail-wrapper"> 260 <button class="thumb-nav prev" onclick="scrollThumbs('@sliderId', -1)"> 261 <svg width="20px" height="20px" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" fill="#1D98A5"> 262 263 <g stroke="none" stroke-width="1" fill="none" fill-rule="evenodd"> 264 <g transform="translate(-336.000000, 0.000000)"> 265 <g id="left_line" transform="translate(336.000000, 0.000000)"> 266 <path d="M24,0 L24,24 L0,24 L0,0 L24,0 Z M12.5934901,23.257841 L12.5819402,23.2595131 L12.5108777,23.2950439 L12.4918791,23.2987469 L12.4918791,23.2987469 L12.4767152,23.2950439 L12.4056548,23.2595131 C12.3958229,23.2563662 12.3870493,23.2590235 12.3821421,23.2649074 L12.3780323,23.275831 L12.360941,23.7031097 L12.3658947,23.7234994 L12.3769048,23.7357139 L12.4804777,23.8096931 L12.4953491,23.8136134 L12.4953491,23.8136134 L12.5071152,23.8096931 L12.6106902,23.7357139 L12.6232938,23.7196733 L12.6232938,23.7196733 L12.6266527,23.7031097 L12.609561,23.275831 C12.6075724,23.2657013 12.6010112,23.2592993 12.5934901,23.257841 L12.5934901,23.257841 Z M12.8583906,23.1452862 L12.8445485,23.1473072 L12.6598443,23.2396597 L12.6498822,23.2499052 L12.6498822,23.2499052 L12.6471943,23.2611114 L12.6650943,23.6906389 L12.6699349,23.7034178 L12.6699349,23.7034178 L12.678386,23.7104931 L12.8793402,23.8032389 C12.8914285,23.8068999 12.9022333,23.8029875 12.9078286,23.7952264 L12.9118235,23.7811639 L12.8776777,23.1665331 C12.8752882,23.1545897 12.8674102,23.1470016 12.8583906,23.1452862 L12.8583906,23.1452862 Z M12.1430473,23.1473072 C12.1332178,23.1423925 12.1221763,23.1452606 12.1156365,23.1525954 L12.1099173,23.1665331 L12.0757714,23.7811639 C12.0751323,23.7926639 12.0828099,23.8018602 12.0926481,23.8045676 L12.108256,23.8032389 L12.3092106,23.7104931 L12.3186497,23.7024347 L12.3186497,23.7024347 L12.3225043,23.6906389 L12.340401,23.2611114 L12.337245,23.2485176 L12.337245,23.2485176 L12.3277531,23.2396597 L12.1430473,23.1473072 Z" id="MingCute" fill-rule="nonzero"> </path> 267 <path d="M8.29292,12.7071 C7.9024,12.3166 7.9024,11.6834 8.29292,11.2929 L13.9498,5.63604 C14.3403,5.24551 14.9735,5.24551 15.364,5.63604 C15.7545,6.02656 15.7545,6.65973 15.364,7.05025 L10.4142,12 L15.364,16.9497 C15.7545,17.3403 15.7545,17.9734 15.364,18.364 C14.9735,18.7545 14.3403,18.7545 13.9498,18.364 L8.29292,12.7071 Z" id="路径" fill="#1D98A5"> </path> 268 </g> 269 </g> 270 </g> 271 </svg> 272 273 </button> 274 <div class="thumbnail-scroll" id="@sliderId"> 275 @{ 276 VariantGroupViewModel group = variantGroup; 277 foreach (var option in group.Options.OrderBy(o => o.Id)) 278 { 279 var productVariant = productService.GetProductById(product.Id, option.Id, false); 280 281 var productSelection = new PriceProductSelection(productVariant, null, 0); 282 283 var currencyCode = string.IsNullOrWhiteSpace(Pageview.User.Currency) ? Pageview.Area.EcomCurrencyId : Pageview.User.Currency; 284 var countryCode = string.IsNullOrWhiteSpace(Pageview.User.CountryCode) ? Pageview.Area.EcomCountryCode : Pageview.User.CountryCode; 285 286 var userCurrency = Dynamicweb.Ecommerce.Services.Currencies.GetCurrency(currencyCode); 287 var userCountry = Dynamicweb.Ecommerce.Services.Countries.GetCountry(countryCode); 288 289 var priceContext = new PriceContext(userCurrency, userCountry, null, Pageview.User, false, null); 290 var productPrice = Dynamicweb.Ecommerce.Services.Prices.FindPrices(priceContext, productSelection, false); 291 292 //throw new Exception(System.Text.Json.JsonSerializer.Serialize(productPrice)); 293 294 var fieldValue = productVariant?.ProductFieldValues?.GetProductFieldValue("BlockedCustomerList")?.Value; 295 296 if ((fieldValue != null && !fieldValue.ToString().Contains(customerNumber)) || String.IsNullOrWhiteSpace(customerNumber)) 297 { 298 299 300 string active = variantId != null && variantId.Contains(option.Id) ? "active" : string.Empty; 301 string buttonId = $"{product.Id}_{option.Id}_{Pageview.CurrentParagraph.ID}"; 302 string contrastColor = string.Empty; 303 304 string searchKey = $"{product.Id}_{option.Id}_"; 305 /*Images*/ 306 var imagePathVariant = option.Image?.Value ?? ""; 307 308 309 var folderPath = Path.GetDirectoryName(imagePathVariant); 310 311 string physicalFolderPath = Dynamicweb.Context.Current.Server.MapPath(folderPath); 312 313 string lastImage = null; 314 315 if (Directory.Exists(physicalFolderPath)) 316 { 317 318 var fileWith15 = Directory.GetFiles(physicalFolderPath) 319 .FirstOrDefault(f => Path.GetFileName(f).Contains($"{product.Id}_{option.Id}_9")); 320 321 if (fileWith15 != null) 322 { 323 lastImage = fileWith15; 324 } 325 else 326 { 327 var files = Directory.GetFiles(physicalFolderPath) 328 .Where(f => Path.GetFileName(f).StartsWith($"{product.Id}_{option.Id}_")) 329 .OrderByDescending(f => 330 { 331 var filename = Path.GetFileNameWithoutExtension(f); 332 var match = System.Text.RegularExpressions.Regex.Match(filename, @"_(\d+)$"); 333 if (match.Success && int.TryParse(match.Groups[1].Value, out int index)) 334 { 335 return index; 336 } 337 return 0; 338 }) 339 .ToList(); 340 341 if (files.Any()) 342 { 343 lastImage = files.First(); 344 } 345 } 346 } 347 348 var lastImageUrl = lastImage != null ? lastImage : "/Files/Images/zijlstra/Afbeeldingen_overig/Coming_Soon.jpg"; 349 int index = lastImageUrl.IndexOf("Files"); 350 string relativePath = index >= 0 ? lastImageUrl.Substring(index).Replace("\\", "/") : lastImageUrl.Replace("\\", "/"); 351 lastImageUrl = "/" + relativePath; 352 lastImageUrl = Dynamicweb.Context.Current.Server.UrlEncode(lastImageUrl); 353 var variantImg = option.Image is object ? Dynamicweb.Context.Current.Server.UrlEncode(option.Image.Value) : null; 354 var variantLink = "/Default.aspx?ID=" + GetPageIdByNavigationTag("Shop") + "&GroupID=" + product.PrimaryOrDefaultGroup.Id + "&ProductID=" + product.Id + "&VariantID=" + option.Id; 355 356 string variantImage = string.Empty; 357 variantImages.TryGetValue(option.Id, out variantImage); 358 /*End Images*/ 359 360 /*stock state*/ 361 double variantStock = productVariant.Stock; 362 string svgInStock = "<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"16\" height=\"16\" fill=\"#44B11A\" class=\"bi bi-check-lg\" viewBox=\"0 0 16 16\"><path d=\"M12.736 3.97a.733.733 0 0 1 1.047 0c.286.289.29.756.01 1.05L7.88 12.01a.733.733 0 0 1-1.065.02L3.217 8.384a.757.757 0 0 1 0-1.06.733.733 0 0 1 1.047 0l3.052 3.093 5.4-6.425z\"/></svg>"; 363 string svgOutStock = "<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"25\" height=\"25\" fill=\"#CA0D0D\" class=\"bi bi-x-lg\" viewBox=\"0 0 16 16\"><path d=\"M4.646 4.646a.5.5 0 0 1 .708 0L8 7.293l2.646-2.647a.5.5 0 0 1 .708.708L8.707 8l2.647 2.646a.5.5 0 0 1-.708.708L8 8.707l-2.646 2.647a.5.5 0 0 1-.708-.708L7.293 8 4.646 5.354a.5.5 0 0 1 0-.708\"/></svg>"; 364 365 string infoStock = "<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"16\" height=\"16\" fill=\"currentColor\" class=\"bi bi-info-circle-fill\" viewBox=\"0 0 16 16\"><path d=\"M8 16A8 8 0 1 0 8 0a8 8 0 0 0 0 16m.93-9.412-1 4.705c-.07.34.029.533.304.533.194 0 .487-.07.686-.246l-.088.416c-.287.346-.92.598-1.465.598-.703 0-1.002-.422-.808-1.319l.738-3.468c.064-.293.006-.399-.287-.47l-.451-.081.082-.381 2.29-.287zM8 5.5a1 1 0 1 1 0-2 1 1 0 0 1 0 2\" /></svg>"; 366 string isNew = productVariant?.ProductFieldValues?.GetProductFieldValue("New")?.Value?.ToString().ToLower() ?? ""; 367 string isNewSvg = "<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"16\" height=\"16\" fill=\"#F2C400\" class=\"bi bi-star-fill\" viewBox=\"0 0 16 16\"><path d = \"M3.612 15.443c-.386.198-.824-.149-.746-.592l.83-4.73L.173 6.765c-.329-.314-.158-.888.283-.95l4.898-.696L7.538.792c.197-.39.73-.39.927 0l2.184 4.327 4.898.696c.441.062.612.636.282.95l-3.522 3.356.83 4.73c.078.443-.36.79-.746.592L8 13.187l-4.389 2.256z\" /></svg> "; 368 string stockState = ""; 369 370 string isSale = productVariant?.ProductFieldValues?.GetProductFieldValue("Sale")?.Value?.ToString().ToLower() ?? ""; 371 string isSaleSvg = "<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"16\" height=\"16\" fill=\"#F03232\" class=\"bi bi-star-fill\" viewBox=\"0 0 16 16\"><path d = \"M3.612 15.443c-.386.198-.824-.149-.746-.592l.83-4.73L.173 6.765c-.329-.314-.158-.888.283-.95l4.898-.696L7.538.792c.197-.39.73-.39.927 0l2.184 4.327 4.898.696c.441.062.612.636.282.95l-3.522 3.356.83 4.73c.078.443-.36.79-.746.592L8 13.187l-4.389 2.256z\" /></svg> "; 372 373 string expectedDeliveryDate = ""; 374 375 if (DateTime.Compare(productVariant.ExpectedDelivery, new DateTime(1900, 1, 1)) != 0) //In DW, if the Date is not set, it is defaulted 01-01-1900 and not null.. 376 { 377 expectedDeliveryDate = productVariant.ExpectedDelivery.ToShortDateString(); 378 } 379 380 string expectedDeliveryDateText = !String.IsNullOrWhiteSpace(expectedDeliveryDate) ? Translate("Verwacht:") + "&nbsp;" + expectedDeliveryDate : ""; 381 382 @if (!(bool?)productVariant.ProductFieldValues.Where(o => o.ProductField.SystemName == "ProductToBeDiscontinued").SingleOrDefault()?.Value ?? false) 383 { 384 if (variantStock > 0) 385 { 386 if (isNew == "true" || isSale == "true") 387 { 388 if (isSale == "true") 389 { 390 stockState += isSaleSvg + "&nbsp; &nbsp;" + Translate("Sale!") + "<br/>"; 391 } 392 393 if (isNew == "true") 394 { 395 stockState += isNewSvg + "&nbsp; &nbsp;" + Translate("New!") + "<br/>"; 396 } 397 398 stockState += "&nbsp;" + Translate("Nu leverbaar"); 399 } 400 else 401 { 402 stockState = svgInStock + "&nbsp; " + Translate("Op voorraad"); 403 404 } 405 } 406 else 407 { 408 stockState = svgOutStock + "&nbsp;" + Translate("Geen voorraad") + "<br/>" + expectedDeliveryDateText; 409 410 } 411 } 412 else 413 { 414 415 stockState = svgOutStock + "&nbsp;" + Translate("Discontinued:") + "<br/>" + variantStock + "&nbsp;" + @Translate("left in stock"); 416 417 } 418 /*End stock state*/ 419 /*Price variants*/ 420 double price = productVariant.DefaultPrice; 421 double cost = productVariant.Cost; 422 423 string priceFormated = Dynamicweb.Ecommerce.Services.Currencies.Format(Dynamicweb.Ecommerce.Services.Currencies.GetCurrency(currency), Convert.ToDouble(productPrice.ToList()[0].Amount, formatProvider)); 424 //string priceFormated = Dynamicweb.Ecommerce.Services.Currencies.Format(Dynamicweb.Ecommerce.Services.Currencies.GetCurrency(currency), Convert.ToDouble(price, formatProvider)); 425 426 427 428 /*End Price variants*/ 429 430 <img class="theme thumbnail" data-stockstate="@WebUtility.HtmlEncode(stockState)" src="/Admin/Public/GetImage.ashx?image=@(lastImageUrl)&width=64&format=webp" onclick="selectVariant('@(product.Id)','/Admin/Public/GetImage.ashx?image=@(variantImg)&format=webp','@variantLink','@product.Id','@option.Id','@option.Name',this.dataset.stockstate,'@isNew','@isSale','@priceFormated','@cost')" /> 431 432 433 } 434 } 435 436 } 437 </div> 438 <button class="thumb-nav next" onclick="scrollThumbs('@sliderId', 1)"> 439 <svg width="20px" height="20px" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" fill="#1D98A5"> 440 441 <g stroke="none" stroke-width="1" fill="none" fill-rule="evenodd"> 442 <g transform="translate(-384.000000, 0.000000)"> 443 <g id="right_line" transform="translate(384.000000, 0.000000)"> 444 <path d="M24,0 L24,24 L0,24 L0,0 L24,0 Z M12.5934901,23.257841 L12.5819402,23.2595131 L12.5108777,23.2950439 L12.4918791,23.2987469 L12.4918791,23.2987469 L12.4767152,23.2950439 L12.4056548,23.2595131 C12.3958229,23.2563662 12.3870493,23.2590235 12.3821421,23.2649074 L12.3780323,23.275831 L12.360941,23.7031097 L12.3658947,23.7234994 L12.3769048,23.7357139 L12.4804777,23.8096931 L12.4953491,23.8136134 L12.4953491,23.8136134 L12.5071152,23.8096931 L12.6106902,23.7357139 L12.6232938,23.7196733 L12.6232938,23.7196733 L12.6266527,23.7031097 L12.609561,23.275831 C12.6075724,23.2657013 12.6010112,23.2592993 12.5934901,23.257841 L12.5934901,23.257841 Z M12.8583906,23.1452862 L12.8445485,23.1473072 L12.6598443,23.2396597 L12.6498822,23.2499052 L12.6498822,23.2499052 L12.6471943,23.2611114 L12.6650943,23.6906389 L12.6699349,23.7034178 L12.6699349,23.7034178 L12.678386,23.7104931 L12.8793402,23.8032389 C12.8914285,23.8068999 12.9022333,23.8029875 12.9078286,23.7952264 L12.9118235,23.7811639 L12.8776777,23.1665331 C12.8752882,23.1545897 12.8674102,23.1470016 12.8583906,23.1452862 L12.8583906,23.1452862 Z M12.1430473,23.1473072 C12.1332178,23.1423925 12.1221763,23.1452606 12.1156365,23.1525954 L12.1099173,23.1665331 L12.0757714,23.7811639 C12.0751323,23.7926639 12.0828099,23.8018602 12.0926481,23.8045676 L12.108256,23.8032389 L12.3092106,23.7104931 L12.3186497,23.7024347 L12.3186497,23.7024347 L12.3225043,23.6906389 L12.340401,23.2611114 L12.337245,23.2485176 L12.337245,23.2485176 L12.3277531,23.2396597 L12.1430473,23.1473072 Z" id="MingCute" fill-rule="nonzero"> </path> 445 <path d="M15.7072,11.2929 C16.0977,11.6834 16.0977,12.3166 15.7072,12.7071 L10.0503,18.364 C9.65982,18.7545 9.02666,18.7545 8.63613,18.364 C8.24561,17.9734 8.24561,17.3403 8.63613,16.9497 L13.5859,12 L8.63613,7.05025 C8.24561,6.65973 8.24561,6.02656 8.63613,5.63604 C9.02666,5.24551 9.65982,5.24551 10.0503,5.63604 L15.7072,11.2929 Z" id="路径" fill="#1D98A5"> </path> 446 </g> 447 </g> 448 449 </svg> 450 451 </button> 452 </div> 453 } 454 455 456 </div> 457 458 } 459 if ((fieldValueBlocked != null && !fieldValueBlocked.ToString().Contains(customerNumber)) || String.IsNullOrWhiteSpace(customerNumber)) 460 { 461 <div class="stock-state pt-2 mt-auto"> 462 @{ 463 464 /*stock state*/ 465 double MainvariantStock = MainVariant.Stock; 466 string MainsvgInStock = "<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"16\" height=\"16\" fill=\"#44B11A\" class=\"bi bi-check-lg\" viewBox=\"0 0 16 16\"><path d=\"M12.736 3.97a.733.733 0 0 1 1.047 0c.286.289.29.756.01 1.05L7.88 12.01a.733.733 0 0 1-1.065.02L3.217 8.384a.757.757 0 0 1 0-1.06.733.733 0 0 1 1.047 0l3.052 3.093 5.4-6.425z\"/></svg>"; 467 string MainsvgOutStock = "<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"25\" height=\"25\" fill=\"#CA0D0D\" class=\"bi bi-x-lg\" viewBox=\"0 0 16 16\"><path d=\"M4.646 4.646a.5.5 0 0 1 .708 0L8 7.293l2.646-2.647a.5.5 0 0 1 .708.708L8.707 8l2.647 2.646a.5.5 0 0 1-.708.708L8 8.707l-2.646 2.647a.5.5 0 0 1-.708-.708L7.293 8 4.646 5.354a.5.5 0 0 1 0-.708\"/></svg>"; 468 469 string MaininfoStock = "<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"16\" height=\"16\" fill=\"currentColor\" class=\"bi bi-info-circle-fill\" viewBox=\"0 0 16 16\"><path d=\"M8 16A8 8 0 1 0 8 0a8 8 0 0 0 0 16m.93-9.412-1 4.705c-.07.34.029.533.304.533.194 0 .487-.07.686-.246l-.088.416c-.287.346-.92.598-1.465.598-.703 0-1.002-.422-.808-1.319l.738-3.468c.064-.293.006-.399-.287-.47l-.451-.081.082-.381 2.29-.287zM8 5.5a1 1 0 1 1 0-2 1 1 0 0 1 0 2\" /></svg>"; 470 string MainisNew = MainVariant?.ProductFieldValues?.GetProductFieldValue("New")?.Value?.ToString().ToLower() ?? ""; 471 string MainisNewSvg = "<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"16\" height=\"16\" fill=\"#F2C400\" class=\"bi bi-star-fill\" viewBox=\"0 0 16 16\"><path d = \"M3.612 15.443c-.386.198-.824-.149-.746-.592l.83-4.73L.173 6.765c-.329-.314-.158-.888.283-.95l4.898-.696L7.538.792c.197-.39.73-.39.927 0l2.184 4.327 4.898.696c.441.062.612.636.282.95l-3.522 3.356.83 4.73c.078.443-.36.79-.746.592L8 13.187l-4.389 2.256z\" /></svg> "; 472 string MainstockState = ""; 473 string MainIsSale = MainVariant?.ProductFieldValues?.GetProductFieldValue("Sale")?.Value?.ToString().ToLower() ?? ""; 474 string MainIsSaleSvg = "<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"16\" height=\"16\" fill=\"#F03232\" class=\"bi bi-star-fill\" viewBox=\"0 0 16 16\"><path d = \"M3.612 15.443c-.386.198-.824-.149-.746-.592l.83-4.73L.173 6.765c-.329-.314-.158-.888.283-.95l4.898-.696L7.538.792c.197-.39.73-.39.927 0l2.184 4.327 4.898.696c.441.062.612.636.282.95l-3.522 3.356.83 4.73c.078.443-.36.79-.746.592L8 13.187l-4.389 2.256z\" /></svg> "; 475 string MainexpectedDeliveryDate = ""; 476 477 if (DateTime.Compare(MainVariant.ExpectedDelivery, new DateTime(1900, 1, 1)) != 0) //In DW, if the Date is not set, it is defaulted 01-01-1900 and not null.. 478 { 479 MainexpectedDeliveryDate = MainVariant.ExpectedDelivery.ToShortDateString(); 480 } 481 482 string MainexpectedDeliveryDateText = !String.IsNullOrWhiteSpace(MainexpectedDeliveryDate) ? Translate("Verwacht:") + "&nbsp;" + MainexpectedDeliveryDate : ""; 483 484 @if (!(bool?)MainVariant.ProductFieldValues.Where(o => o.ProductField.SystemName == "ProductToBeDiscontinued").SingleOrDefault()?.Value ?? false) 485 { 486 if (MainvariantStock > 0) 487 { 488 if (MainisNew == "true" || MainIsSale == "true") 489 { 490 if (MainIsSale == "true") 491 { 492 MainstockState += MainIsSaleSvg + "&nbsp; &nbsp;" + Translate("Sale!") + "<br/>"; 493 } 494 495 if (MainisNew == "true") 496 { 497 MainstockState += MainisNewSvg + "&nbsp; &nbsp;" + Translate("New!") + "<br/>"; 498 } 499 500 MainstockState += "&nbsp;" + Translate("Nu leverbaar"); 501 } 502 else 503 { 504 MainstockState = MainsvgInStock + "&nbsp; " + Translate("Op voorraad"); 505 506 } 507 } 508 else 509 { 510 MainstockState = MainsvgOutStock + "&nbsp;" + Translate("Geen voorraad") + "<br/>" + MainexpectedDeliveryDateText; 511 512 } 513 } 514 else 515 { 516 517 MainstockState = MainsvgOutStock + "&nbsp;" + Translate("Discontinued:") + "<br/>" + MainvariantStock + "&nbsp;" + @Translate("left in stock"); 518 519 } 520 /*End stock state*/ 521 522 523 @MainstockState 524 525 526 } 527 </div> 528 } 529 else 530 { 531 <div class="stock-state pt-2 mt-auto"> 532 @MainOutStock @Translate("Discontinued") 533 </div> 534 } 535 <div class="custom-price mt-auto"> 536 @{ 537 538 539 540 541 bool isErpConnectionDown = !Dynamicweb.Core.Converter.ToBoolean(Dynamicweb.Context.Current.Items["IsWebServiceConnectionAvailable"]); 542 bool hidePrice = anonymousUsersLimitations.Contains("price") && anonymousUser || Pageview.AreaSettings.GetBoolean("ErpDownHidePrices") && isErpConnectionDown; 543 544 bool productIsDiscontinued = product is object && product.Discontinued; 545 bool doNotShowPriceIfProductIsDiscontinued = Model.Item.GetBoolean("DoNotShowPriceIfProductIsDiscontinued"); 546 var isDiscontinued = productIsDiscontinued && doNotShowPriceIfProductIsDiscontinued; 547 } 548 549 @if (product is object && !hidePrice && !isDiscontinued) 550 { 551 string unitId = !string.IsNullOrEmpty(Dynamicweb.Context.Current.Request.Form.Get("UnitId")) ? Dynamicweb.Context.Current.Request.Form.Get("UnitId") : string.Empty; 552 553 string priceFontSize = Model.Item.GetRawValueString("PriceSize", "fs-4"); 554 string horizontalAlign = Model.Item.GetRawValueString("HorizontalAlignment", ""); 555 string layout = Model.Item.GetRawValueString("Layout", "horizontal"); 556 string textAlign = horizontalAlign == "center" ? "text-center" : string.Empty; 557 textAlign = horizontalAlign == "end" ? "text-end" : textAlign; 558 559 horizontalAlign = horizontalAlign == "center" && layout == "horizontal" ? "justify-content-center" : horizontalAlign; 560 horizontalAlign = horizontalAlign == "end" && layout == "horizontal" ? "justify-content-end" : horizontalAlign; 561 horizontalAlign = horizontalAlign == "center" && layout == "vertical" ? "align-items-center" : horizontalAlign; 562 horizontalAlign = horizontalAlign == "end" && layout == "vertical" ? "align-items-end" : horizontalAlign; 563 564 string flexDirection = layout == "horizontal" ? string.Empty : "flex-column"; 565 string flexGap = layout == "horizontal" ? "gap-3" : string.Empty; 566 string order = layout == "horizontal" ? string.Empty : "order-2"; 567 568 569 string contentPadding = Model.Item.GetRawValueString("ContentPadding", ""); 570 contentPadding = contentPadding == "none" ? "p-0" : contentPadding; 571 contentPadding = contentPadding == "small" ? "p-1 px-md-2 py-md-1" : contentPadding; 572 contentPadding = contentPadding == "large" ? "p-2 px-md-3 py-md-2" : contentPadding; 573 string liveInfoClass = ""; 574 575 576 577 578 579 580 if (isLazyLoadingForProductInfoEnabled) 581 { 582 if (Dynamicweb.Context.Current.Items.Contains("ProductInfoFeed")) 583 { 584 productInfoFeed = Dynamicweb.Context.Current.Items["ProductInfoFeed"]?.ToString(); 585 if (!string.IsNullOrEmpty(productInfoFeed)) 586 { 587 productInfoFeed = $"data-product-info-feed=\"{productInfoFeed}\""; 588 } 589 } 590 liveInfoClass = "js-live-info"; 591 } 592 593 <div class="@textAlign @liveInfoClass item_@Model.Item.SystemName.ToLower()" data-product-id="@product.Id" data-variant-id="@product.VariantId" @productInfoFeed> 594 @if (showInformativePrice && product.PriceInformative.Price != 0) 595 { 596 <div class="opacity-50"> 597 <span>@Translate("RRP") </span> 598 <span class="text-decoration-line-through text-price">@product.PriceInformative.PriceFormatted</span> 599 </div> 600 } 601 <div class="@priceFontSize m-0 d-flex flex-wrap @flexDirection @flexGap @horizontalAlign" style="row-gap: 0 !important" itemprop="offers" itemscope itemtype="https://schema.org/Offer"> 602 <span itemprop="priceCurrency" content="@product.Price.CurrencyCode" class="d-none"></span> 603 604 605 @if (showPricesWithVat == "false" && !neverShowVat) 606 { 607 if (isLazyLoadingForProductInfoEnabled && !Pageview.IsVisualEditorMode) 608 { 609 <span itemprop="price" content="" class="d-none"></span> 610 <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> 611 } 612 else 613 { 614 string beforePrice = !string.IsNullOrEmpty(unitId) ? product.GetPrice(unitId).PriceBeforeDiscount.PriceWithoutVatFormatted : product.PriceBeforeDiscount.PriceWithoutVatFormatted; 615 616 <span itemprop="price" content="@product.Price.PriceWithoutVat.ToString("0.00", System.Globalization.CultureInfo.InvariantCulture)" class="d-none"></span> 617 if (product.Price.Price != product.PriceBeforeDiscount.Price) 618 { 619 <span class="text-decoration-line-through opacity-75 @order">@beforePrice</span> 620 } 621 } 622 } 623 else 624 { 625 if (isLazyLoadingForProductInfoEnabled && !Pageview.IsVisualEditorMode) 626 { 627 <span itemprop="price" content="" class="d-none"></span> 628 <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> 629 } 630 else 631 { 632 string beforePrice = !string.IsNullOrEmpty(unitId) ? product.GetPrice(unitId).PriceBeforeDiscount.PriceFormatted : product.PriceBeforeDiscount.PriceFormatted; 633 634 <span itemprop="price" content="@product.Price.Price.ToString("0.00", System.Globalization.CultureInfo.InvariantCulture)" class="d-none"></span> 635 636 if (product.Price.Price != product.PriceBeforeDiscount.Price) 637 { 638 <span class="text-decoration-line-through opacity-75 @order"> 639 <span class="text-price">@beforePrice</span> 640 </span> 641 } 642 } 643 } 644 645 @if (showPricesWithVat == "false" && !neverShowVat) 646 { 647 if (isLazyLoadingForProductInfoEnabled && !Pageview.IsVisualEditorMode) 648 { 649 <span class="text-price js-text-price"> 650 <span class="spinner-border" role="status"></span> 651 </span> 652 } 653 else 654 { 655 string price = !string.IsNullOrEmpty(unitId) ? product.GetPrice(unitId).Price.PriceWithoutVatFormatted : product.Price.PriceWithoutVatFormatted; 656 657 if (product?.VariantInfo?.VariantInfo != null) 658 { 659 priceMin = product?.VariantInfo?.PriceMin?.PriceWithoutVatFormatted != null ? product.VariantInfo.PriceMin.PriceWithoutVatFormatted : ""; 660 priceMax = product?.VariantInfo?.PriceMax?.PriceWithoutVatFormatted != null ? product.VariantInfo.PriceMax.PriceWithoutVatFormatted : ""; 661 } 662 if (priceMin != priceMax) 663 { 664 price = priceMin + " - " + priceMax; 665 } 666 <span class="@theme @contentPadding"> 667 <span class="text-price">@price</span> 668 </span> 669 } 670 } 671 else 672 { 673 if (isLazyLoadingForProductInfoEnabled && !Pageview.IsVisualEditorMode) 674 { 675 <span class="text-price js-text-price"> 676 <span class="spinner-border" role="status"></span> 677 </span> 678 } 679 else 680 { 681 string price = !string.IsNullOrEmpty(unitId) ? product.GetPrice(unitId).Price.PriceFormatted : product.Price.PriceFormatted; 682 683 if (product?.VariantInfo?.VariantInfo != null) 684 { 685 priceMin = product?.VariantInfo?.PriceMin?.PriceFormatted != null ? product.VariantInfo.PriceMin.PriceFormatted : ""; 686 priceMax = product?.VariantInfo?.PriceMax?.PriceFormatted != null ? product.VariantInfo.PriceMax.PriceFormatted : ""; 687 } 688 if (priceMin != priceMax) 689 { 690 price = priceMin + " - " + priceMax; 691 } 692 <span class="@theme @contentPadding"> 693 <span class="text-price">@price</span> 694 </span> 695 } 696 } 697 698 @* Stock state for Schema.org, start *@ 699 @{ 700 Uri url = Dynamicweb.Context.Current.Request.Url; 701 } 702 703 <link itemprop="url" href="@url"> 704 705 @{ 706 bool IsNeverOutOfStock = product.NeverOutOfstock; 707 } 708 709 @if (IsNeverOutOfStock) 710 { 711 <span itemprop="availability" class="d-none">@Translate("Available in stock")</span> 712 } 713 else 714 { 715 if (product.StockLevel > 0) 716 { 717 <span itemprop="availability" class="d-none">InStock</span> 718 } 719 else 720 { 721 <span itemprop="availability" class="d-none">OutOfStock</span> 722 } 723 } 724 @* Stock state for Schema.org, stop *@ 725 726 </div> 727 728 @if (showPricesWithVat == "false" && !neverShowVat) 729 { 730 if (isLazyLoadingForProductInfoEnabled && !Pageview.IsVisualEditorMode) 731 { 732 <small class="opacity-85 fst-normal js-text-price-with-vat d-none" data-suffix="@Translate("Incl. VAT")"></small> 733 } 734 else 735 { 736 string price = !string.IsNullOrEmpty(unitId) ? product.GetPrice(unitId).Price.PriceWithVatFormatted : product.Price.PriceWithVatFormatted; 737 738 if (product?.VariantInfo?.VariantInfo != null) 739 { 740 priceMin = product?.VariantInfo?.PriceMin?.PriceWithVatFormatted != null ? product.VariantInfo.PriceMin.PriceWithVatFormatted : ""; 741 priceMax = product?.VariantInfo?.PriceMax?.PriceWithVatFormatted != null ? product.VariantInfo.PriceMax.PriceWithVatFormatted : ""; 742 } 743 if (priceMin != priceMax) 744 { 745 price = priceMin + " - " + priceMax; 746 } 747 <!-- <small class="opacity-85 fst-normal">@price @Translate("Incl. VAT")</small> --> 748 } 749 } 750 </div> 751 } 752 else if (Pageview.IsVisualEditorMode) 753 { 754 <div class="alert alert-dark m-0" role="alert"> 755 <span>@Translate("No products available")</span> 756 </div> 757 } 758 759 </div> 760 } 761 } 762
Tischlampe 1L Arch wood L
Error executing template "Designs/Swift/Paragraph/CustomProductSlider.cshtml"
System.NullReferenceException: Object reference not set to an instance of an object.
   at CompiledRazorTemplates.Dynamic.RazorEngine_3562354021b44d5c892fe73dc2806e4f.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 Dynamicweb.Ecommerce.ProductCatalog 3 @using Dynamicweb.Ecommerce.CustomerExperienceCenter.Favorites 4 @using Dynamicweb.Files 5 @using System.IO 6 @using System.Net 7 @using Dynamicweb.Security.UserManagement 8 9 10 @{ 11 ProductViewModel product = null; 12 if (Dynamicweb.Context.Current.Items.Contains("ProductDetails")) 13 { 14 product = (ProductViewModel)Dynamicweb.Context.Current.Items["ProductDetails"]; 15 } 16 else if (Pageview.Page.Item["DummyProduct"] != null && Pageview.IsVisualEditorMode) 17 { 18 var pageViewModel = Dynamicweb.Frontend.ContentViewModelFactory.CreatePageInfoViewModel(Pageview.Page); 19 ProductListViewModel productList = pageViewModel.Item.GetValue("DummyProduct") != null ? pageViewModel.Item.GetValue("DummyProduct") as ProductListViewModel : new ProductListViewModel(); 20 21 if (productList?.Products is object) 22 { 23 product = productList.Products[0]; 24 } 25 } 26 } 27 28 @{ 29 var currentUser = Pageview?.User; 30 var customerNumber = !string.IsNullOrEmpty(currentUser?.CustomerNumber) 31 ? currentUser.CustomerNumber 32 : ""; 33 } 34 @if (product is object) 35 { 36 string imagePath = product?.DefaultImage?.Value ?? ""; 37 string imagePathUrlEncoded = Dynamicweb.Context.Current.Server.UrlEncode(imagePath); 38 39 string ratio = Model.Item.GetRawValueString("ImageAspectRatio", ""); 40 ratio = ratio != "0" ? ratio : ""; 41 string ratioCssClass = ratio != "" ? " ratio" : ""; 42 string ratioVariable = ratio != "" ? "--bs-aspect-ratio: " + ratio + ";" : ""; 43 44 string width = Model.Item.GetRawValueString("Width", "auto"); 45 int smallImageSize = 640; 46 int largeImageSize = width == "auto" ? 1280 : Convert.ToInt32(width); 47 48 string ImageObjectFit = Model.Item.GetRawValueString("ImageObjectFit", "contain"); 49 50 string imagePathXs = "/Admin/Public/GetImage.ashx?width=" + smallImageSize + "&image=" + imagePathUrlEncoded + "&format=webp"; 51 string imagePathS = "/Admin/Public/GetImage.ashx?width=" + largeImageSize + "&image=" + imagePathUrlEncoded + "&format=webp"; 52 string imagePathFallBack = "/Admin/Public/GetImage.ashx?width=" + largeImageSize + "&image=" + imagePathUrlEncoded + "&format=webp"; 53 54 var badgeParms = new Dictionary<string, object>(); 55 badgeParms.Add("size", "h7"); 56 badgeParms.Add("saleBadgeType", Model.Item.GetRawValue("SaleBadgeType")); 57 badgeParms.Add("saleBadgeCssClassName", Model.Item.GetRawValue("SaleBadgeDesign")); 58 badgeParms.Add("newBadgeCssClassName", Model.Item.GetRawValue("NewBadgeDesign")); 59 badgeParms.Add("newPublicationDays", Model.Item.GetInt32("NewPublicationDays")); 60 badgeParms.Add("campaignBadgesValues", Model.Item.GetList("CampaignBadges")?.GetRawValue().OfType<string>().ToList()); 61 62 string badgeSize = Model.Item.GetRawValueString("BadgeSize", "fs-2"); 63 bool saleBadgeEnabled = !string.IsNullOrWhiteSpace(Model.Item.GetRawValueString("SaleBadgeDesign")) && Model.Item.GetRawValueString("SaleBadgeDesign") != "none" ? true : false; 64 bool newBadgeEnabled = !string.IsNullOrWhiteSpace(Model.Item.GetRawValueString("NewBadgeDesign")) && Model.Item.GetRawValueString("NewBadgeDesign") != "none" ? true : false; 65 66 /*Custom badge*/ 67 var productService = new Dynamicweb.Ecommerce.Products.ProductService(); 68 var currency = Dynamicweb.Ecommerce.Common.Context.Currency.Code; 69 var formatProvider = new System.Globalization.NumberFormatInfo(); 70 formatProvider.NumberDecimalSeparator = "."; 71 formatProvider.NumberGroupSeparator = ","; 72 var MainVariant = productService.GetProductById(product.Id, product.VariantId, false); 73 var fieldValueBlocked = MainVariant?.ProductFieldValues?.GetProductFieldValue("BlockedCustomerList")?.Value; 74 75 76 string isNewProduct = MainVariant?.ProductFieldValues?.GetProductFieldValue("New")?.Value?.ToString().ToLower() ?? ""; 77 string MainisSale = MainVariant?.ProductFieldValues?.GetProductFieldValue("Sale")?.Value?.ToString().ToLower() ?? ""; 78 bool showNewBadge = isNewProduct == "true" ? true : false; 79 bool showSaleBadge = MainisSale == "true" ? true : false; 80 string showNewSaleBadge = "d-none"; 81 if (showSaleBadge) 82 { 83 badgeParms.Add("isSale", "true"); 84 85 } 86 else 87 { 88 badgeParms.Add("isSale", "false"); 89 } 90 if (showNewBadge) 91 { 92 badgeParms.Add("isNew", "true"); 93 } 94 else 95 { 96 badgeParms.Add("isNew", "false"); 97 } 98 /*End Custom badge*/ 99 if (showSaleBadge || showNewBadge) 100 { 101 showNewSaleBadge = ""; 102 } 103 DateTime createdDate = product.Created.Value; 104 bool showBadges = saleBadgeEnabled && product.Discount.Price != 0 ? true : false; 105 106 bool showFavoritesSelector = !string.IsNullOrEmpty(Model.Item.GetString("ShowAddToFavorites")) ? Model.Item.GetBoolean("ShowAddToFavorites") : false; 107 string anonymousUsersLimitations = Pageview.AreaSettings.GetRawValueString("AnonymousUsers", ""); 108 bool anonymousUser = Pageview.User == null; 109 110 var favoriteParameters = new Dictionary<string, object>(); 111 if (!anonymousUser && showFavoritesSelector) 112 { 113 int defaultFavoriteListId = 0; 114 115 IEnumerable<FavoriteList> favoreiteLists = Pageview.User.GetFavoriteLists(); 116 if (favoreiteLists.Count() == 1) 117 { 118 foreach (FavoriteList list in favoreiteLists) 119 { 120 defaultFavoriteListId = list.ListId; 121 } 122 } 123 124 favoriteParameters.Add("ListId", defaultFavoriteListId); 125 } 126 127 MediaViewModel alternativeImage = new MediaViewModel(); 128 if (Model.Item.GetBoolean("ShowAlternativeImageOnHover")) 129 { 130 var selectedImageCategories = Model.Item.GetList("GetAlternativeImageFrom")?.GetRawValue().OfType<string>().ToList(); 131 List<MediaViewModel> allAssetsImages = product.AssetCategories.Where(x => selectedImageCategories.Contains(x.SystemName)).SelectMany(x => x.Assets).ToList(); 132 allAssetsImages.RemoveAll(x => x.Value == product.DefaultImage.Value); 133 alternativeImage = allAssetsImages.FirstOrDefault(); 134 } 135 136 string altImagePathXs = string.Empty; 137 string altImagePathS = string.Empty; 138 139 if (!string.IsNullOrEmpty(alternativeImage?.Value)) 140 { 141 altImagePathXs = "/Admin/Public/GetImage.ashx?width=" + smallImageSize + "&image=" + Dynamicweb.Context.Current.Server.UrlEncode(alternativeImage.Value) + "&format=webp"; 142 altImagePathS = "/Admin/Public/GetImage.ashx?width=" + largeImageSize + "&image=" + Dynamicweb.Context.Current.Server.UrlEncode(alternativeImage.Value) + "&format=webp"; 143 } 144 145 @* Theme settings *@ 146 string theme = !string.IsNullOrWhiteSpace(Model.Item.GetRawValueString("Theme")) ? " theme " + Model.Item.GetRawValueString("Theme").Replace(" ", "").Trim().ToLower() : ""; 147 string themeBorder = !string.IsNullOrWhiteSpace(theme) ? "border: 1px solid rgba(0,0,0,0)" : ""; 148 string themePadding = !string.IsNullOrWhiteSpace(theme) ? "p-2 p-lg-3" : ""; 149 150 string imageId = "ProductImage_" + product.Id; 151 152 153 154 string fullWidth = width == "auto" ? "w-100" : ""; 155 string customWidth = width != "auto" ? "style=\"width: " + width + "px\"" : "style=\"min-width: 60px\""; 156 157 string altImageZindex = Model.Item.GetBoolean("ShowAlternativeImageOnHover") && !string.IsNullOrEmpty(alternativeImage?.Value) ? " z-index: 1" : string.Empty; 158 string groupid = !string.IsNullOrEmpty(Dynamicweb.Context.Current.Request.QueryString.Get("GroupID")) ? Dynamicweb.Context.Current.Request.QueryString.Get("GroupID"):"" ; 159 string link = product.GetProductLink(GetPageIdByNavigationTag("Shop"), false); 160 var productVariantGroups = product.VariantGroups(); 161 string MainOutStock = "<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"25\" height=\"25\" fill=\"#CA0D0D\" class=\"bi bi-x-lg\" viewBox=\"0 0 16 16\"><path d=\"M4.646 4.646a.5.5 0 0 1 .708 0L8 7.293l2.646-2.647a.5.5 0 0 1 .708.708L8.707 8l2.647 2.646a.5.5 0 0 1-.708.708L8 8.707l-2.646 2.647a.5.5 0 0 1-.708-.708L7.293 8 4.646 5.354a.5.5 0 0 1 0-.708\"/></svg>"; 162 163 @if (!string.IsNullOrEmpty(imagePath)) 164 { 165 <div class="@fullWidth @theme position-relative item_@Model.Item.SystemName.ToLower() main-image-container" @customWidth> 166 <div class="" style="@(ratioVariable)@(altImageZindex)"> 167 <div class="d-flex justify-content-center align-items-center"> 168 <a class="main-link-link" href="@link"> 169 @if (imagePath.StartsWith("/Files/", StringComparison.OrdinalIgnoreCase)) 170 { 171 <img id="@imageId" 172 srcset=" 173 @imagePathXs @(smallImageSize)w, 174 @imagePathS @(largeImageSize)w" 175 sizes="(max-width: 992px) 50vw, 25vw" 176 src="@imagePathFallBack" 177 loading="lazy" 178 decoding="async" 179 class="h-100 w-100 @themePadding main-image" 180 style="object-fit: @ImageObjectFit; @themeBorder " 181 alt="@product.Name" 182 itemprop="image"> 183 } 184 else 185 { 186 <img src="@product.DefaultImage.Value" 187 loading="lazy" 188 class="h-100 w-100 @themePadding main-image" 189 style="object-fit: contain; @themeBorder" 190 alt="@product.Name" 191 itemprop="image"> 192 } 193 </a> 194 </div> 195 </div> 196 197 <div class="position-absolute top-0 left-0 p-2 pb-0 custom-badge-product-list @showNewSaleBadge"> 198 @{ 199 @RenderPartial("Components/Custom_EcommerceBadge.cshtml", product, badgeParms) 200 } 201 </div> 202 203 204 </div> 205 } 206 207 <div class="product-info h-100"> 208 <div class="fs-7 pt-1 opacity-85 start item_@Model.Item.SystemName.ToLower() product-number" itemprop="sku">@product.Id / @product.VariantId - @product.VariantName</div> 209 <div class="py-2" data-col-size="12"> 210 <h2 class="h6 start m-0 item_swift_productheader product-name" itemprop="name"><b>@product.Name</b></h2> 211 </div> 212 </div> 213 var sliderId = $"thumb-scroll-{product.Id}"; 214 if (productVariantGroups.Any() && product?.VariantInfo?.VariantInfo != null) 215 216 { 217 @using Dynamicweb.Ecommerce.Prices 218 @{ 219 string[] variantId = product.VariantId.Split('.'); 220 string showPricesWithVat = Pageview.Area.EcomPricesWithVat.ToLower(); 221 bool neverShowVat = string.IsNullOrEmpty(showPricesWithVat); 222 bool showInformativePrice = Model.Item.GetBoolean("ShowInformativePrice"); 223 string productInfoFeed = ""; 224 bool isLazyLoadingForProductInfoEnabled = Dynamicweb.Core.Converter.ToBoolean(Dynamicweb.Context.Current.Items["IsLazyLoadingForProductInfoEnabled"]); 225 if (isLazyLoadingForProductInfoEnabled) 226 { 227 if (Dynamicweb.Context.Current.Items.Contains("ProductInfoFeed")) 228 { 229 productInfoFeed = Dynamicweb.Context.Current.Items["ProductInfoFeed"]?.ToString(); 230 if (!string.IsNullOrEmpty(productInfoFeed)) 231 { 232 productInfoFeed =productInfoFeed; 233 } 234 } 235 236 } 237 string priceMin = ""; 238 string priceMax = ""; 239 int groupNumber = 1; 240 241 242 243 244 string baseUrl = $"Default.aspx?ID={GetPageIdByNavigationTag("Shop")}&GroupID={product.PrimaryOrDefaultGroup.Id}&ProductID={product.Id}"; 245 if (!string.IsNullOrEmpty(baseUrl)) 246 { 247 baseUrl = $"/{baseUrl.TrimStart('/')}"; 248 } 249 string variantUrl = string.Empty; 250 251 252 Dictionary<string, string> 253 variantImages = new Dictionary<string, string> 254 (); 255 <div class="last-row mt-auto"> 256 257 @foreach (var variantGroup in productVariantGroups) 258 { 259 <div class="thumbnail-wrapper"> 260 <button class="thumb-nav prev" onclick="scrollThumbs('@sliderId', -1)"> 261 <svg width="20px" height="20px" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" fill="#1D98A5"> 262 263 <g stroke="none" stroke-width="1" fill="none" fill-rule="evenodd"> 264 <g transform="translate(-336.000000, 0.000000)"> 265 <g id="left_line" transform="translate(336.000000, 0.000000)"> 266 <path d="M24,0 L24,24 L0,24 L0,0 L24,0 Z M12.5934901,23.257841 L12.5819402,23.2595131 L12.5108777,23.2950439 L12.4918791,23.2987469 L12.4918791,23.2987469 L12.4767152,23.2950439 L12.4056548,23.2595131 C12.3958229,23.2563662 12.3870493,23.2590235 12.3821421,23.2649074 L12.3780323,23.275831 L12.360941,23.7031097 L12.3658947,23.7234994 L12.3769048,23.7357139 L12.4804777,23.8096931 L12.4953491,23.8136134 L12.4953491,23.8136134 L12.5071152,23.8096931 L12.6106902,23.7357139 L12.6232938,23.7196733 L12.6232938,23.7196733 L12.6266527,23.7031097 L12.609561,23.275831 C12.6075724,23.2657013 12.6010112,23.2592993 12.5934901,23.257841 L12.5934901,23.257841 Z M12.8583906,23.1452862 L12.8445485,23.1473072 L12.6598443,23.2396597 L12.6498822,23.2499052 L12.6498822,23.2499052 L12.6471943,23.2611114 L12.6650943,23.6906389 L12.6699349,23.7034178 L12.6699349,23.7034178 L12.678386,23.7104931 L12.8793402,23.8032389 C12.8914285,23.8068999 12.9022333,23.8029875 12.9078286,23.7952264 L12.9118235,23.7811639 L12.8776777,23.1665331 C12.8752882,23.1545897 12.8674102,23.1470016 12.8583906,23.1452862 L12.8583906,23.1452862 Z M12.1430473,23.1473072 C12.1332178,23.1423925 12.1221763,23.1452606 12.1156365,23.1525954 L12.1099173,23.1665331 L12.0757714,23.7811639 C12.0751323,23.7926639 12.0828099,23.8018602 12.0926481,23.8045676 L12.108256,23.8032389 L12.3092106,23.7104931 L12.3186497,23.7024347 L12.3186497,23.7024347 L12.3225043,23.6906389 L12.340401,23.2611114 L12.337245,23.2485176 L12.337245,23.2485176 L12.3277531,23.2396597 L12.1430473,23.1473072 Z" id="MingCute" fill-rule="nonzero"> </path> 267 <path d="M8.29292,12.7071 C7.9024,12.3166 7.9024,11.6834 8.29292,11.2929 L13.9498,5.63604 C14.3403,5.24551 14.9735,5.24551 15.364,5.63604 C15.7545,6.02656 15.7545,6.65973 15.364,7.05025 L10.4142,12 L15.364,16.9497 C15.7545,17.3403 15.7545,17.9734 15.364,18.364 C14.9735,18.7545 14.3403,18.7545 13.9498,18.364 L8.29292,12.7071 Z" id="路径" fill="#1D98A5"> </path> 268 </g> 269 </g> 270 </g> 271 </svg> 272 273 </button> 274 <div class="thumbnail-scroll" id="@sliderId"> 275 @{ 276 VariantGroupViewModel group = variantGroup; 277 foreach (var option in group.Options.OrderBy(o => o.Id)) 278 { 279 var productVariant = productService.GetProductById(product.Id, option.Id, false); 280 281 var productSelection = new PriceProductSelection(productVariant, null, 0); 282 283 var currencyCode = string.IsNullOrWhiteSpace(Pageview.User.Currency) ? Pageview.Area.EcomCurrencyId : Pageview.User.Currency; 284 var countryCode = string.IsNullOrWhiteSpace(Pageview.User.CountryCode) ? Pageview.Area.EcomCountryCode : Pageview.User.CountryCode; 285 286 var userCurrency = Dynamicweb.Ecommerce.Services.Currencies.GetCurrency(currencyCode); 287 var userCountry = Dynamicweb.Ecommerce.Services.Countries.GetCountry(countryCode); 288 289 var priceContext = new PriceContext(userCurrency, userCountry, null, Pageview.User, false, null); 290 var productPrice = Dynamicweb.Ecommerce.Services.Prices.FindPrices(priceContext, productSelection, false); 291 292 //throw new Exception(System.Text.Json.JsonSerializer.Serialize(productPrice)); 293 294 var fieldValue = productVariant?.ProductFieldValues?.GetProductFieldValue("BlockedCustomerList")?.Value; 295 296 if ((fieldValue != null && !fieldValue.ToString().Contains(customerNumber)) || String.IsNullOrWhiteSpace(customerNumber)) 297 { 298 299 300 string active = variantId != null && variantId.Contains(option.Id) ? "active" : string.Empty; 301 string buttonId = $"{product.Id}_{option.Id}_{Pageview.CurrentParagraph.ID}"; 302 string contrastColor = string.Empty; 303 304 string searchKey = $"{product.Id}_{option.Id}_"; 305 /*Images*/ 306 var imagePathVariant = option.Image?.Value ?? ""; 307 308 309 var folderPath = Path.GetDirectoryName(imagePathVariant); 310 311 string physicalFolderPath = Dynamicweb.Context.Current.Server.MapPath(folderPath); 312 313 string lastImage = null; 314 315 if (Directory.Exists(physicalFolderPath)) 316 { 317 318 var fileWith15 = Directory.GetFiles(physicalFolderPath) 319 .FirstOrDefault(f => Path.GetFileName(f).Contains($"{product.Id}_{option.Id}_9")); 320 321 if (fileWith15 != null) 322 { 323 lastImage = fileWith15; 324 } 325 else 326 { 327 var files = Directory.GetFiles(physicalFolderPath) 328 .Where(f => Path.GetFileName(f).StartsWith($"{product.Id}_{option.Id}_")) 329 .OrderByDescending(f => 330 { 331 var filename = Path.GetFileNameWithoutExtension(f); 332 var match = System.Text.RegularExpressions.Regex.Match(filename, @"_(\d+)$"); 333 if (match.Success && int.TryParse(match.Groups[1].Value, out int index)) 334 { 335 return index; 336 } 337 return 0; 338 }) 339 .ToList(); 340 341 if (files.Any()) 342 { 343 lastImage = files.First(); 344 } 345 } 346 } 347 348 var lastImageUrl = lastImage != null ? lastImage : "/Files/Images/zijlstra/Afbeeldingen_overig/Coming_Soon.jpg"; 349 int index = lastImageUrl.IndexOf("Files"); 350 string relativePath = index >= 0 ? lastImageUrl.Substring(index).Replace("\\", "/") : lastImageUrl.Replace("\\", "/"); 351 lastImageUrl = "/" + relativePath; 352 lastImageUrl = Dynamicweb.Context.Current.Server.UrlEncode(lastImageUrl); 353 var variantImg = option.Image is object ? Dynamicweb.Context.Current.Server.UrlEncode(option.Image.Value) : null; 354 var variantLink = "/Default.aspx?ID=" + GetPageIdByNavigationTag("Shop") + "&GroupID=" + product.PrimaryOrDefaultGroup.Id + "&ProductID=" + product.Id + "&VariantID=" + option.Id; 355 356 string variantImage = string.Empty; 357 variantImages.TryGetValue(option.Id, out variantImage); 358 /*End Images*/ 359 360 /*stock state*/ 361 double variantStock = productVariant.Stock; 362 string svgInStock = "<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"16\" height=\"16\" fill=\"#44B11A\" class=\"bi bi-check-lg\" viewBox=\"0 0 16 16\"><path d=\"M12.736 3.97a.733.733 0 0 1 1.047 0c.286.289.29.756.01 1.05L7.88 12.01a.733.733 0 0 1-1.065.02L3.217 8.384a.757.757 0 0 1 0-1.06.733.733 0 0 1 1.047 0l3.052 3.093 5.4-6.425z\"/></svg>"; 363 string svgOutStock = "<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"25\" height=\"25\" fill=\"#CA0D0D\" class=\"bi bi-x-lg\" viewBox=\"0 0 16 16\"><path d=\"M4.646 4.646a.5.5 0 0 1 .708 0L8 7.293l2.646-2.647a.5.5 0 0 1 .708.708L8.707 8l2.647 2.646a.5.5 0 0 1-.708.708L8 8.707l-2.646 2.647a.5.5 0 0 1-.708-.708L7.293 8 4.646 5.354a.5.5 0 0 1 0-.708\"/></svg>"; 364 365 string infoStock = "<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"16\" height=\"16\" fill=\"currentColor\" class=\"bi bi-info-circle-fill\" viewBox=\"0 0 16 16\"><path d=\"M8 16A8 8 0 1 0 8 0a8 8 0 0 0 0 16m.93-9.412-1 4.705c-.07.34.029.533.304.533.194 0 .487-.07.686-.246l-.088.416c-.287.346-.92.598-1.465.598-.703 0-1.002-.422-.808-1.319l.738-3.468c.064-.293.006-.399-.287-.47l-.451-.081.082-.381 2.29-.287zM8 5.5a1 1 0 1 1 0-2 1 1 0 0 1 0 2\" /></svg>"; 366 string isNew = productVariant?.ProductFieldValues?.GetProductFieldValue("New")?.Value?.ToString().ToLower() ?? ""; 367 string isNewSvg = "<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"16\" height=\"16\" fill=\"#F2C400\" class=\"bi bi-star-fill\" viewBox=\"0 0 16 16\"><path d = \"M3.612 15.443c-.386.198-.824-.149-.746-.592l.83-4.73L.173 6.765c-.329-.314-.158-.888.283-.95l4.898-.696L7.538.792c.197-.39.73-.39.927 0l2.184 4.327 4.898.696c.441.062.612.636.282.95l-3.522 3.356.83 4.73c.078.443-.36.79-.746.592L8 13.187l-4.389 2.256z\" /></svg> "; 368 string stockState = ""; 369 370 string isSale = productVariant?.ProductFieldValues?.GetProductFieldValue("Sale")?.Value?.ToString().ToLower() ?? ""; 371 string isSaleSvg = "<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"16\" height=\"16\" fill=\"#F03232\" class=\"bi bi-star-fill\" viewBox=\"0 0 16 16\"><path d = \"M3.612 15.443c-.386.198-.824-.149-.746-.592l.83-4.73L.173 6.765c-.329-.314-.158-.888.283-.95l4.898-.696L7.538.792c.197-.39.73-.39.927 0l2.184 4.327 4.898.696c.441.062.612.636.282.95l-3.522 3.356.83 4.73c.078.443-.36.79-.746.592L8 13.187l-4.389 2.256z\" /></svg> "; 372 373 string expectedDeliveryDate = ""; 374 375 if (DateTime.Compare(productVariant.ExpectedDelivery, new DateTime(1900, 1, 1)) != 0) //In DW, if the Date is not set, it is defaulted 01-01-1900 and not null.. 376 { 377 expectedDeliveryDate = productVariant.ExpectedDelivery.ToShortDateString(); 378 } 379 380 string expectedDeliveryDateText = !String.IsNullOrWhiteSpace(expectedDeliveryDate) ? Translate("Verwacht:") + "&nbsp;" + expectedDeliveryDate : ""; 381 382 @if (!(bool?)productVariant.ProductFieldValues.Where(o => o.ProductField.SystemName == "ProductToBeDiscontinued").SingleOrDefault()?.Value ?? false) 383 { 384 if (variantStock > 0) 385 { 386 if (isNew == "true" || isSale == "true") 387 { 388 if (isSale == "true") 389 { 390 stockState += isSaleSvg + "&nbsp; &nbsp;" + Translate("Sale!") + "<br/>"; 391 } 392 393 if (isNew == "true") 394 { 395 stockState += isNewSvg + "&nbsp; &nbsp;" + Translate("New!") + "<br/>"; 396 } 397 398 stockState += "&nbsp;" + Translate("Nu leverbaar"); 399 } 400 else 401 { 402 stockState = svgInStock + "&nbsp; " + Translate("Op voorraad"); 403 404 } 405 } 406 else 407 { 408 stockState = svgOutStock + "&nbsp;" + Translate("Geen voorraad") + "<br/>" + expectedDeliveryDateText; 409 410 } 411 } 412 else 413 { 414 415 stockState = svgOutStock + "&nbsp;" + Translate("Discontinued:") + "<br/>" + variantStock + "&nbsp;" + @Translate("left in stock"); 416 417 } 418 /*End stock state*/ 419 /*Price variants*/ 420 double price = productVariant.DefaultPrice; 421 double cost = productVariant.Cost; 422 423 string priceFormated = Dynamicweb.Ecommerce.Services.Currencies.Format(Dynamicweb.Ecommerce.Services.Currencies.GetCurrency(currency), Convert.ToDouble(productPrice.ToList()[0].Amount, formatProvider)); 424 //string priceFormated = Dynamicweb.Ecommerce.Services.Currencies.Format(Dynamicweb.Ecommerce.Services.Currencies.GetCurrency(currency), Convert.ToDouble(price, formatProvider)); 425 426 427 428 /*End Price variants*/ 429 430 <img class="theme thumbnail" data-stockstate="@WebUtility.HtmlEncode(stockState)" src="/Admin/Public/GetImage.ashx?image=@(lastImageUrl)&width=64&format=webp" onclick="selectVariant('@(product.Id)','/Admin/Public/GetImage.ashx?image=@(variantImg)&format=webp','@variantLink','@product.Id','@option.Id','@option.Name',this.dataset.stockstate,'@isNew','@isSale','@priceFormated','@cost')" /> 431 432 433 } 434 } 435 436 } 437 </div> 438 <button class="thumb-nav next" onclick="scrollThumbs('@sliderId', 1)"> 439 <svg width="20px" height="20px" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" fill="#1D98A5"> 440 441 <g stroke="none" stroke-width="1" fill="none" fill-rule="evenodd"> 442 <g transform="translate(-384.000000, 0.000000)"> 443 <g id="right_line" transform="translate(384.000000, 0.000000)"> 444 <path d="M24,0 L24,24 L0,24 L0,0 L24,0 Z M12.5934901,23.257841 L12.5819402,23.2595131 L12.5108777,23.2950439 L12.4918791,23.2987469 L12.4918791,23.2987469 L12.4767152,23.2950439 L12.4056548,23.2595131 C12.3958229,23.2563662 12.3870493,23.2590235 12.3821421,23.2649074 L12.3780323,23.275831 L12.360941,23.7031097 L12.3658947,23.7234994 L12.3769048,23.7357139 L12.4804777,23.8096931 L12.4953491,23.8136134 L12.4953491,23.8136134 L12.5071152,23.8096931 L12.6106902,23.7357139 L12.6232938,23.7196733 L12.6232938,23.7196733 L12.6266527,23.7031097 L12.609561,23.275831 C12.6075724,23.2657013 12.6010112,23.2592993 12.5934901,23.257841 L12.5934901,23.257841 Z M12.8583906,23.1452862 L12.8445485,23.1473072 L12.6598443,23.2396597 L12.6498822,23.2499052 L12.6498822,23.2499052 L12.6471943,23.2611114 L12.6650943,23.6906389 L12.6699349,23.7034178 L12.6699349,23.7034178 L12.678386,23.7104931 L12.8793402,23.8032389 C12.8914285,23.8068999 12.9022333,23.8029875 12.9078286,23.7952264 L12.9118235,23.7811639 L12.8776777,23.1665331 C12.8752882,23.1545897 12.8674102,23.1470016 12.8583906,23.1452862 L12.8583906,23.1452862 Z M12.1430473,23.1473072 C12.1332178,23.1423925 12.1221763,23.1452606 12.1156365,23.1525954 L12.1099173,23.1665331 L12.0757714,23.7811639 C12.0751323,23.7926639 12.0828099,23.8018602 12.0926481,23.8045676 L12.108256,23.8032389 L12.3092106,23.7104931 L12.3186497,23.7024347 L12.3186497,23.7024347 L12.3225043,23.6906389 L12.340401,23.2611114 L12.337245,23.2485176 L12.337245,23.2485176 L12.3277531,23.2396597 L12.1430473,23.1473072 Z" id="MingCute" fill-rule="nonzero"> </path> 445 <path d="M15.7072,11.2929 C16.0977,11.6834 16.0977,12.3166 15.7072,12.7071 L10.0503,18.364 C9.65982,18.7545 9.02666,18.7545 8.63613,18.364 C8.24561,17.9734 8.24561,17.3403 8.63613,16.9497 L13.5859,12 L8.63613,7.05025 C8.24561,6.65973 8.24561,6.02656 8.63613,5.63604 C9.02666,5.24551 9.65982,5.24551 10.0503,5.63604 L15.7072,11.2929 Z" id="路径" fill="#1D98A5"> </path> 446 </g> 447 </g> 448 449 </svg> 450 451 </button> 452 </div> 453 } 454 455 456 </div> 457 458 } 459 if ((fieldValueBlocked != null && !fieldValueBlocked.ToString().Contains(customerNumber)) || String.IsNullOrWhiteSpace(customerNumber)) 460 { 461 <div class="stock-state pt-2 mt-auto"> 462 @{ 463 464 /*stock state*/ 465 double MainvariantStock = MainVariant.Stock; 466 string MainsvgInStock = "<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"16\" height=\"16\" fill=\"#44B11A\" class=\"bi bi-check-lg\" viewBox=\"0 0 16 16\"><path d=\"M12.736 3.97a.733.733 0 0 1 1.047 0c.286.289.29.756.01 1.05L7.88 12.01a.733.733 0 0 1-1.065.02L3.217 8.384a.757.757 0 0 1 0-1.06.733.733 0 0 1 1.047 0l3.052 3.093 5.4-6.425z\"/></svg>"; 467 string MainsvgOutStock = "<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"25\" height=\"25\" fill=\"#CA0D0D\" class=\"bi bi-x-lg\" viewBox=\"0 0 16 16\"><path d=\"M4.646 4.646a.5.5 0 0 1 .708 0L8 7.293l2.646-2.647a.5.5 0 0 1 .708.708L8.707 8l2.647 2.646a.5.5 0 0 1-.708.708L8 8.707l-2.646 2.647a.5.5 0 0 1-.708-.708L7.293 8 4.646 5.354a.5.5 0 0 1 0-.708\"/></svg>"; 468 469 string MaininfoStock = "<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"16\" height=\"16\" fill=\"currentColor\" class=\"bi bi-info-circle-fill\" viewBox=\"0 0 16 16\"><path d=\"M8 16A8 8 0 1 0 8 0a8 8 0 0 0 0 16m.93-9.412-1 4.705c-.07.34.029.533.304.533.194 0 .487-.07.686-.246l-.088.416c-.287.346-.92.598-1.465.598-.703 0-1.002-.422-.808-1.319l.738-3.468c.064-.293.006-.399-.287-.47l-.451-.081.082-.381 2.29-.287zM8 5.5a1 1 0 1 1 0-2 1 1 0 0 1 0 2\" /></svg>"; 470 string MainisNew = MainVariant?.ProductFieldValues?.GetProductFieldValue("New")?.Value?.ToString().ToLower() ?? ""; 471 string MainisNewSvg = "<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"16\" height=\"16\" fill=\"#F2C400\" class=\"bi bi-star-fill\" viewBox=\"0 0 16 16\"><path d = \"M3.612 15.443c-.386.198-.824-.149-.746-.592l.83-4.73L.173 6.765c-.329-.314-.158-.888.283-.95l4.898-.696L7.538.792c.197-.39.73-.39.927 0l2.184 4.327 4.898.696c.441.062.612.636.282.95l-3.522 3.356.83 4.73c.078.443-.36.79-.746.592L8 13.187l-4.389 2.256z\" /></svg> "; 472 string MainstockState = ""; 473 string MainIsSale = MainVariant?.ProductFieldValues?.GetProductFieldValue("Sale")?.Value?.ToString().ToLower() ?? ""; 474 string MainIsSaleSvg = "<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"16\" height=\"16\" fill=\"#F03232\" class=\"bi bi-star-fill\" viewBox=\"0 0 16 16\"><path d = \"M3.612 15.443c-.386.198-.824-.149-.746-.592l.83-4.73L.173 6.765c-.329-.314-.158-.888.283-.95l4.898-.696L7.538.792c.197-.39.73-.39.927 0l2.184 4.327 4.898.696c.441.062.612.636.282.95l-3.522 3.356.83 4.73c.078.443-.36.79-.746.592L8 13.187l-4.389 2.256z\" /></svg> "; 475 string MainexpectedDeliveryDate = ""; 476 477 if (DateTime.Compare(MainVariant.ExpectedDelivery, new DateTime(1900, 1, 1)) != 0) //In DW, if the Date is not set, it is defaulted 01-01-1900 and not null.. 478 { 479 MainexpectedDeliveryDate = MainVariant.ExpectedDelivery.ToShortDateString(); 480 } 481 482 string MainexpectedDeliveryDateText = !String.IsNullOrWhiteSpace(MainexpectedDeliveryDate) ? Translate("Verwacht:") + "&nbsp;" + MainexpectedDeliveryDate : ""; 483 484 @if (!(bool?)MainVariant.ProductFieldValues.Where(o => o.ProductField.SystemName == "ProductToBeDiscontinued").SingleOrDefault()?.Value ?? false) 485 { 486 if (MainvariantStock > 0) 487 { 488 if (MainisNew == "true" || MainIsSale == "true") 489 { 490 if (MainIsSale == "true") 491 { 492 MainstockState += MainIsSaleSvg + "&nbsp; &nbsp;" + Translate("Sale!") + "<br/>"; 493 } 494 495 if (MainisNew == "true") 496 { 497 MainstockState += MainisNewSvg + "&nbsp; &nbsp;" + Translate("New!") + "<br/>"; 498 } 499 500 MainstockState += "&nbsp;" + Translate("Nu leverbaar"); 501 } 502 else 503 { 504 MainstockState = MainsvgInStock + "&nbsp; " + Translate("Op voorraad"); 505 506 } 507 } 508 else 509 { 510 MainstockState = MainsvgOutStock + "&nbsp;" + Translate("Geen voorraad") + "<br/>" + MainexpectedDeliveryDateText; 511 512 } 513 } 514 else 515 { 516 517 MainstockState = MainsvgOutStock + "&nbsp;" + Translate("Discontinued:") + "<br/>" + MainvariantStock + "&nbsp;" + @Translate("left in stock"); 518 519 } 520 /*End stock state*/ 521 522 523 @MainstockState 524 525 526 } 527 </div> 528 } 529 else 530 { 531 <div class="stock-state pt-2 mt-auto"> 532 @MainOutStock @Translate("Discontinued") 533 </div> 534 } 535 <div class="custom-price mt-auto"> 536 @{ 537 538 539 540 541 bool isErpConnectionDown = !Dynamicweb.Core.Converter.ToBoolean(Dynamicweb.Context.Current.Items["IsWebServiceConnectionAvailable"]); 542 bool hidePrice = anonymousUsersLimitations.Contains("price") && anonymousUser || Pageview.AreaSettings.GetBoolean("ErpDownHidePrices") && isErpConnectionDown; 543 544 bool productIsDiscontinued = product is object && product.Discontinued; 545 bool doNotShowPriceIfProductIsDiscontinued = Model.Item.GetBoolean("DoNotShowPriceIfProductIsDiscontinued"); 546 var isDiscontinued = productIsDiscontinued && doNotShowPriceIfProductIsDiscontinued; 547 } 548 549 @if (product is object && !hidePrice && !isDiscontinued) 550 { 551 string unitId = !string.IsNullOrEmpty(Dynamicweb.Context.Current.Request.Form.Get("UnitId")) ? Dynamicweb.Context.Current.Request.Form.Get("UnitId") : string.Empty; 552 553 string priceFontSize = Model.Item.GetRawValueString("PriceSize", "fs-4"); 554 string horizontalAlign = Model.Item.GetRawValueString("HorizontalAlignment", ""); 555 string layout = Model.Item.GetRawValueString("Layout", "horizontal"); 556 string textAlign = horizontalAlign == "center" ? "text-center" : string.Empty; 557 textAlign = horizontalAlign == "end" ? "text-end" : textAlign; 558 559 horizontalAlign = horizontalAlign == "center" && layout == "horizontal" ? "justify-content-center" : horizontalAlign; 560 horizontalAlign = horizontalAlign == "end" && layout == "horizontal" ? "justify-content-end" : horizontalAlign; 561 horizontalAlign = horizontalAlign == "center" && layout == "vertical" ? "align-items-center" : horizontalAlign; 562 horizontalAlign = horizontalAlign == "end" && layout == "vertical" ? "align-items-end" : horizontalAlign; 563 564 string flexDirection = layout == "horizontal" ? string.Empty : "flex-column"; 565 string flexGap = layout == "horizontal" ? "gap-3" : string.Empty; 566 string order = layout == "horizontal" ? string.Empty : "order-2"; 567 568 569 string contentPadding = Model.Item.GetRawValueString("ContentPadding", ""); 570 contentPadding = contentPadding == "none" ? "p-0" : contentPadding; 571 contentPadding = contentPadding == "small" ? "p-1 px-md-2 py-md-1" : contentPadding; 572 contentPadding = contentPadding == "large" ? "p-2 px-md-3 py-md-2" : contentPadding; 573 string liveInfoClass = ""; 574 575 576 577 578 579 580 if (isLazyLoadingForProductInfoEnabled) 581 { 582 if (Dynamicweb.Context.Current.Items.Contains("ProductInfoFeed")) 583 { 584 productInfoFeed = Dynamicweb.Context.Current.Items["ProductInfoFeed"]?.ToString(); 585 if (!string.IsNullOrEmpty(productInfoFeed)) 586 { 587 productInfoFeed = $"data-product-info-feed=\"{productInfoFeed}\""; 588 } 589 } 590 liveInfoClass = "js-live-info"; 591 } 592 593 <div class="@textAlign @liveInfoClass item_@Model.Item.SystemName.ToLower()" data-product-id="@product.Id" data-variant-id="@product.VariantId" @productInfoFeed> 594 @if (showInformativePrice && product.PriceInformative.Price != 0) 595 { 596 <div class="opacity-50"> 597 <span>@Translate("RRP") </span> 598 <span class="text-decoration-line-through text-price">@product.PriceInformative.PriceFormatted</span> 599 </div> 600 } 601 <div class="@priceFontSize m-0 d-flex flex-wrap @flexDirection @flexGap @horizontalAlign" style="row-gap: 0 !important" itemprop="offers" itemscope itemtype="https://schema.org/Offer"> 602 <span itemprop="priceCurrency" content="@product.Price.CurrencyCode" class="d-none"></span> 603 604 605 @if (showPricesWithVat == "false" && !neverShowVat) 606 { 607 if (isLazyLoadingForProductInfoEnabled && !Pageview.IsVisualEditorMode) 608 { 609 <span itemprop="price" content="" class="d-none"></span> 610 <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> 611 } 612 else 613 { 614 string beforePrice = !string.IsNullOrEmpty(unitId) ? product.GetPrice(unitId).PriceBeforeDiscount.PriceWithoutVatFormatted : product.PriceBeforeDiscount.PriceWithoutVatFormatted; 615 616 <span itemprop="price" content="@product.Price.PriceWithoutVat.ToString("0.00", System.Globalization.CultureInfo.InvariantCulture)" class="d-none"></span> 617 if (product.Price.Price != product.PriceBeforeDiscount.Price) 618 { 619 <span class="text-decoration-line-through opacity-75 @order">@beforePrice</span> 620 } 621 } 622 } 623 else 624 { 625 if (isLazyLoadingForProductInfoEnabled && !Pageview.IsVisualEditorMode) 626 { 627 <span itemprop="price" content="" class="d-none"></span> 628 <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> 629 } 630 else 631 { 632 string beforePrice = !string.IsNullOrEmpty(unitId) ? product.GetPrice(unitId).PriceBeforeDiscount.PriceFormatted : product.PriceBeforeDiscount.PriceFormatted; 633 634 <span itemprop="price" content="@product.Price.Price.ToString("0.00", System.Globalization.CultureInfo.InvariantCulture)" class="d-none"></span> 635 636 if (product.Price.Price != product.PriceBeforeDiscount.Price) 637 { 638 <span class="text-decoration-line-through opacity-75 @order"> 639 <span class="text-price">@beforePrice</span> 640 </span> 641 } 642 } 643 } 644 645 @if (showPricesWithVat == "false" && !neverShowVat) 646 { 647 if (isLazyLoadingForProductInfoEnabled && !Pageview.IsVisualEditorMode) 648 { 649 <span class="text-price js-text-price"> 650 <span class="spinner-border" role="status"></span> 651 </span> 652 } 653 else 654 { 655 string price = !string.IsNullOrEmpty(unitId) ? product.GetPrice(unitId).Price.PriceWithoutVatFormatted : product.Price.PriceWithoutVatFormatted; 656 657 if (product?.VariantInfo?.VariantInfo != null) 658 { 659 priceMin = product?.VariantInfo?.PriceMin?.PriceWithoutVatFormatted != null ? product.VariantInfo.PriceMin.PriceWithoutVatFormatted : ""; 660 priceMax = product?.VariantInfo?.PriceMax?.PriceWithoutVatFormatted != null ? product.VariantInfo.PriceMax.PriceWithoutVatFormatted : ""; 661 } 662 if (priceMin != priceMax) 663 { 664 price = priceMin + " - " + priceMax; 665 } 666 <span class="@theme @contentPadding"> 667 <span class="text-price">@price</span> 668 </span> 669 } 670 } 671 else 672 { 673 if (isLazyLoadingForProductInfoEnabled && !Pageview.IsVisualEditorMode) 674 { 675 <span class="text-price js-text-price"> 676 <span class="spinner-border" role="status"></span> 677 </span> 678 } 679 else 680 { 681 string price = !string.IsNullOrEmpty(unitId) ? product.GetPrice(unitId).Price.PriceFormatted : product.Price.PriceFormatted; 682 683 if (product?.VariantInfo?.VariantInfo != null) 684 { 685 priceMin = product?.VariantInfo?.PriceMin?.PriceFormatted != null ? product.VariantInfo.PriceMin.PriceFormatted : ""; 686 priceMax = product?.VariantInfo?.PriceMax?.PriceFormatted != null ? product.VariantInfo.PriceMax.PriceFormatted : ""; 687 } 688 if (priceMin != priceMax) 689 { 690 price = priceMin + " - " + priceMax; 691 } 692 <span class="@theme @contentPadding"> 693 <span class="text-price">@price</span> 694 </span> 695 } 696 } 697 698 @* Stock state for Schema.org, start *@ 699 @{ 700 Uri url = Dynamicweb.Context.Current.Request.Url; 701 } 702 703 <link itemprop="url" href="@url"> 704 705 @{ 706 bool IsNeverOutOfStock = product.NeverOutOfstock; 707 } 708 709 @if (IsNeverOutOfStock) 710 { 711 <span itemprop="availability" class="d-none">@Translate("Available in stock")</span> 712 } 713 else 714 { 715 if (product.StockLevel > 0) 716 { 717 <span itemprop="availability" class="d-none">InStock</span> 718 } 719 else 720 { 721 <span itemprop="availability" class="d-none">OutOfStock</span> 722 } 723 } 724 @* Stock state for Schema.org, stop *@ 725 726 </div> 727 728 @if (showPricesWithVat == "false" && !neverShowVat) 729 { 730 if (isLazyLoadingForProductInfoEnabled && !Pageview.IsVisualEditorMode) 731 { 732 <small class="opacity-85 fst-normal js-text-price-with-vat d-none" data-suffix="@Translate("Incl. VAT")"></small> 733 } 734 else 735 { 736 string price = !string.IsNullOrEmpty(unitId) ? product.GetPrice(unitId).Price.PriceWithVatFormatted : product.Price.PriceWithVatFormatted; 737 738 if (product?.VariantInfo?.VariantInfo != null) 739 { 740 priceMin = product?.VariantInfo?.PriceMin?.PriceWithVatFormatted != null ? product.VariantInfo.PriceMin.PriceWithVatFormatted : ""; 741 priceMax = product?.VariantInfo?.PriceMax?.PriceWithVatFormatted != null ? product.VariantInfo.PriceMax.PriceWithVatFormatted : ""; 742 } 743 if (priceMin != priceMax) 744 { 745 price = priceMin + " - " + priceMax; 746 } 747 <!-- <small class="opacity-85 fst-normal">@price @Translate("Incl. VAT")</small> --> 748 } 749 } 750 </div> 751 } 752 else if (Pageview.IsVisualEditorMode) 753 { 754 <div class="alert alert-dark m-0" role="alert"> 755 <span>@Translate("No products available")</span> 756 </div> 757 } 758 759 </div> 760 } 761 } 762
Tischlampe 1L patch Zylinder
Error executing template "Designs/Swift/Paragraph/CustomProductSlider.cshtml"
System.NullReferenceException: Object reference not set to an instance of an object.
   at CompiledRazorTemplates.Dynamic.RazorEngine_3562354021b44d5c892fe73dc2806e4f.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 Dynamicweb.Ecommerce.ProductCatalog 3 @using Dynamicweb.Ecommerce.CustomerExperienceCenter.Favorites 4 @using Dynamicweb.Files 5 @using System.IO 6 @using System.Net 7 @using Dynamicweb.Security.UserManagement 8 9 10 @{ 11 ProductViewModel product = null; 12 if (Dynamicweb.Context.Current.Items.Contains("ProductDetails")) 13 { 14 product = (ProductViewModel)Dynamicweb.Context.Current.Items["ProductDetails"]; 15 } 16 else if (Pageview.Page.Item["DummyProduct"] != null && Pageview.IsVisualEditorMode) 17 { 18 var pageViewModel = Dynamicweb.Frontend.ContentViewModelFactory.CreatePageInfoViewModel(Pageview.Page); 19 ProductListViewModel productList = pageViewModel.Item.GetValue("DummyProduct") != null ? pageViewModel.Item.GetValue("DummyProduct") as ProductListViewModel : new ProductListViewModel(); 20 21 if (productList?.Products is object) 22 { 23 product = productList.Products[0]; 24 } 25 } 26 } 27 28 @{ 29 var currentUser = Pageview?.User; 30 var customerNumber = !string.IsNullOrEmpty(currentUser?.CustomerNumber) 31 ? currentUser.CustomerNumber 32 : ""; 33 } 34 @if (product is object) 35 { 36 string imagePath = product?.DefaultImage?.Value ?? ""; 37 string imagePathUrlEncoded = Dynamicweb.Context.Current.Server.UrlEncode(imagePath); 38 39 string ratio = Model.Item.GetRawValueString("ImageAspectRatio", ""); 40 ratio = ratio != "0" ? ratio : ""; 41 string ratioCssClass = ratio != "" ? " ratio" : ""; 42 string ratioVariable = ratio != "" ? "--bs-aspect-ratio: " + ratio + ";" : ""; 43 44 string width = Model.Item.GetRawValueString("Width", "auto"); 45 int smallImageSize = 640; 46 int largeImageSize = width == "auto" ? 1280 : Convert.ToInt32(width); 47 48 string ImageObjectFit = Model.Item.GetRawValueString("ImageObjectFit", "contain"); 49 50 string imagePathXs = "/Admin/Public/GetImage.ashx?width=" + smallImageSize + "&image=" + imagePathUrlEncoded + "&format=webp"; 51 string imagePathS = "/Admin/Public/GetImage.ashx?width=" + largeImageSize + "&image=" + imagePathUrlEncoded + "&format=webp"; 52 string imagePathFallBack = "/Admin/Public/GetImage.ashx?width=" + largeImageSize + "&image=" + imagePathUrlEncoded + "&format=webp"; 53 54 var badgeParms = new Dictionary<string, object>(); 55 badgeParms.Add("size", "h7"); 56 badgeParms.Add("saleBadgeType", Model.Item.GetRawValue("SaleBadgeType")); 57 badgeParms.Add("saleBadgeCssClassName", Model.Item.GetRawValue("SaleBadgeDesign")); 58 badgeParms.Add("newBadgeCssClassName", Model.Item.GetRawValue("NewBadgeDesign")); 59 badgeParms.Add("newPublicationDays", Model.Item.GetInt32("NewPublicationDays")); 60 badgeParms.Add("campaignBadgesValues", Model.Item.GetList("CampaignBadges")?.GetRawValue().OfType<string>().ToList()); 61 62 string badgeSize = Model.Item.GetRawValueString("BadgeSize", "fs-2"); 63 bool saleBadgeEnabled = !string.IsNullOrWhiteSpace(Model.Item.GetRawValueString("SaleBadgeDesign")) && Model.Item.GetRawValueString("SaleBadgeDesign") != "none" ? true : false; 64 bool newBadgeEnabled = !string.IsNullOrWhiteSpace(Model.Item.GetRawValueString("NewBadgeDesign")) && Model.Item.GetRawValueString("NewBadgeDesign") != "none" ? true : false; 65 66 /*Custom badge*/ 67 var productService = new Dynamicweb.Ecommerce.Products.ProductService(); 68 var currency = Dynamicweb.Ecommerce.Common.Context.Currency.Code; 69 var formatProvider = new System.Globalization.NumberFormatInfo(); 70 formatProvider.NumberDecimalSeparator = "."; 71 formatProvider.NumberGroupSeparator = ","; 72 var MainVariant = productService.GetProductById(product.Id, product.VariantId, false); 73 var fieldValueBlocked = MainVariant?.ProductFieldValues?.GetProductFieldValue("BlockedCustomerList")?.Value; 74 75 76 string isNewProduct = MainVariant?.ProductFieldValues?.GetProductFieldValue("New")?.Value?.ToString().ToLower() ?? ""; 77 string MainisSale = MainVariant?.ProductFieldValues?.GetProductFieldValue("Sale")?.Value?.ToString().ToLower() ?? ""; 78 bool showNewBadge = isNewProduct == "true" ? true : false; 79 bool showSaleBadge = MainisSale == "true" ? true : false; 80 string showNewSaleBadge = "d-none"; 81 if (showSaleBadge) 82 { 83 badgeParms.Add("isSale", "true"); 84 85 } 86 else 87 { 88 badgeParms.Add("isSale", "false"); 89 } 90 if (showNewBadge) 91 { 92 badgeParms.Add("isNew", "true"); 93 } 94 else 95 { 96 badgeParms.Add("isNew", "false"); 97 } 98 /*End Custom badge*/ 99 if (showSaleBadge || showNewBadge) 100 { 101 showNewSaleBadge = ""; 102 } 103 DateTime createdDate = product.Created.Value; 104 bool showBadges = saleBadgeEnabled && product.Discount.Price != 0 ? true : false; 105 106 bool showFavoritesSelector = !string.IsNullOrEmpty(Model.Item.GetString("ShowAddToFavorites")) ? Model.Item.GetBoolean("ShowAddToFavorites") : false; 107 string anonymousUsersLimitations = Pageview.AreaSettings.GetRawValueString("AnonymousUsers", ""); 108 bool anonymousUser = Pageview.User == null; 109 110 var favoriteParameters = new Dictionary<string, object>(); 111 if (!anonymousUser && showFavoritesSelector) 112 { 113 int defaultFavoriteListId = 0; 114 115 IEnumerable<FavoriteList> favoreiteLists = Pageview.User.GetFavoriteLists(); 116 if (favoreiteLists.Count() == 1) 117 { 118 foreach (FavoriteList list in favoreiteLists) 119 { 120 defaultFavoriteListId = list.ListId; 121 } 122 } 123 124 favoriteParameters.Add("ListId", defaultFavoriteListId); 125 } 126 127 MediaViewModel alternativeImage = new MediaViewModel(); 128 if (Model.Item.GetBoolean("ShowAlternativeImageOnHover")) 129 { 130 var selectedImageCategories = Model.Item.GetList("GetAlternativeImageFrom")?.GetRawValue().OfType<string>().ToList(); 131 List<MediaViewModel> allAssetsImages = product.AssetCategories.Where(x => selectedImageCategories.Contains(x.SystemName)).SelectMany(x => x.Assets).ToList(); 132 allAssetsImages.RemoveAll(x => x.Value == product.DefaultImage.Value); 133 alternativeImage = allAssetsImages.FirstOrDefault(); 134 } 135 136 string altImagePathXs = string.Empty; 137 string altImagePathS = string.Empty; 138 139 if (!string.IsNullOrEmpty(alternativeImage?.Value)) 140 { 141 altImagePathXs = "/Admin/Public/GetImage.ashx?width=" + smallImageSize + "&image=" + Dynamicweb.Context.Current.Server.UrlEncode(alternativeImage.Value) + "&format=webp"; 142 altImagePathS = "/Admin/Public/GetImage.ashx?width=" + largeImageSize + "&image=" + Dynamicweb.Context.Current.Server.UrlEncode(alternativeImage.Value) + "&format=webp"; 143 } 144 145 @* Theme settings *@ 146 string theme = !string.IsNullOrWhiteSpace(Model.Item.GetRawValueString("Theme")) ? " theme " + Model.Item.GetRawValueString("Theme").Replace(" ", "").Trim().ToLower() : ""; 147 string themeBorder = !string.IsNullOrWhiteSpace(theme) ? "border: 1px solid rgba(0,0,0,0)" : ""; 148 string themePadding = !string.IsNullOrWhiteSpace(theme) ? "p-2 p-lg-3" : ""; 149 150 string imageId = "ProductImage_" + product.Id; 151 152 153 154 string fullWidth = width == "auto" ? "w-100" : ""; 155 string customWidth = width != "auto" ? "style=\"width: " + width + "px\"" : "style=\"min-width: 60px\""; 156 157 string altImageZindex = Model.Item.GetBoolean("ShowAlternativeImageOnHover") && !string.IsNullOrEmpty(alternativeImage?.Value) ? " z-index: 1" : string.Empty; 158 string groupid = !string.IsNullOrEmpty(Dynamicweb.Context.Current.Request.QueryString.Get("GroupID")) ? Dynamicweb.Context.Current.Request.QueryString.Get("GroupID"):"" ; 159 string link = product.GetProductLink(GetPageIdByNavigationTag("Shop"), false); 160 var productVariantGroups = product.VariantGroups(); 161 string MainOutStock = "<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"25\" height=\"25\" fill=\"#CA0D0D\" class=\"bi bi-x-lg\" viewBox=\"0 0 16 16\"><path d=\"M4.646 4.646a.5.5 0 0 1 .708 0L8 7.293l2.646-2.647a.5.5 0 0 1 .708.708L8.707 8l2.647 2.646a.5.5 0 0 1-.708.708L8 8.707l-2.646 2.647a.5.5 0 0 1-.708-.708L7.293 8 4.646 5.354a.5.5 0 0 1 0-.708\"/></svg>"; 162 163 @if (!string.IsNullOrEmpty(imagePath)) 164 { 165 <div class="@fullWidth @theme position-relative item_@Model.Item.SystemName.ToLower() main-image-container" @customWidth> 166 <div class="" style="@(ratioVariable)@(altImageZindex)"> 167 <div class="d-flex justify-content-center align-items-center"> 168 <a class="main-link-link" href="@link"> 169 @if (imagePath.StartsWith("/Files/", StringComparison.OrdinalIgnoreCase)) 170 { 171 <img id="@imageId" 172 srcset=" 173 @imagePathXs @(smallImageSize)w, 174 @imagePathS @(largeImageSize)w" 175 sizes="(max-width: 992px) 50vw, 25vw" 176 src="@imagePathFallBack" 177 loading="lazy" 178 decoding="async" 179 class="h-100 w-100 @themePadding main-image" 180 style="object-fit: @ImageObjectFit; @themeBorder " 181 alt="@product.Name" 182 itemprop="image"> 183 } 184 else 185 { 186 <img src="@product.DefaultImage.Value" 187 loading="lazy" 188 class="h-100 w-100 @themePadding main-image" 189 style="object-fit: contain; @themeBorder" 190 alt="@product.Name" 191 itemprop="image"> 192 } 193 </a> 194 </div> 195 </div> 196 197 <div class="position-absolute top-0 left-0 p-2 pb-0 custom-badge-product-list @showNewSaleBadge"> 198 @{ 199 @RenderPartial("Components/Custom_EcommerceBadge.cshtml", product, badgeParms) 200 } 201 </div> 202 203 204 </div> 205 } 206 207 <div class="product-info h-100"> 208 <div class="fs-7 pt-1 opacity-85 start item_@Model.Item.SystemName.ToLower() product-number" itemprop="sku">@product.Id / @product.VariantId - @product.VariantName</div> 209 <div class="py-2" data-col-size="12"> 210 <h2 class="h6 start m-0 item_swift_productheader product-name" itemprop="name"><b>@product.Name</b></h2> 211 </div> 212 </div> 213 var sliderId = $"thumb-scroll-{product.Id}"; 214 if (productVariantGroups.Any() && product?.VariantInfo?.VariantInfo != null) 215 216 { 217 @using Dynamicweb.Ecommerce.Prices 218 @{ 219 string[] variantId = product.VariantId.Split('.'); 220 string showPricesWithVat = Pageview.Area.EcomPricesWithVat.ToLower(); 221 bool neverShowVat = string.IsNullOrEmpty(showPricesWithVat); 222 bool showInformativePrice = Model.Item.GetBoolean("ShowInformativePrice"); 223 string productInfoFeed = ""; 224 bool isLazyLoadingForProductInfoEnabled = Dynamicweb.Core.Converter.ToBoolean(Dynamicweb.Context.Current.Items["IsLazyLoadingForProductInfoEnabled"]); 225 if (isLazyLoadingForProductInfoEnabled) 226 { 227 if (Dynamicweb.Context.Current.Items.Contains("ProductInfoFeed")) 228 { 229 productInfoFeed = Dynamicweb.Context.Current.Items["ProductInfoFeed"]?.ToString(); 230 if (!string.IsNullOrEmpty(productInfoFeed)) 231 { 232 productInfoFeed =productInfoFeed; 233 } 234 } 235 236 } 237 string priceMin = ""; 238 string priceMax = ""; 239 int groupNumber = 1; 240 241 242 243 244 string baseUrl = $"Default.aspx?ID={GetPageIdByNavigationTag("Shop")}&GroupID={product.PrimaryOrDefaultGroup.Id}&ProductID={product.Id}"; 245 if (!string.IsNullOrEmpty(baseUrl)) 246 { 247 baseUrl = $"/{baseUrl.TrimStart('/')}"; 248 } 249 string variantUrl = string.Empty; 250 251 252 Dictionary<string, string> 253 variantImages = new Dictionary<string, string> 254 (); 255 <div class="last-row mt-auto"> 256 257 @foreach (var variantGroup in productVariantGroups) 258 { 259 <div class="thumbnail-wrapper"> 260 <button class="thumb-nav prev" onclick="scrollThumbs('@sliderId', -1)"> 261 <svg width="20px" height="20px" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" fill="#1D98A5"> 262 263 <g stroke="none" stroke-width="1" fill="none" fill-rule="evenodd"> 264 <g transform="translate(-336.000000, 0.000000)"> 265 <g id="left_line" transform="translate(336.000000, 0.000000)"> 266 <path d="M24,0 L24,24 L0,24 L0,0 L24,0 Z M12.5934901,23.257841 L12.5819402,23.2595131 L12.5108777,23.2950439 L12.4918791,23.2987469 L12.4918791,23.2987469 L12.4767152,23.2950439 L12.4056548,23.2595131 C12.3958229,23.2563662 12.3870493,23.2590235 12.3821421,23.2649074 L12.3780323,23.275831 L12.360941,23.7031097 L12.3658947,23.7234994 L12.3769048,23.7357139 L12.4804777,23.8096931 L12.4953491,23.8136134 L12.4953491,23.8136134 L12.5071152,23.8096931 L12.6106902,23.7357139 L12.6232938,23.7196733 L12.6232938,23.7196733 L12.6266527,23.7031097 L12.609561,23.275831 C12.6075724,23.2657013 12.6010112,23.2592993 12.5934901,23.257841 L12.5934901,23.257841 Z M12.8583906,23.1452862 L12.8445485,23.1473072 L12.6598443,23.2396597 L12.6498822,23.2499052 L12.6498822,23.2499052 L12.6471943,23.2611114 L12.6650943,23.6906389 L12.6699349,23.7034178 L12.6699349,23.7034178 L12.678386,23.7104931 L12.8793402,23.8032389 C12.8914285,23.8068999 12.9022333,23.8029875 12.9078286,23.7952264 L12.9118235,23.7811639 L12.8776777,23.1665331 C12.8752882,23.1545897 12.8674102,23.1470016 12.8583906,23.1452862 L12.8583906,23.1452862 Z M12.1430473,23.1473072 C12.1332178,23.1423925 12.1221763,23.1452606 12.1156365,23.1525954 L12.1099173,23.1665331 L12.0757714,23.7811639 C12.0751323,23.7926639 12.0828099,23.8018602 12.0926481,23.8045676 L12.108256,23.8032389 L12.3092106,23.7104931 L12.3186497,23.7024347 L12.3186497,23.7024347 L12.3225043,23.6906389 L12.340401,23.2611114 L12.337245,23.2485176 L12.337245,23.2485176 L12.3277531,23.2396597 L12.1430473,23.1473072 Z" id="MingCute" fill-rule="nonzero"> </path> 267 <path d="M8.29292,12.7071 C7.9024,12.3166 7.9024,11.6834 8.29292,11.2929 L13.9498,5.63604 C14.3403,5.24551 14.9735,5.24551 15.364,5.63604 C15.7545,6.02656 15.7545,6.65973 15.364,7.05025 L10.4142,12 L15.364,16.9497 C15.7545,17.3403 15.7545,17.9734 15.364,18.364 C14.9735,18.7545 14.3403,18.7545 13.9498,18.364 L8.29292,12.7071 Z" id="路径" fill="#1D98A5"> </path> 268 </g> 269 </g> 270 </g> 271 </svg> 272 273 </button> 274 <div class="thumbnail-scroll" id="@sliderId"> 275 @{ 276 VariantGroupViewModel group = variantGroup; 277 foreach (var option in group.Options.OrderBy(o => o.Id)) 278 { 279 var productVariant = productService.GetProductById(product.Id, option.Id, false); 280 281 var productSelection = new PriceProductSelection(productVariant, null, 0); 282 283 var currencyCode = string.IsNullOrWhiteSpace(Pageview.User.Currency) ? Pageview.Area.EcomCurrencyId : Pageview.User.Currency; 284 var countryCode = string.IsNullOrWhiteSpace(Pageview.User.CountryCode) ? Pageview.Area.EcomCountryCode : Pageview.User.CountryCode; 285 286 var userCurrency = Dynamicweb.Ecommerce.Services.Currencies.GetCurrency(currencyCode); 287 var userCountry = Dynamicweb.Ecommerce.Services.Countries.GetCountry(countryCode); 288 289 var priceContext = new PriceContext(userCurrency, userCountry, null, Pageview.User, false, null); 290 var productPrice = Dynamicweb.Ecommerce.Services.Prices.FindPrices(priceContext, productSelection, false); 291 292 //throw new Exception(System.Text.Json.JsonSerializer.Serialize(productPrice)); 293 294 var fieldValue = productVariant?.ProductFieldValues?.GetProductFieldValue("BlockedCustomerList")?.Value; 295 296 if ((fieldValue != null && !fieldValue.ToString().Contains(customerNumber)) || String.IsNullOrWhiteSpace(customerNumber)) 297 { 298 299 300 string active = variantId != null && variantId.Contains(option.Id) ? "active" : string.Empty; 301 string buttonId = $"{product.Id}_{option.Id}_{Pageview.CurrentParagraph.ID}"; 302 string contrastColor = string.Empty; 303 304 string searchKey = $"{product.Id}_{option.Id}_"; 305 /*Images*/ 306 var imagePathVariant = option.Image?.Value ?? ""; 307 308 309 var folderPath = Path.GetDirectoryName(imagePathVariant); 310 311 string physicalFolderPath = Dynamicweb.Context.Current.Server.MapPath(folderPath); 312 313 string lastImage = null; 314 315 if (Directory.Exists(physicalFolderPath)) 316 { 317 318 var fileWith15 = Directory.GetFiles(physicalFolderPath) 319 .FirstOrDefault(f => Path.GetFileName(f).Contains($"{product.Id}_{option.Id}_9")); 320 321 if (fileWith15 != null) 322 { 323 lastImage = fileWith15; 324 } 325 else 326 { 327 var files = Directory.GetFiles(physicalFolderPath) 328 .Where(f => Path.GetFileName(f).StartsWith($"{product.Id}_{option.Id}_")) 329 .OrderByDescending(f => 330 { 331 var filename = Path.GetFileNameWithoutExtension(f); 332 var match = System.Text.RegularExpressions.Regex.Match(filename, @"_(\d+)$"); 333 if (match.Success && int.TryParse(match.Groups[1].Value, out int index)) 334 { 335 return index; 336 } 337 return 0; 338 }) 339 .ToList(); 340 341 if (files.Any()) 342 { 343 lastImage = files.First(); 344 } 345 } 346 } 347 348 var lastImageUrl = lastImage != null ? lastImage : "/Files/Images/zijlstra/Afbeeldingen_overig/Coming_Soon.jpg"; 349 int index = lastImageUrl.IndexOf("Files"); 350 string relativePath = index >= 0 ? lastImageUrl.Substring(index).Replace("\\", "/") : lastImageUrl.Replace("\\", "/"); 351 lastImageUrl = "/" + relativePath; 352 lastImageUrl = Dynamicweb.Context.Current.Server.UrlEncode(lastImageUrl); 353 var variantImg = option.Image is object ? Dynamicweb.Context.Current.Server.UrlEncode(option.Image.Value) : null; 354 var variantLink = "/Default.aspx?ID=" + GetPageIdByNavigationTag("Shop") + "&GroupID=" + product.PrimaryOrDefaultGroup.Id + "&ProductID=" + product.Id + "&VariantID=" + option.Id; 355 356 string variantImage = string.Empty; 357 variantImages.TryGetValue(option.Id, out variantImage); 358 /*End Images*/ 359 360 /*stock state*/ 361 double variantStock = productVariant.Stock; 362 string svgInStock = "<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"16\" height=\"16\" fill=\"#44B11A\" class=\"bi bi-check-lg\" viewBox=\"0 0 16 16\"><path d=\"M12.736 3.97a.733.733 0 0 1 1.047 0c.286.289.29.756.01 1.05L7.88 12.01a.733.733 0 0 1-1.065.02L3.217 8.384a.757.757 0 0 1 0-1.06.733.733 0 0 1 1.047 0l3.052 3.093 5.4-6.425z\"/></svg>"; 363 string svgOutStock = "<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"25\" height=\"25\" fill=\"#CA0D0D\" class=\"bi bi-x-lg\" viewBox=\"0 0 16 16\"><path d=\"M4.646 4.646a.5.5 0 0 1 .708 0L8 7.293l2.646-2.647a.5.5 0 0 1 .708.708L8.707 8l2.647 2.646a.5.5 0 0 1-.708.708L8 8.707l-2.646 2.647a.5.5 0 0 1-.708-.708L7.293 8 4.646 5.354a.5.5 0 0 1 0-.708\"/></svg>"; 364 365 string infoStock = "<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"16\" height=\"16\" fill=\"currentColor\" class=\"bi bi-info-circle-fill\" viewBox=\"0 0 16 16\"><path d=\"M8 16A8 8 0 1 0 8 0a8 8 0 0 0 0 16m.93-9.412-1 4.705c-.07.34.029.533.304.533.194 0 .487-.07.686-.246l-.088.416c-.287.346-.92.598-1.465.598-.703 0-1.002-.422-.808-1.319l.738-3.468c.064-.293.006-.399-.287-.47l-.451-.081.082-.381 2.29-.287zM8 5.5a1 1 0 1 1 0-2 1 1 0 0 1 0 2\" /></svg>"; 366 string isNew = productVariant?.ProductFieldValues?.GetProductFieldValue("New")?.Value?.ToString().ToLower() ?? ""; 367 string isNewSvg = "<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"16\" height=\"16\" fill=\"#F2C400\" class=\"bi bi-star-fill\" viewBox=\"0 0 16 16\"><path d = \"M3.612 15.443c-.386.198-.824-.149-.746-.592l.83-4.73L.173 6.765c-.329-.314-.158-.888.283-.95l4.898-.696L7.538.792c.197-.39.73-.39.927 0l2.184 4.327 4.898.696c.441.062.612.636.282.95l-3.522 3.356.83 4.73c.078.443-.36.79-.746.592L8 13.187l-4.389 2.256z\" /></svg> "; 368 string stockState = ""; 369 370 string isSale = productVariant?.ProductFieldValues?.GetProductFieldValue("Sale")?.Value?.ToString().ToLower() ?? ""; 371 string isSaleSvg = "<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"16\" height=\"16\" fill=\"#F03232\" class=\"bi bi-star-fill\" viewBox=\"0 0 16 16\"><path d = \"M3.612 15.443c-.386.198-.824-.149-.746-.592l.83-4.73L.173 6.765c-.329-.314-.158-.888.283-.95l4.898-.696L7.538.792c.197-.39.73-.39.927 0l2.184 4.327 4.898.696c.441.062.612.636.282.95l-3.522 3.356.83 4.73c.078.443-.36.79-.746.592L8 13.187l-4.389 2.256z\" /></svg> "; 372 373 string expectedDeliveryDate = ""; 374 375 if (DateTime.Compare(productVariant.ExpectedDelivery, new DateTime(1900, 1, 1)) != 0) //In DW, if the Date is not set, it is defaulted 01-01-1900 and not null.. 376 { 377 expectedDeliveryDate = productVariant.ExpectedDelivery.ToShortDateString(); 378 } 379 380 string expectedDeliveryDateText = !String.IsNullOrWhiteSpace(expectedDeliveryDate) ? Translate("Verwacht:") + "&nbsp;" + expectedDeliveryDate : ""; 381 382 @if (!(bool?)productVariant.ProductFieldValues.Where(o => o.ProductField.SystemName == "ProductToBeDiscontinued").SingleOrDefault()?.Value ?? false) 383 { 384 if (variantStock > 0) 385 { 386 if (isNew == "true" || isSale == "true") 387 { 388 if (isSale == "true") 389 { 390 stockState += isSaleSvg + "&nbsp; &nbsp;" + Translate("Sale!") + "<br/>"; 391 } 392 393 if (isNew == "true") 394 { 395 stockState += isNewSvg + "&nbsp; &nbsp;" + Translate("New!") + "<br/>"; 396 } 397 398 stockState += "&nbsp;" + Translate("Nu leverbaar"); 399 } 400 else 401 { 402 stockState = svgInStock + "&nbsp; " + Translate("Op voorraad"); 403 404 } 405 } 406 else 407 { 408 stockState = svgOutStock + "&nbsp;" + Translate("Geen voorraad") + "<br/>" + expectedDeliveryDateText; 409 410 } 411 } 412 else 413 { 414 415 stockState = svgOutStock + "&nbsp;" + Translate("Discontinued:") + "<br/>" + variantStock + "&nbsp;" + @Translate("left in stock"); 416 417 } 418 /*End stock state*/ 419 /*Price variants*/ 420 double price = productVariant.DefaultPrice; 421 double cost = productVariant.Cost; 422 423 string priceFormated = Dynamicweb.Ecommerce.Services.Currencies.Format(Dynamicweb.Ecommerce.Services.Currencies.GetCurrency(currency), Convert.ToDouble(productPrice.ToList()[0].Amount, formatProvider)); 424 //string priceFormated = Dynamicweb.Ecommerce.Services.Currencies.Format(Dynamicweb.Ecommerce.Services.Currencies.GetCurrency(currency), Convert.ToDouble(price, formatProvider)); 425 426 427 428 /*End Price variants*/ 429 430 <img class="theme thumbnail" data-stockstate="@WebUtility.HtmlEncode(stockState)" src="/Admin/Public/GetImage.ashx?image=@(lastImageUrl)&width=64&format=webp" onclick="selectVariant('@(product.Id)','/Admin/Public/GetImage.ashx?image=@(variantImg)&format=webp','@variantLink','@product.Id','@option.Id','@option.Name',this.dataset.stockstate,'@isNew','@isSale','@priceFormated','@cost')" /> 431 432 433 } 434 } 435 436 } 437 </div> 438 <button class="thumb-nav next" onclick="scrollThumbs('@sliderId', 1)"> 439 <svg width="20px" height="20px" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" fill="#1D98A5"> 440 441 <g stroke="none" stroke-width="1" fill="none" fill-rule="evenodd"> 442 <g transform="translate(-384.000000, 0.000000)"> 443 <g id="right_line" transform="translate(384.000000, 0.000000)"> 444 <path d="M24,0 L24,24 L0,24 L0,0 L24,0 Z M12.5934901,23.257841 L12.5819402,23.2595131 L12.5108777,23.2950439 L12.4918791,23.2987469 L12.4918791,23.2987469 L12.4767152,23.2950439 L12.4056548,23.2595131 C12.3958229,23.2563662 12.3870493,23.2590235 12.3821421,23.2649074 L12.3780323,23.275831 L12.360941,23.7031097 L12.3658947,23.7234994 L12.3769048,23.7357139 L12.4804777,23.8096931 L12.4953491,23.8136134 L12.4953491,23.8136134 L12.5071152,23.8096931 L12.6106902,23.7357139 L12.6232938,23.7196733 L12.6232938,23.7196733 L12.6266527,23.7031097 L12.609561,23.275831 C12.6075724,23.2657013 12.6010112,23.2592993 12.5934901,23.257841 L12.5934901,23.257841 Z M12.8583906,23.1452862 L12.8445485,23.1473072 L12.6598443,23.2396597 L12.6498822,23.2499052 L12.6498822,23.2499052 L12.6471943,23.2611114 L12.6650943,23.6906389 L12.6699349,23.7034178 L12.6699349,23.7034178 L12.678386,23.7104931 L12.8793402,23.8032389 C12.8914285,23.8068999 12.9022333,23.8029875 12.9078286,23.7952264 L12.9118235,23.7811639 L12.8776777,23.1665331 C12.8752882,23.1545897 12.8674102,23.1470016 12.8583906,23.1452862 L12.8583906,23.1452862 Z M12.1430473,23.1473072 C12.1332178,23.1423925 12.1221763,23.1452606 12.1156365,23.1525954 L12.1099173,23.1665331 L12.0757714,23.7811639 C12.0751323,23.7926639 12.0828099,23.8018602 12.0926481,23.8045676 L12.108256,23.8032389 L12.3092106,23.7104931 L12.3186497,23.7024347 L12.3186497,23.7024347 L12.3225043,23.6906389 L12.340401,23.2611114 L12.337245,23.2485176 L12.337245,23.2485176 L12.3277531,23.2396597 L12.1430473,23.1473072 Z" id="MingCute" fill-rule="nonzero"> </path> 445 <path d="M15.7072,11.2929 C16.0977,11.6834 16.0977,12.3166 15.7072,12.7071 L10.0503,18.364 C9.65982,18.7545 9.02666,18.7545 8.63613,18.364 C8.24561,17.9734 8.24561,17.3403 8.63613,16.9497 L13.5859,12 L8.63613,7.05025 C8.24561,6.65973 8.24561,6.02656 8.63613,5.63604 C9.02666,5.24551 9.65982,5.24551 10.0503,5.63604 L15.7072,11.2929 Z" id="路径" fill="#1D98A5"> </path> 446 </g> 447 </g> 448 449 </svg> 450 451 </button> 452 </div> 453 } 454 455 456 </div> 457 458 } 459 if ((fieldValueBlocked != null && !fieldValueBlocked.ToString().Contains(customerNumber)) || String.IsNullOrWhiteSpace(customerNumber)) 460 { 461 <div class="stock-state pt-2 mt-auto"> 462 @{ 463 464 /*stock state*/ 465 double MainvariantStock = MainVariant.Stock; 466 string MainsvgInStock = "<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"16\" height=\"16\" fill=\"#44B11A\" class=\"bi bi-check-lg\" viewBox=\"0 0 16 16\"><path d=\"M12.736 3.97a.733.733 0 0 1 1.047 0c.286.289.29.756.01 1.05L7.88 12.01a.733.733 0 0 1-1.065.02L3.217 8.384a.757.757 0 0 1 0-1.06.733.733 0 0 1 1.047 0l3.052 3.093 5.4-6.425z\"/></svg>"; 467 string MainsvgOutStock = "<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"25\" height=\"25\" fill=\"#CA0D0D\" class=\"bi bi-x-lg\" viewBox=\"0 0 16 16\"><path d=\"M4.646 4.646a.5.5 0 0 1 .708 0L8 7.293l2.646-2.647a.5.5 0 0 1 .708.708L8.707 8l2.647 2.646a.5.5 0 0 1-.708.708L8 8.707l-2.646 2.647a.5.5 0 0 1-.708-.708L7.293 8 4.646 5.354a.5.5 0 0 1 0-.708\"/></svg>"; 468 469 string MaininfoStock = "<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"16\" height=\"16\" fill=\"currentColor\" class=\"bi bi-info-circle-fill\" viewBox=\"0 0 16 16\"><path d=\"M8 16A8 8 0 1 0 8 0a8 8 0 0 0 0 16m.93-9.412-1 4.705c-.07.34.029.533.304.533.194 0 .487-.07.686-.246l-.088.416c-.287.346-.92.598-1.465.598-.703 0-1.002-.422-.808-1.319l.738-3.468c.064-.293.006-.399-.287-.47l-.451-.081.082-.381 2.29-.287zM8 5.5a1 1 0 1 1 0-2 1 1 0 0 1 0 2\" /></svg>"; 470 string MainisNew = MainVariant?.ProductFieldValues?.GetProductFieldValue("New")?.Value?.ToString().ToLower() ?? ""; 471 string MainisNewSvg = "<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"16\" height=\"16\" fill=\"#F2C400\" class=\"bi bi-star-fill\" viewBox=\"0 0 16 16\"><path d = \"M3.612 15.443c-.386.198-.824-.149-.746-.592l.83-4.73L.173 6.765c-.329-.314-.158-.888.283-.95l4.898-.696L7.538.792c.197-.39.73-.39.927 0l2.184 4.327 4.898.696c.441.062.612.636.282.95l-3.522 3.356.83 4.73c.078.443-.36.79-.746.592L8 13.187l-4.389 2.256z\" /></svg> "; 472 string MainstockState = ""; 473 string MainIsSale = MainVariant?.ProductFieldValues?.GetProductFieldValue("Sale")?.Value?.ToString().ToLower() ?? ""; 474 string MainIsSaleSvg = "<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"16\" height=\"16\" fill=\"#F03232\" class=\"bi bi-star-fill\" viewBox=\"0 0 16 16\"><path d = \"M3.612 15.443c-.386.198-.824-.149-.746-.592l.83-4.73L.173 6.765c-.329-.314-.158-.888.283-.95l4.898-.696L7.538.792c.197-.39.73-.39.927 0l2.184 4.327 4.898.696c.441.062.612.636.282.95l-3.522 3.356.83 4.73c.078.443-.36.79-.746.592L8 13.187l-4.389 2.256z\" /></svg> "; 475 string MainexpectedDeliveryDate = ""; 476 477 if (DateTime.Compare(MainVariant.ExpectedDelivery, new DateTime(1900, 1, 1)) != 0) //In DW, if the Date is not set, it is defaulted 01-01-1900 and not null.. 478 { 479 MainexpectedDeliveryDate = MainVariant.ExpectedDelivery.ToShortDateString(); 480 } 481 482 string MainexpectedDeliveryDateText = !String.IsNullOrWhiteSpace(MainexpectedDeliveryDate) ? Translate("Verwacht:") + "&nbsp;" + MainexpectedDeliveryDate : ""; 483 484 @if (!(bool?)MainVariant.ProductFieldValues.Where(o => o.ProductField.SystemName == "ProductToBeDiscontinued").SingleOrDefault()?.Value ?? false) 485 { 486 if (MainvariantStock > 0) 487 { 488 if (MainisNew == "true" || MainIsSale == "true") 489 { 490 if (MainIsSale == "true") 491 { 492 MainstockState += MainIsSaleSvg + "&nbsp; &nbsp;" + Translate("Sale!") + "<br/>"; 493 } 494 495 if (MainisNew == "true") 496 { 497 MainstockState += MainisNewSvg + "&nbsp; &nbsp;" + Translate("New!") + "<br/>"; 498 } 499 500 MainstockState += "&nbsp;" + Translate("Nu leverbaar"); 501 } 502 else 503 { 504 MainstockState = MainsvgInStock + "&nbsp; " + Translate("Op voorraad"); 505 506 } 507 } 508 else 509 { 510 MainstockState = MainsvgOutStock + "&nbsp;" + Translate("Geen voorraad") + "<br/>" + MainexpectedDeliveryDateText; 511 512 } 513 } 514 else 515 { 516 517 MainstockState = MainsvgOutStock + "&nbsp;" + Translate("Discontinued:") + "<br/>" + MainvariantStock + "&nbsp;" + @Translate("left in stock"); 518 519 } 520 /*End stock state*/ 521 522 523 @MainstockState 524 525 526 } 527 </div> 528 } 529 else 530 { 531 <div class="stock-state pt-2 mt-auto"> 532 @MainOutStock @Translate("Discontinued") 533 </div> 534 } 535 <div class="custom-price mt-auto"> 536 @{ 537 538 539 540 541 bool isErpConnectionDown = !Dynamicweb.Core.Converter.ToBoolean(Dynamicweb.Context.Current.Items["IsWebServiceConnectionAvailable"]); 542 bool hidePrice = anonymousUsersLimitations.Contains("price") && anonymousUser || Pageview.AreaSettings.GetBoolean("ErpDownHidePrices") && isErpConnectionDown; 543 544 bool productIsDiscontinued = product is object && product.Discontinued; 545 bool doNotShowPriceIfProductIsDiscontinued = Model.Item.GetBoolean("DoNotShowPriceIfProductIsDiscontinued"); 546 var isDiscontinued = productIsDiscontinued && doNotShowPriceIfProductIsDiscontinued; 547 } 548 549 @if (product is object && !hidePrice && !isDiscontinued) 550 { 551 string unitId = !string.IsNullOrEmpty(Dynamicweb.Context.Current.Request.Form.Get("UnitId")) ? Dynamicweb.Context.Current.Request.Form.Get("UnitId") : string.Empty; 552 553 string priceFontSize = Model.Item.GetRawValueString("PriceSize", "fs-4"); 554 string horizontalAlign = Model.Item.GetRawValueString("HorizontalAlignment", ""); 555 string layout = Model.Item.GetRawValueString("Layout", "horizontal"); 556 string textAlign = horizontalAlign == "center" ? "text-center" : string.Empty; 557 textAlign = horizontalAlign == "end" ? "text-end" : textAlign; 558 559 horizontalAlign = horizontalAlign == "center" && layout == "horizontal" ? "justify-content-center" : horizontalAlign; 560 horizontalAlign = horizontalAlign == "end" && layout == "horizontal" ? "justify-content-end" : horizontalAlign; 561 horizontalAlign = horizontalAlign == "center" && layout == "vertical" ? "align-items-center" : horizontalAlign; 562 horizontalAlign = horizontalAlign == "end" && layout == "vertical" ? "align-items-end" : horizontalAlign; 563 564 string flexDirection = layout == "horizontal" ? string.Empty : "flex-column"; 565 string flexGap = layout == "horizontal" ? "gap-3" : string.Empty; 566 string order = layout == "horizontal" ? string.Empty : "order-2"; 567 568 569 string contentPadding = Model.Item.GetRawValueString("ContentPadding", ""); 570 contentPadding = contentPadding == "none" ? "p-0" : contentPadding; 571 contentPadding = contentPadding == "small" ? "p-1 px-md-2 py-md-1" : contentPadding; 572 contentPadding = contentPadding == "large" ? "p-2 px-md-3 py-md-2" : contentPadding; 573 string liveInfoClass = ""; 574 575 576 577 578 579 580 if (isLazyLoadingForProductInfoEnabled) 581 { 582 if (Dynamicweb.Context.Current.Items.Contains("ProductInfoFeed")) 583 { 584 productInfoFeed = Dynamicweb.Context.Current.Items["ProductInfoFeed"]?.ToString(); 585 if (!string.IsNullOrEmpty(productInfoFeed)) 586 { 587 productInfoFeed = $"data-product-info-feed=\"{productInfoFeed}\""; 588 } 589 } 590 liveInfoClass = "js-live-info"; 591 } 592 593 <div class="@textAlign @liveInfoClass item_@Model.Item.SystemName.ToLower()" data-product-id="@product.Id" data-variant-id="@product.VariantId" @productInfoFeed> 594 @if (showInformativePrice && product.PriceInformative.Price != 0) 595 { 596 <div class="opacity-50"> 597 <span>@Translate("RRP") </span> 598 <span class="text-decoration-line-through text-price">@product.PriceInformative.PriceFormatted</span> 599 </div> 600 } 601 <div class="@priceFontSize m-0 d-flex flex-wrap @flexDirection @flexGap @horizontalAlign" style="row-gap: 0 !important" itemprop="offers" itemscope itemtype="https://schema.org/Offer"> 602 <span itemprop="priceCurrency" content="@product.Price.CurrencyCode" class="d-none"></span> 603 604 605 @if (showPricesWithVat == "false" && !neverShowVat) 606 { 607 if (isLazyLoadingForProductInfoEnabled && !Pageview.IsVisualEditorMode) 608 { 609 <span itemprop="price" content="" class="d-none"></span> 610 <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> 611 } 612 else 613 { 614 string beforePrice = !string.IsNullOrEmpty(unitId) ? product.GetPrice(unitId).PriceBeforeDiscount.PriceWithoutVatFormatted : product.PriceBeforeDiscount.PriceWithoutVatFormatted; 615 616 <span itemprop="price" content="@product.Price.PriceWithoutVat.ToString("0.00", System.Globalization.CultureInfo.InvariantCulture)" class="d-none"></span> 617 if (product.Price.Price != product.PriceBeforeDiscount.Price) 618 { 619 <span class="text-decoration-line-through opacity-75 @order">@beforePrice</span> 620 } 621 } 622 } 623 else 624 { 625 if (isLazyLoadingForProductInfoEnabled && !Pageview.IsVisualEditorMode) 626 { 627 <span itemprop="price" content="" class="d-none"></span> 628 <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> 629 } 630 else 631 { 632 string beforePrice = !string.IsNullOrEmpty(unitId) ? product.GetPrice(unitId).PriceBeforeDiscount.PriceFormatted : product.PriceBeforeDiscount.PriceFormatted; 633 634 <span itemprop="price" content="@product.Price.Price.ToString("0.00", System.Globalization.CultureInfo.InvariantCulture)" class="d-none"></span> 635 636 if (product.Price.Price != product.PriceBeforeDiscount.Price) 637 { 638 <span class="text-decoration-line-through opacity-75 @order"> 639 <span class="text-price">@beforePrice</span> 640 </span> 641 } 642 } 643 } 644 645 @if (showPricesWithVat == "false" && !neverShowVat) 646 { 647 if (isLazyLoadingForProductInfoEnabled && !Pageview.IsVisualEditorMode) 648 { 649 <span class="text-price js-text-price"> 650 <span class="spinner-border" role="status"></span> 651 </span> 652 } 653 else 654 { 655 string price = !string.IsNullOrEmpty(unitId) ? product.GetPrice(unitId).Price.PriceWithoutVatFormatted : product.Price.PriceWithoutVatFormatted; 656 657 if (product?.VariantInfo?.VariantInfo != null) 658 { 659 priceMin = product?.VariantInfo?.PriceMin?.PriceWithoutVatFormatted != null ? product.VariantInfo.PriceMin.PriceWithoutVatFormatted : ""; 660 priceMax = product?.VariantInfo?.PriceMax?.PriceWithoutVatFormatted != null ? product.VariantInfo.PriceMax.PriceWithoutVatFormatted : ""; 661 } 662 if (priceMin != priceMax) 663 { 664 price = priceMin + " - " + priceMax; 665 } 666 <span class="@theme @contentPadding"> 667 <span class="text-price">@price</span> 668 </span> 669 } 670 } 671 else 672 { 673 if (isLazyLoadingForProductInfoEnabled && !Pageview.IsVisualEditorMode) 674 { 675 <span class="text-price js-text-price"> 676 <span class="spinner-border" role="status"></span> 677 </span> 678 } 679 else 680 { 681 string price = !string.IsNullOrEmpty(unitId) ? product.GetPrice(unitId).Price.PriceFormatted : product.Price.PriceFormatted; 682 683 if (product?.VariantInfo?.VariantInfo != null) 684 { 685 priceMin = product?.VariantInfo?.PriceMin?.PriceFormatted != null ? product.VariantInfo.PriceMin.PriceFormatted : ""; 686 priceMax = product?.VariantInfo?.PriceMax?.PriceFormatted != null ? product.VariantInfo.PriceMax.PriceFormatted : ""; 687 } 688 if (priceMin != priceMax) 689 { 690 price = priceMin + " - " + priceMax; 691 } 692 <span class="@theme @contentPadding"> 693 <span class="text-price">@price</span> 694 </span> 695 } 696 } 697 698 @* Stock state for Schema.org, start *@ 699 @{ 700 Uri url = Dynamicweb.Context.Current.Request.Url; 701 } 702 703 <link itemprop="url" href="@url"> 704 705 @{ 706 bool IsNeverOutOfStock = product.NeverOutOfstock; 707 } 708 709 @if (IsNeverOutOfStock) 710 { 711 <span itemprop="availability" class="d-none">@Translate("Available in stock")</span> 712 } 713 else 714 { 715 if (product.StockLevel > 0) 716 { 717 <span itemprop="availability" class="d-none">InStock</span> 718 } 719 else 720 { 721 <span itemprop="availability" class="d-none">OutOfStock</span> 722 } 723 } 724 @* Stock state for Schema.org, stop *@ 725 726 </div> 727 728 @if (showPricesWithVat == "false" && !neverShowVat) 729 { 730 if (isLazyLoadingForProductInfoEnabled && !Pageview.IsVisualEditorMode) 731 { 732 <small class="opacity-85 fst-normal js-text-price-with-vat d-none" data-suffix="@Translate("Incl. VAT")"></small> 733 } 734 else 735 { 736 string price = !string.IsNullOrEmpty(unitId) ? product.GetPrice(unitId).Price.PriceWithVatFormatted : product.Price.PriceWithVatFormatted; 737 738 if (product?.VariantInfo?.VariantInfo != null) 739 { 740 priceMin = product?.VariantInfo?.PriceMin?.PriceWithVatFormatted != null ? product.VariantInfo.PriceMin.PriceWithVatFormatted : ""; 741 priceMax = product?.VariantInfo?.PriceMax?.PriceWithVatFormatted != null ? product.VariantInfo.PriceMax.PriceWithVatFormatted : ""; 742 } 743 if (priceMin != priceMax) 744 { 745 price = priceMin + " - " + priceMax; 746 } 747 <!-- <small class="opacity-85 fst-normal">@price @Translate("Incl. VAT")</small> --> 748 } 749 } 750 </div> 751 } 752 else if (Pageview.IsVisualEditorMode) 753 { 754 <div class="alert alert-dark m-0" role="alert"> 755 <span>@Translate("No products available")</span> 756 </div> 757 } 758 759 </div> 760 } 761 } 762
Tischlampe 1L sphere natural
Error executing template "Designs/Swift/Paragraph/CustomProductSlider.cshtml"
System.NullReferenceException: Object reference not set to an instance of an object.
   at CompiledRazorTemplates.Dynamic.RazorEngine_3562354021b44d5c892fe73dc2806e4f.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 Dynamicweb.Ecommerce.ProductCatalog 3 @using Dynamicweb.Ecommerce.CustomerExperienceCenter.Favorites 4 @using Dynamicweb.Files 5 @using System.IO 6 @using System.Net 7 @using Dynamicweb.Security.UserManagement 8 9 10 @{ 11 ProductViewModel product = null; 12 if (Dynamicweb.Context.Current.Items.Contains("ProductDetails")) 13 { 14 product = (ProductViewModel)Dynamicweb.Context.Current.Items["ProductDetails"]; 15 } 16 else if (Pageview.Page.Item["DummyProduct"] != null && Pageview.IsVisualEditorMode) 17 { 18 var pageViewModel = Dynamicweb.Frontend.ContentViewModelFactory.CreatePageInfoViewModel(Pageview.Page); 19 ProductListViewModel productList = pageViewModel.Item.GetValue("DummyProduct") != null ? pageViewModel.Item.GetValue("DummyProduct") as ProductListViewModel : new ProductListViewModel(); 20 21 if (productList?.Products is object) 22 { 23 product = productList.Products[0]; 24 } 25 } 26 } 27 28 @{ 29 var currentUser = Pageview?.User; 30 var customerNumber = !string.IsNullOrEmpty(currentUser?.CustomerNumber) 31 ? currentUser.CustomerNumber 32 : ""; 33 } 34 @if (product is object) 35 { 36 string imagePath = product?.DefaultImage?.Value ?? ""; 37 string imagePathUrlEncoded = Dynamicweb.Context.Current.Server.UrlEncode(imagePath); 38 39 string ratio = Model.Item.GetRawValueString("ImageAspectRatio", ""); 40 ratio = ratio != "0" ? ratio : ""; 41 string ratioCssClass = ratio != "" ? " ratio" : ""; 42 string ratioVariable = ratio != "" ? "--bs-aspect-ratio: " + ratio + ";" : ""; 43 44 string width = Model.Item.GetRawValueString("Width", "auto"); 45 int smallImageSize = 640; 46 int largeImageSize = width == "auto" ? 1280 : Convert.ToInt32(width); 47 48 string ImageObjectFit = Model.Item.GetRawValueString("ImageObjectFit", "contain"); 49 50 string imagePathXs = "/Admin/Public/GetImage.ashx?width=" + smallImageSize + "&image=" + imagePathUrlEncoded + "&format=webp"; 51 string imagePathS = "/Admin/Public/GetImage.ashx?width=" + largeImageSize + "&image=" + imagePathUrlEncoded + "&format=webp"; 52 string imagePathFallBack = "/Admin/Public/GetImage.ashx?width=" + largeImageSize + "&image=" + imagePathUrlEncoded + "&format=webp"; 53 54 var badgeParms = new Dictionary<string, object>(); 55 badgeParms.Add("size", "h7"); 56 badgeParms.Add("saleBadgeType", Model.Item.GetRawValue("SaleBadgeType")); 57 badgeParms.Add("saleBadgeCssClassName", Model.Item.GetRawValue("SaleBadgeDesign")); 58 badgeParms.Add("newBadgeCssClassName", Model.Item.GetRawValue("NewBadgeDesign")); 59 badgeParms.Add("newPublicationDays", Model.Item.GetInt32("NewPublicationDays")); 60 badgeParms.Add("campaignBadgesValues", Model.Item.GetList("CampaignBadges")?.GetRawValue().OfType<string>().ToList()); 61 62 string badgeSize = Model.Item.GetRawValueString("BadgeSize", "fs-2"); 63 bool saleBadgeEnabled = !string.IsNullOrWhiteSpace(Model.Item.GetRawValueString("SaleBadgeDesign")) && Model.Item.GetRawValueString("SaleBadgeDesign") != "none" ? true : false; 64 bool newBadgeEnabled = !string.IsNullOrWhiteSpace(Model.Item.GetRawValueString("NewBadgeDesign")) && Model.Item.GetRawValueString("NewBadgeDesign") != "none" ? true : false; 65 66 /*Custom badge*/ 67 var productService = new Dynamicweb.Ecommerce.Products.ProductService(); 68 var currency = Dynamicweb.Ecommerce.Common.Context.Currency.Code; 69 var formatProvider = new System.Globalization.NumberFormatInfo(); 70 formatProvider.NumberDecimalSeparator = "."; 71 formatProvider.NumberGroupSeparator = ","; 72 var MainVariant = productService.GetProductById(product.Id, product.VariantId, false); 73 var fieldValueBlocked = MainVariant?.ProductFieldValues?.GetProductFieldValue("BlockedCustomerList")?.Value; 74 75 76 string isNewProduct = MainVariant?.ProductFieldValues?.GetProductFieldValue("New")?.Value?.ToString().ToLower() ?? ""; 77 string MainisSale = MainVariant?.ProductFieldValues?.GetProductFieldValue("Sale")?.Value?.ToString().ToLower() ?? ""; 78 bool showNewBadge = isNewProduct == "true" ? true : false; 79 bool showSaleBadge = MainisSale == "true" ? true : false; 80 string showNewSaleBadge = "d-none"; 81 if (showSaleBadge) 82 { 83 badgeParms.Add("isSale", "true"); 84 85 } 86 else 87 { 88 badgeParms.Add("isSale", "false"); 89 } 90 if (showNewBadge) 91 { 92 badgeParms.Add("isNew", "true"); 93 } 94 else 95 { 96 badgeParms.Add("isNew", "false"); 97 } 98 /*End Custom badge*/ 99 if (showSaleBadge || showNewBadge) 100 { 101 showNewSaleBadge = ""; 102 } 103 DateTime createdDate = product.Created.Value; 104 bool showBadges = saleBadgeEnabled && product.Discount.Price != 0 ? true : false; 105 106 bool showFavoritesSelector = !string.IsNullOrEmpty(Model.Item.GetString("ShowAddToFavorites")) ? Model.Item.GetBoolean("ShowAddToFavorites") : false; 107 string anonymousUsersLimitations = Pageview.AreaSettings.GetRawValueString("AnonymousUsers", ""); 108 bool anonymousUser = Pageview.User == null; 109 110 var favoriteParameters = new Dictionary<string, object>(); 111 if (!anonymousUser && showFavoritesSelector) 112 { 113 int defaultFavoriteListId = 0; 114 115 IEnumerable<FavoriteList> favoreiteLists = Pageview.User.GetFavoriteLists(); 116 if (favoreiteLists.Count() == 1) 117 { 118 foreach (FavoriteList list in favoreiteLists) 119 { 120 defaultFavoriteListId = list.ListId; 121 } 122 } 123 124 favoriteParameters.Add("ListId", defaultFavoriteListId); 125 } 126 127 MediaViewModel alternativeImage = new MediaViewModel(); 128 if (Model.Item.GetBoolean("ShowAlternativeImageOnHover")) 129 { 130 var selectedImageCategories = Model.Item.GetList("GetAlternativeImageFrom")?.GetRawValue().OfType<string>().ToList(); 131 List<MediaViewModel> allAssetsImages = product.AssetCategories.Where(x => selectedImageCategories.Contains(x.SystemName)).SelectMany(x => x.Assets).ToList(); 132 allAssetsImages.RemoveAll(x => x.Value == product.DefaultImage.Value); 133 alternativeImage = allAssetsImages.FirstOrDefault(); 134 } 135 136 string altImagePathXs = string.Empty; 137 string altImagePathS = string.Empty; 138 139 if (!string.IsNullOrEmpty(alternativeImage?.Value)) 140 { 141 altImagePathXs = "/Admin/Public/GetImage.ashx?width=" + smallImageSize + "&image=" + Dynamicweb.Context.Current.Server.UrlEncode(alternativeImage.Value) + "&format=webp"; 142 altImagePathS = "/Admin/Public/GetImage.ashx?width=" + largeImageSize + "&image=" + Dynamicweb.Context.Current.Server.UrlEncode(alternativeImage.Value) + "&format=webp"; 143 } 144 145 @* Theme settings *@ 146 string theme = !string.IsNullOrWhiteSpace(Model.Item.GetRawValueString("Theme")) ? " theme " + Model.Item.GetRawValueString("Theme").Replace(" ", "").Trim().ToLower() : ""; 147 string themeBorder = !string.IsNullOrWhiteSpace(theme) ? "border: 1px solid rgba(0,0,0,0)" : ""; 148 string themePadding = !string.IsNullOrWhiteSpace(theme) ? "p-2 p-lg-3" : ""; 149 150 string imageId = "ProductImage_" + product.Id; 151 152 153 154 string fullWidth = width == "auto" ? "w-100" : ""; 155 string customWidth = width != "auto" ? "style=\"width: " + width + "px\"" : "style=\"min-width: 60px\""; 156 157 string altImageZindex = Model.Item.GetBoolean("ShowAlternativeImageOnHover") && !string.IsNullOrEmpty(alternativeImage?.Value) ? " z-index: 1" : string.Empty; 158 string groupid = !string.IsNullOrEmpty(Dynamicweb.Context.Current.Request.QueryString.Get("GroupID")) ? Dynamicweb.Context.Current.Request.QueryString.Get("GroupID"):"" ; 159 string link = product.GetProductLink(GetPageIdByNavigationTag("Shop"), false); 160 var productVariantGroups = product.VariantGroups(); 161 string MainOutStock = "<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"25\" height=\"25\" fill=\"#CA0D0D\" class=\"bi bi-x-lg\" viewBox=\"0 0 16 16\"><path d=\"M4.646 4.646a.5.5 0 0 1 .708 0L8 7.293l2.646-2.647a.5.5 0 0 1 .708.708L8.707 8l2.647 2.646a.5.5 0 0 1-.708.708L8 8.707l-2.646 2.647a.5.5 0 0 1-.708-.708L7.293 8 4.646 5.354a.5.5 0 0 1 0-.708\"/></svg>"; 162 163 @if (!string.IsNullOrEmpty(imagePath)) 164 { 165 <div class="@fullWidth @theme position-relative item_@Model.Item.SystemName.ToLower() main-image-container" @customWidth> 166 <div class="" style="@(ratioVariable)@(altImageZindex)"> 167 <div class="d-flex justify-content-center align-items-center"> 168 <a class="main-link-link" href="@link"> 169 @if (imagePath.StartsWith("/Files/", StringComparison.OrdinalIgnoreCase)) 170 { 171 <img id="@imageId" 172 srcset=" 173 @imagePathXs @(smallImageSize)w, 174 @imagePathS @(largeImageSize)w" 175 sizes="(max-width: 992px) 50vw, 25vw" 176 src="@imagePathFallBack" 177 loading="lazy" 178 decoding="async" 179 class="h-100 w-100 @themePadding main-image" 180 style="object-fit: @ImageObjectFit; @themeBorder " 181 alt="@product.Name" 182 itemprop="image"> 183 } 184 else 185 { 186 <img src="@product.DefaultImage.Value" 187 loading="lazy" 188 class="h-100 w-100 @themePadding main-image" 189 style="object-fit: contain; @themeBorder" 190 alt="@product.Name" 191 itemprop="image"> 192 } 193 </a> 194 </div> 195 </div> 196 197 <div class="position-absolute top-0 left-0 p-2 pb-0 custom-badge-product-list @showNewSaleBadge"> 198 @{ 199 @RenderPartial("Components/Custom_EcommerceBadge.cshtml", product, badgeParms) 200 } 201 </div> 202 203 204 </div> 205 } 206 207 <div class="product-info h-100"> 208 <div class="fs-7 pt-1 opacity-85 start item_@Model.Item.SystemName.ToLower() product-number" itemprop="sku">@product.Id / @product.VariantId - @product.VariantName</div> 209 <div class="py-2" data-col-size="12"> 210 <h2 class="h6 start m-0 item_swift_productheader product-name" itemprop="name"><b>@product.Name</b></h2> 211 </div> 212 </div> 213 var sliderId = $"thumb-scroll-{product.Id}"; 214 if (productVariantGroups.Any() && product?.VariantInfo?.VariantInfo != null) 215 216 { 217 @using Dynamicweb.Ecommerce.Prices 218 @{ 219 string[] variantId = product.VariantId.Split('.'); 220 string showPricesWithVat = Pageview.Area.EcomPricesWithVat.ToLower(); 221 bool neverShowVat = string.IsNullOrEmpty(showPricesWithVat); 222 bool showInformativePrice = Model.Item.GetBoolean("ShowInformativePrice"); 223 string productInfoFeed = ""; 224 bool isLazyLoadingForProductInfoEnabled = Dynamicweb.Core.Converter.ToBoolean(Dynamicweb.Context.Current.Items["IsLazyLoadingForProductInfoEnabled"]); 225 if (isLazyLoadingForProductInfoEnabled) 226 { 227 if (Dynamicweb.Context.Current.Items.Contains("ProductInfoFeed")) 228 { 229 productInfoFeed = Dynamicweb.Context.Current.Items["ProductInfoFeed"]?.ToString(); 230 if (!string.IsNullOrEmpty(productInfoFeed)) 231 { 232 productInfoFeed =productInfoFeed; 233 } 234 } 235 236 } 237 string priceMin = ""; 238 string priceMax = ""; 239 int groupNumber = 1; 240 241 242 243 244 string baseUrl = $"Default.aspx?ID={GetPageIdByNavigationTag("Shop")}&GroupID={product.PrimaryOrDefaultGroup.Id}&ProductID={product.Id}"; 245 if (!string.IsNullOrEmpty(baseUrl)) 246 { 247 baseUrl = $"/{baseUrl.TrimStart('/')}"; 248 } 249 string variantUrl = string.Empty; 250 251 252 Dictionary<string, string> 253 variantImages = new Dictionary<string, string> 254 (); 255 <div class="last-row mt-auto"> 256 257 @foreach (var variantGroup in productVariantGroups) 258 { 259 <div class="thumbnail-wrapper"> 260 <button class="thumb-nav prev" onclick="scrollThumbs('@sliderId', -1)"> 261 <svg width="20px" height="20px" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" fill="#1D98A5"> 262 263 <g stroke="none" stroke-width="1" fill="none" fill-rule="evenodd"> 264 <g transform="translate(-336.000000, 0.000000)"> 265 <g id="left_line" transform="translate(336.000000, 0.000000)"> 266 <path d="M24,0 L24,24 L0,24 L0,0 L24,0 Z M12.5934901,23.257841 L12.5819402,23.2595131 L12.5108777,23.2950439 L12.4918791,23.2987469 L12.4918791,23.2987469 L12.4767152,23.2950439 L12.4056548,23.2595131 C12.3958229,23.2563662 12.3870493,23.2590235 12.3821421,23.2649074 L12.3780323,23.275831 L12.360941,23.7031097 L12.3658947,23.7234994 L12.3769048,23.7357139 L12.4804777,23.8096931 L12.4953491,23.8136134 L12.4953491,23.8136134 L12.5071152,23.8096931 L12.6106902,23.7357139 L12.6232938,23.7196733 L12.6232938,23.7196733 L12.6266527,23.7031097 L12.609561,23.275831 C12.6075724,23.2657013 12.6010112,23.2592993 12.5934901,23.257841 L12.5934901,23.257841 Z M12.8583906,23.1452862 L12.8445485,23.1473072 L12.6598443,23.2396597 L12.6498822,23.2499052 L12.6498822,23.2499052 L12.6471943,23.2611114 L12.6650943,23.6906389 L12.6699349,23.7034178 L12.6699349,23.7034178 L12.678386,23.7104931 L12.8793402,23.8032389 C12.8914285,23.8068999 12.9022333,23.8029875 12.9078286,23.7952264 L12.9118235,23.7811639 L12.8776777,23.1665331 C12.8752882,23.1545897 12.8674102,23.1470016 12.8583906,23.1452862 L12.8583906,23.1452862 Z M12.1430473,23.1473072 C12.1332178,23.1423925 12.1221763,23.1452606 12.1156365,23.1525954 L12.1099173,23.1665331 L12.0757714,23.7811639 C12.0751323,23.7926639 12.0828099,23.8018602 12.0926481,23.8045676 L12.108256,23.8032389 L12.3092106,23.7104931 L12.3186497,23.7024347 L12.3186497,23.7024347 L12.3225043,23.6906389 L12.340401,23.2611114 L12.337245,23.2485176 L12.337245,23.2485176 L12.3277531,23.2396597 L12.1430473,23.1473072 Z" id="MingCute" fill-rule="nonzero"> </path> 267 <path d="M8.29292,12.7071 C7.9024,12.3166 7.9024,11.6834 8.29292,11.2929 L13.9498,5.63604 C14.3403,5.24551 14.9735,5.24551 15.364,5.63604 C15.7545,6.02656 15.7545,6.65973 15.364,7.05025 L10.4142,12 L15.364,16.9497 C15.7545,17.3403 15.7545,17.9734 15.364,18.364 C14.9735,18.7545 14.3403,18.7545 13.9498,18.364 L8.29292,12.7071 Z" id="路径" fill="#1D98A5"> </path> 268 </g> 269 </g> 270 </g> 271 </svg> 272 273 </button> 274 <div class="thumbnail-scroll" id="@sliderId"> 275 @{ 276 VariantGroupViewModel group = variantGroup; 277 foreach (var option in group.Options.OrderBy(o => o.Id)) 278 { 279 var productVariant = productService.GetProductById(product.Id, option.Id, false); 280 281 var productSelection = new PriceProductSelection(productVariant, null, 0); 282 283 var currencyCode = string.IsNullOrWhiteSpace(Pageview.User.Currency) ? Pageview.Area.EcomCurrencyId : Pageview.User.Currency; 284 var countryCode = string.IsNullOrWhiteSpace(Pageview.User.CountryCode) ? Pageview.Area.EcomCountryCode : Pageview.User.CountryCode; 285 286 var userCurrency = Dynamicweb.Ecommerce.Services.Currencies.GetCurrency(currencyCode); 287 var userCountry = Dynamicweb.Ecommerce.Services.Countries.GetCountry(countryCode); 288 289 var priceContext = new PriceContext(userCurrency, userCountry, null, Pageview.User, false, null); 290 var productPrice = Dynamicweb.Ecommerce.Services.Prices.FindPrices(priceContext, productSelection, false); 291 292 //throw new Exception(System.Text.Json.JsonSerializer.Serialize(productPrice)); 293 294 var fieldValue = productVariant?.ProductFieldValues?.GetProductFieldValue("BlockedCustomerList")?.Value; 295 296 if ((fieldValue != null && !fieldValue.ToString().Contains(customerNumber)) || String.IsNullOrWhiteSpace(customerNumber)) 297 { 298 299 300 string active = variantId != null && variantId.Contains(option.Id) ? "active" : string.Empty; 301 string buttonId = $"{product.Id}_{option.Id}_{Pageview.CurrentParagraph.ID}"; 302 string contrastColor = string.Empty; 303 304 string searchKey = $"{product.Id}_{option.Id}_"; 305 /*Images*/ 306 var imagePathVariant = option.Image?.Value ?? ""; 307 308 309 var folderPath = Path.GetDirectoryName(imagePathVariant); 310 311 string physicalFolderPath = Dynamicweb.Context.Current.Server.MapPath(folderPath); 312 313 string lastImage = null; 314 315 if (Directory.Exists(physicalFolderPath)) 316 { 317 318 var fileWith15 = Directory.GetFiles(physicalFolderPath) 319 .FirstOrDefault(f => Path.GetFileName(f).Contains($"{product.Id}_{option.Id}_9")); 320 321 if (fileWith15 != null) 322 { 323 lastImage = fileWith15; 324 } 325 else 326 { 327 var files = Directory.GetFiles(physicalFolderPath) 328 .Where(f => Path.GetFileName(f).StartsWith($"{product.Id}_{option.Id}_")) 329 .OrderByDescending(f => 330 { 331 var filename = Path.GetFileNameWithoutExtension(f); 332 var match = System.Text.RegularExpressions.Regex.Match(filename, @"_(\d+)$"); 333 if (match.Success && int.TryParse(match.Groups[1].Value, out int index)) 334 { 335 return index; 336 } 337 return 0; 338 }) 339 .ToList(); 340 341 if (files.Any()) 342 { 343 lastImage = files.First(); 344 } 345 } 346 } 347 348 var lastImageUrl = lastImage != null ? lastImage : "/Files/Images/zijlstra/Afbeeldingen_overig/Coming_Soon.jpg"; 349 int index = lastImageUrl.IndexOf("Files"); 350 string relativePath = index >= 0 ? lastImageUrl.Substring(index).Replace("\\", "/") : lastImageUrl.Replace("\\", "/"); 351 lastImageUrl = "/" + relativePath; 352 lastImageUrl = Dynamicweb.Context.Current.Server.UrlEncode(lastImageUrl); 353 var variantImg = option.Image is object ? Dynamicweb.Context.Current.Server.UrlEncode(option.Image.Value) : null; 354 var variantLink = "/Default.aspx?ID=" + GetPageIdByNavigationTag("Shop") + "&GroupID=" + product.PrimaryOrDefaultGroup.Id + "&ProductID=" + product.Id + "&VariantID=" + option.Id; 355 356 string variantImage = string.Empty; 357 variantImages.TryGetValue(option.Id, out variantImage); 358 /*End Images*/ 359 360 /*stock state*/ 361 double variantStock = productVariant.Stock; 362 string svgInStock = "<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"16\" height=\"16\" fill=\"#44B11A\" class=\"bi bi-check-lg\" viewBox=\"0 0 16 16\"><path d=\"M12.736 3.97a.733.733 0 0 1 1.047 0c.286.289.29.756.01 1.05L7.88 12.01a.733.733 0 0 1-1.065.02L3.217 8.384a.757.757 0 0 1 0-1.06.733.733 0 0 1 1.047 0l3.052 3.093 5.4-6.425z\"/></svg>"; 363 string svgOutStock = "<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"25\" height=\"25\" fill=\"#CA0D0D\" class=\"bi bi-x-lg\" viewBox=\"0 0 16 16\"><path d=\"M4.646 4.646a.5.5 0 0 1 .708 0L8 7.293l2.646-2.647a.5.5 0 0 1 .708.708L8.707 8l2.647 2.646a.5.5 0 0 1-.708.708L8 8.707l-2.646 2.647a.5.5 0 0 1-.708-.708L7.293 8 4.646 5.354a.5.5 0 0 1 0-.708\"/></svg>"; 364 365 string infoStock = "<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"16\" height=\"16\" fill=\"currentColor\" class=\"bi bi-info-circle-fill\" viewBox=\"0 0 16 16\"><path d=\"M8 16A8 8 0 1 0 8 0a8 8 0 0 0 0 16m.93-9.412-1 4.705c-.07.34.029.533.304.533.194 0 .487-.07.686-.246l-.088.416c-.287.346-.92.598-1.465.598-.703 0-1.002-.422-.808-1.319l.738-3.468c.064-.293.006-.399-.287-.47l-.451-.081.082-.381 2.29-.287zM8 5.5a1 1 0 1 1 0-2 1 1 0 0 1 0 2\" /></svg>"; 366 string isNew = productVariant?.ProductFieldValues?.GetProductFieldValue("New")?.Value?.ToString().ToLower() ?? ""; 367 string isNewSvg = "<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"16\" height=\"16\" fill=\"#F2C400\" class=\"bi bi-star-fill\" viewBox=\"0 0 16 16\"><path d = \"M3.612 15.443c-.386.198-.824-.149-.746-.592l.83-4.73L.173 6.765c-.329-.314-.158-.888.283-.95l4.898-.696L7.538.792c.197-.39.73-.39.927 0l2.184 4.327 4.898.696c.441.062.612.636.282.95l-3.522 3.356.83 4.73c.078.443-.36.79-.746.592L8 13.187l-4.389 2.256z\" /></svg> "; 368 string stockState = ""; 369 370 string isSale = productVariant?.ProductFieldValues?.GetProductFieldValue("Sale")?.Value?.ToString().ToLower() ?? ""; 371 string isSaleSvg = "<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"16\" height=\"16\" fill=\"#F03232\" class=\"bi bi-star-fill\" viewBox=\"0 0 16 16\"><path d = \"M3.612 15.443c-.386.198-.824-.149-.746-.592l.83-4.73L.173 6.765c-.329-.314-.158-.888.283-.95l4.898-.696L7.538.792c.197-.39.73-.39.927 0l2.184 4.327 4.898.696c.441.062.612.636.282.95l-3.522 3.356.83 4.73c.078.443-.36.79-.746.592L8 13.187l-4.389 2.256z\" /></svg> "; 372 373 string expectedDeliveryDate = ""; 374 375 if (DateTime.Compare(productVariant.ExpectedDelivery, new DateTime(1900, 1, 1)) != 0) //In DW, if the Date is not set, it is defaulted 01-01-1900 and not null.. 376 { 377 expectedDeliveryDate = productVariant.ExpectedDelivery.ToShortDateString(); 378 } 379 380 string expectedDeliveryDateText = !String.IsNullOrWhiteSpace(expectedDeliveryDate) ? Translate("Verwacht:") + "&nbsp;" + expectedDeliveryDate : ""; 381 382 @if (!(bool?)productVariant.ProductFieldValues.Where(o => o.ProductField.SystemName == "ProductToBeDiscontinued").SingleOrDefault()?.Value ?? false) 383 { 384 if (variantStock > 0) 385 { 386 if (isNew == "true" || isSale == "true") 387 { 388 if (isSale == "true") 389 { 390 stockState += isSaleSvg + "&nbsp; &nbsp;" + Translate("Sale!") + "<br/>"; 391 } 392 393 if (isNew == "true") 394 { 395 stockState += isNewSvg + "&nbsp; &nbsp;" + Translate("New!") + "<br/>"; 396 } 397 398 stockState += "&nbsp;" + Translate("Nu leverbaar"); 399 } 400 else 401 { 402 stockState = svgInStock + "&nbsp; " + Translate("Op voorraad"); 403 404 } 405 } 406 else 407 { 408 stockState = svgOutStock + "&nbsp;" + Translate("Geen voorraad") + "<br/>" + expectedDeliveryDateText; 409 410 } 411 } 412 else 413 { 414 415 stockState = svgOutStock + "&nbsp;" + Translate("Discontinued:") + "<br/>" + variantStock + "&nbsp;" + @Translate("left in stock"); 416 417 } 418 /*End stock state*/ 419 /*Price variants*/ 420 double price = productVariant.DefaultPrice; 421 double cost = productVariant.Cost; 422 423 string priceFormated = Dynamicweb.Ecommerce.Services.Currencies.Format(Dynamicweb.Ecommerce.Services.Currencies.GetCurrency(currency), Convert.ToDouble(productPrice.ToList()[0].Amount, formatProvider)); 424 //string priceFormated = Dynamicweb.Ecommerce.Services.Currencies.Format(Dynamicweb.Ecommerce.Services.Currencies.GetCurrency(currency), Convert.ToDouble(price, formatProvider)); 425 426 427 428 /*End Price variants*/ 429 430 <img class="theme thumbnail" data-stockstate="@WebUtility.HtmlEncode(stockState)" src="/Admin/Public/GetImage.ashx?image=@(lastImageUrl)&width=64&format=webp" onclick="selectVariant('@(product.Id)','/Admin/Public/GetImage.ashx?image=@(variantImg)&format=webp','@variantLink','@product.Id','@option.Id','@option.Name',this.dataset.stockstate,'@isNew','@isSale','@priceFormated','@cost')" /> 431 432 433 } 434 } 435 436 } 437 </div> 438 <button class="thumb-nav next" onclick="scrollThumbs('@sliderId', 1)"> 439 <svg width="20px" height="20px" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" fill="#1D98A5"> 440 441 <g stroke="none" stroke-width="1" fill="none" fill-rule="evenodd"> 442 <g transform="translate(-384.000000, 0.000000)"> 443 <g id="right_line" transform="translate(384.000000, 0.000000)"> 444 <path d="M24,0 L24,24 L0,24 L0,0 L24,0 Z M12.5934901,23.257841 L12.5819402,23.2595131 L12.5108777,23.2950439 L12.4918791,23.2987469 L12.4918791,23.2987469 L12.4767152,23.2950439 L12.4056548,23.2595131 C12.3958229,23.2563662 12.3870493,23.2590235 12.3821421,23.2649074 L12.3780323,23.275831 L12.360941,23.7031097 L12.3658947,23.7234994 L12.3769048,23.7357139 L12.4804777,23.8096931 L12.4953491,23.8136134 L12.4953491,23.8136134 L12.5071152,23.8096931 L12.6106902,23.7357139 L12.6232938,23.7196733 L12.6232938,23.7196733 L12.6266527,23.7031097 L12.609561,23.275831 C12.6075724,23.2657013 12.6010112,23.2592993 12.5934901,23.257841 L12.5934901,23.257841 Z M12.8583906,23.1452862 L12.8445485,23.1473072 L12.6598443,23.2396597 L12.6498822,23.2499052 L12.6498822,23.2499052 L12.6471943,23.2611114 L12.6650943,23.6906389 L12.6699349,23.7034178 L12.6699349,23.7034178 L12.678386,23.7104931 L12.8793402,23.8032389 C12.8914285,23.8068999 12.9022333,23.8029875 12.9078286,23.7952264 L12.9118235,23.7811639 L12.8776777,23.1665331 C12.8752882,23.1545897 12.8674102,23.1470016 12.8583906,23.1452862 L12.8583906,23.1452862 Z M12.1430473,23.1473072 C12.1332178,23.1423925 12.1221763,23.1452606 12.1156365,23.1525954 L12.1099173,23.1665331 L12.0757714,23.7811639 C12.0751323,23.7926639 12.0828099,23.8018602 12.0926481,23.8045676 L12.108256,23.8032389 L12.3092106,23.7104931 L12.3186497,23.7024347 L12.3186497,23.7024347 L12.3225043,23.6906389 L12.340401,23.2611114 L12.337245,23.2485176 L12.337245,23.2485176 L12.3277531,23.2396597 L12.1430473,23.1473072 Z" id="MingCute" fill-rule="nonzero"> </path> 445 <path d="M15.7072,11.2929 C16.0977,11.6834 16.0977,12.3166 15.7072,12.7071 L10.0503,18.364 C9.65982,18.7545 9.02666,18.7545 8.63613,18.364 C8.24561,17.9734 8.24561,17.3403 8.63613,16.9497 L13.5859,12 L8.63613,7.05025 C8.24561,6.65973 8.24561,6.02656 8.63613,5.63604 C9.02666,5.24551 9.65982,5.24551 10.0503,5.63604 L15.7072,11.2929 Z" id="路径" fill="#1D98A5"> </path> 446 </g> 447 </g> 448 449 </svg> 450 451 </button> 452 </div> 453 } 454 455 456 </div> 457 458 } 459 if ((fieldValueBlocked != null && !fieldValueBlocked.ToString().Contains(customerNumber)) || String.IsNullOrWhiteSpace(customerNumber)) 460 { 461 <div class="stock-state pt-2 mt-auto"> 462 @{ 463 464 /*stock state*/ 465 double MainvariantStock = MainVariant.Stock; 466 string MainsvgInStock = "<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"16\" height=\"16\" fill=\"#44B11A\" class=\"bi bi-check-lg\" viewBox=\"0 0 16 16\"><path d=\"M12.736 3.97a.733.733 0 0 1 1.047 0c.286.289.29.756.01 1.05L7.88 12.01a.733.733 0 0 1-1.065.02L3.217 8.384a.757.757 0 0 1 0-1.06.733.733 0 0 1 1.047 0l3.052 3.093 5.4-6.425z\"/></svg>"; 467 string MainsvgOutStock = "<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"25\" height=\"25\" fill=\"#CA0D0D\" class=\"bi bi-x-lg\" viewBox=\"0 0 16 16\"><path d=\"M4.646 4.646a.5.5 0 0 1 .708 0L8 7.293l2.646-2.647a.5.5 0 0 1 .708.708L8.707 8l2.647 2.646a.5.5 0 0 1-.708.708L8 8.707l-2.646 2.647a.5.5 0 0 1-.708-.708L7.293 8 4.646 5.354a.5.5 0 0 1 0-.708\"/></svg>"; 468 469 string MaininfoStock = "<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"16\" height=\"16\" fill=\"currentColor\" class=\"bi bi-info-circle-fill\" viewBox=\"0 0 16 16\"><path d=\"M8 16A8 8 0 1 0 8 0a8 8 0 0 0 0 16m.93-9.412-1 4.705c-.07.34.029.533.304.533.194 0 .487-.07.686-.246l-.088.416c-.287.346-.92.598-1.465.598-.703 0-1.002-.422-.808-1.319l.738-3.468c.064-.293.006-.399-.287-.47l-.451-.081.082-.381 2.29-.287zM8 5.5a1 1 0 1 1 0-2 1 1 0 0 1 0 2\" /></svg>"; 470 string MainisNew = MainVariant?.ProductFieldValues?.GetProductFieldValue("New")?.Value?.ToString().ToLower() ?? ""; 471 string MainisNewSvg = "<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"16\" height=\"16\" fill=\"#F2C400\" class=\"bi bi-star-fill\" viewBox=\"0 0 16 16\"><path d = \"M3.612 15.443c-.386.198-.824-.149-.746-.592l.83-4.73L.173 6.765c-.329-.314-.158-.888.283-.95l4.898-.696L7.538.792c.197-.39.73-.39.927 0l2.184 4.327 4.898.696c.441.062.612.636.282.95l-3.522 3.356.83 4.73c.078.443-.36.79-.746.592L8 13.187l-4.389 2.256z\" /></svg> "; 472 string MainstockState = ""; 473 string MainIsSale = MainVariant?.ProductFieldValues?.GetProductFieldValue("Sale")?.Value?.ToString().ToLower() ?? ""; 474 string MainIsSaleSvg = "<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"16\" height=\"16\" fill=\"#F03232\" class=\"bi bi-star-fill\" viewBox=\"0 0 16 16\"><path d = \"M3.612 15.443c-.386.198-.824-.149-.746-.592l.83-4.73L.173 6.765c-.329-.314-.158-.888.283-.95l4.898-.696L7.538.792c.197-.39.73-.39.927 0l2.184 4.327 4.898.696c.441.062.612.636.282.95l-3.522 3.356.83 4.73c.078.443-.36.79-.746.592L8 13.187l-4.389 2.256z\" /></svg> "; 475 string MainexpectedDeliveryDate = ""; 476 477 if (DateTime.Compare(MainVariant.ExpectedDelivery, new DateTime(1900, 1, 1)) != 0) //In DW, if the Date is not set, it is defaulted 01-01-1900 and not null.. 478 { 479 MainexpectedDeliveryDate = MainVariant.ExpectedDelivery.ToShortDateString(); 480 } 481 482 string MainexpectedDeliveryDateText = !String.IsNullOrWhiteSpace(MainexpectedDeliveryDate) ? Translate("Verwacht:") + "&nbsp;" + MainexpectedDeliveryDate : ""; 483 484 @if (!(bool?)MainVariant.ProductFieldValues.Where(o => o.ProductField.SystemName == "ProductToBeDiscontinued").SingleOrDefault()?.Value ?? false) 485 { 486 if (MainvariantStock > 0) 487 { 488 if (MainisNew == "true" || MainIsSale == "true") 489 { 490 if (MainIsSale == "true") 491 { 492 MainstockState += MainIsSaleSvg + "&nbsp; &nbsp;" + Translate("Sale!") + "<br/>"; 493 } 494 495 if (MainisNew == "true") 496 { 497 MainstockState += MainisNewSvg + "&nbsp; &nbsp;" + Translate("New!") + "<br/>"; 498 } 499 500 MainstockState += "&nbsp;" + Translate("Nu leverbaar"); 501 } 502 else 503 { 504 MainstockState = MainsvgInStock + "&nbsp; " + Translate("Op voorraad"); 505 506 } 507 } 508 else 509 { 510 MainstockState = MainsvgOutStock + "&nbsp;" + Translate("Geen voorraad") + "<br/>" + MainexpectedDeliveryDateText; 511 512 } 513 } 514 else 515 { 516 517 MainstockState = MainsvgOutStock + "&nbsp;" + Translate("Discontinued:") + "<br/>" + MainvariantStock + "&nbsp;" + @Translate("left in stock"); 518 519 } 520 /*End stock state*/ 521 522 523 @MainstockState 524 525 526 } 527 </div> 528 } 529 else 530 { 531 <div class="stock-state pt-2 mt-auto"> 532 @MainOutStock @Translate("Discontinued") 533 </div> 534 } 535 <div class="custom-price mt-auto"> 536 @{ 537 538 539 540 541 bool isErpConnectionDown = !Dynamicweb.Core.Converter.ToBoolean(Dynamicweb.Context.Current.Items["IsWebServiceConnectionAvailable"]); 542 bool hidePrice = anonymousUsersLimitations.Contains("price") && anonymousUser || Pageview.AreaSettings.GetBoolean("ErpDownHidePrices") && isErpConnectionDown; 543 544 bool productIsDiscontinued = product is object && product.Discontinued; 545 bool doNotShowPriceIfProductIsDiscontinued = Model.Item.GetBoolean("DoNotShowPriceIfProductIsDiscontinued"); 546 var isDiscontinued = productIsDiscontinued && doNotShowPriceIfProductIsDiscontinued; 547 } 548 549 @if (product is object && !hidePrice && !isDiscontinued) 550 { 551 string unitId = !string.IsNullOrEmpty(Dynamicweb.Context.Current.Request.Form.Get("UnitId")) ? Dynamicweb.Context.Current.Request.Form.Get("UnitId") : string.Empty; 552 553 string priceFontSize = Model.Item.GetRawValueString("PriceSize", "fs-4"); 554 string horizontalAlign = Model.Item.GetRawValueString("HorizontalAlignment", ""); 555 string layout = Model.Item.GetRawValueString("Layout", "horizontal"); 556 string textAlign = horizontalAlign == "center" ? "text-center" : string.Empty; 557 textAlign = horizontalAlign == "end" ? "text-end" : textAlign; 558 559 horizontalAlign = horizontalAlign == "center" && layout == "horizontal" ? "justify-content-center" : horizontalAlign; 560 horizontalAlign = horizontalAlign == "end" && layout == "horizontal" ? "justify-content-end" : horizontalAlign; 561 horizontalAlign = horizontalAlign == "center" && layout == "vertical" ? "align-items-center" : horizontalAlign; 562 horizontalAlign = horizontalAlign == "end" && layout == "vertical" ? "align-items-end" : horizontalAlign; 563 564 string flexDirection = layout == "horizontal" ? string.Empty : "flex-column"; 565 string flexGap = layout == "horizontal" ? "gap-3" : string.Empty; 566 string order = layout == "horizontal" ? string.Empty : "order-2"; 567 568 569 string contentPadding = Model.Item.GetRawValueString("ContentPadding", ""); 570 contentPadding = contentPadding == "none" ? "p-0" : contentPadding; 571 contentPadding = contentPadding == "small" ? "p-1 px-md-2 py-md-1" : contentPadding; 572 contentPadding = contentPadding == "large" ? "p-2 px-md-3 py-md-2" : contentPadding; 573 string liveInfoClass = ""; 574 575 576 577 578 579 580 if (isLazyLoadingForProductInfoEnabled) 581 { 582 if (Dynamicweb.Context.Current.Items.Contains("ProductInfoFeed")) 583 { 584 productInfoFeed = Dynamicweb.Context.Current.Items["ProductInfoFeed"]?.ToString(); 585 if (!string.IsNullOrEmpty(productInfoFeed)) 586 { 587 productInfoFeed = $"data-product-info-feed=\"{productInfoFeed}\""; 588 } 589 } 590 liveInfoClass = "js-live-info"; 591 } 592 593 <div class="@textAlign @liveInfoClass item_@Model.Item.SystemName.ToLower()" data-product-id="@product.Id" data-variant-id="@product.VariantId" @productInfoFeed> 594 @if (showInformativePrice && product.PriceInformative.Price != 0) 595 { 596 <div class="opacity-50"> 597 <span>@Translate("RRP") </span> 598 <span class="text-decoration-line-through text-price">@product.PriceInformative.PriceFormatted</span> 599 </div> 600 } 601 <div class="@priceFontSize m-0 d-flex flex-wrap @flexDirection @flexGap @horizontalAlign" style="row-gap: 0 !important" itemprop="offers" itemscope itemtype="https://schema.org/Offer"> 602 <span itemprop="priceCurrency" content="@product.Price.CurrencyCode" class="d-none"></span> 603 604 605 @if (showPricesWithVat == "false" && !neverShowVat) 606 { 607 if (isLazyLoadingForProductInfoEnabled && !Pageview.IsVisualEditorMode) 608 { 609 <span itemprop="price" content="" class="d-none"></span> 610 <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> 611 } 612 else 613 { 614 string beforePrice = !string.IsNullOrEmpty(unitId) ? product.GetPrice(unitId).PriceBeforeDiscount.PriceWithoutVatFormatted : product.PriceBeforeDiscount.PriceWithoutVatFormatted; 615 616 <span itemprop="price" content="@product.Price.PriceWithoutVat.ToString("0.00", System.Globalization.CultureInfo.InvariantCulture)" class="d-none"></span> 617 if (product.Price.Price != product.PriceBeforeDiscount.Price) 618 { 619 <span class="text-decoration-line-through opacity-75 @order">@beforePrice</span> 620 } 621 } 622 } 623 else 624 { 625 if (isLazyLoadingForProductInfoEnabled && !Pageview.IsVisualEditorMode) 626 { 627 <span itemprop="price" content="" class="d-none"></span> 628 <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> 629 } 630 else 631 { 632 string beforePrice = !string.IsNullOrEmpty(unitId) ? product.GetPrice(unitId).PriceBeforeDiscount.PriceFormatted : product.PriceBeforeDiscount.PriceFormatted; 633 634 <span itemprop="price" content="@product.Price.Price.ToString("0.00", System.Globalization.CultureInfo.InvariantCulture)" class="d-none"></span> 635 636 if (product.Price.Price != product.PriceBeforeDiscount.Price) 637 { 638 <span class="text-decoration-line-through opacity-75 @order"> 639 <span class="text-price">@beforePrice</span> 640 </span> 641 } 642 } 643 } 644 645 @if (showPricesWithVat == "false" && !neverShowVat) 646 { 647 if (isLazyLoadingForProductInfoEnabled && !Pageview.IsVisualEditorMode) 648 { 649 <span class="text-price js-text-price"> 650 <span class="spinner-border" role="status"></span> 651 </span> 652 } 653 else 654 { 655 string price = !string.IsNullOrEmpty(unitId) ? product.GetPrice(unitId).Price.PriceWithoutVatFormatted : product.Price.PriceWithoutVatFormatted; 656 657 if (product?.VariantInfo?.VariantInfo != null) 658 { 659 priceMin = product?.VariantInfo?.PriceMin?.PriceWithoutVatFormatted != null ? product.VariantInfo.PriceMin.PriceWithoutVatFormatted : ""; 660 priceMax = product?.VariantInfo?.PriceMax?.PriceWithoutVatFormatted != null ? product.VariantInfo.PriceMax.PriceWithoutVatFormatted : ""; 661 } 662 if (priceMin != priceMax) 663 { 664 price = priceMin + " - " + priceMax; 665 } 666 <span class="@theme @contentPadding"> 667 <span class="text-price">@price</span> 668 </span> 669 } 670 } 671 else 672 { 673 if (isLazyLoadingForProductInfoEnabled && !Pageview.IsVisualEditorMode) 674 { 675 <span class="text-price js-text-price"> 676 <span class="spinner-border" role="status"></span> 677 </span> 678 } 679 else 680 { 681 string price = !string.IsNullOrEmpty(unitId) ? product.GetPrice(unitId).Price.PriceFormatted : product.Price.PriceFormatted; 682 683 if (product?.VariantInfo?.VariantInfo != null) 684 { 685 priceMin = product?.VariantInfo?.PriceMin?.PriceFormatted != null ? product.VariantInfo.PriceMin.PriceFormatted : ""; 686 priceMax = product?.VariantInfo?.PriceMax?.PriceFormatted != null ? product.VariantInfo.PriceMax.PriceFormatted : ""; 687 } 688 if (priceMin != priceMax) 689 { 690 price = priceMin + " - " + priceMax; 691 } 692 <span class="@theme @contentPadding"> 693 <span class="text-price">@price</span> 694 </span> 695 } 696 } 697 698 @* Stock state for Schema.org, start *@ 699 @{ 700 Uri url = Dynamicweb.Context.Current.Request.Url; 701 } 702 703 <link itemprop="url" href="@url"> 704 705 @{ 706 bool IsNeverOutOfStock = product.NeverOutOfstock; 707 } 708 709 @if (IsNeverOutOfStock) 710 { 711 <span itemprop="availability" class="d-none">@Translate("Available in stock")</span> 712 } 713 else 714 { 715 if (product.StockLevel > 0) 716 { 717 <span itemprop="availability" class="d-none">InStock</span> 718 } 719 else 720 { 721 <span itemprop="availability" class="d-none">OutOfStock</span> 722 } 723 } 724 @* Stock state for Schema.org, stop *@ 725 726 </div> 727 728 @if (showPricesWithVat == "false" && !neverShowVat) 729 { 730 if (isLazyLoadingForProductInfoEnabled && !Pageview.IsVisualEditorMode) 731 { 732 <small class="opacity-85 fst-normal js-text-price-with-vat d-none" data-suffix="@Translate("Incl. VAT")"></small> 733 } 734 else 735 { 736 string price = !string.IsNullOrEmpty(unitId) ? product.GetPrice(unitId).Price.PriceWithVatFormatted : product.Price.PriceWithVatFormatted; 737 738 if (product?.VariantInfo?.VariantInfo != null) 739 { 740 priceMin = product?.VariantInfo?.PriceMin?.PriceWithVatFormatted != null ? product.VariantInfo.PriceMin.PriceWithVatFormatted : ""; 741 priceMax = product?.VariantInfo?.PriceMax?.PriceWithVatFormatted != null ? product.VariantInfo.PriceMax.PriceWithVatFormatted : ""; 742 } 743 if (priceMin != priceMax) 744 { 745 price = priceMin + " - " + priceMax; 746 } 747 <!-- <small class="opacity-85 fst-normal">@price @Translate("Incl. VAT")</small> --> 748 } 749 } 750 </div> 751 } 752 else if (Pageview.IsVisualEditorMode) 753 { 754 <div class="alert alert-dark m-0" role="alert"> 755 <span>@Translate("No products available")</span> 756 </div> 757 } 758 759 </div> 760 } 761 } 762
Tischlampe 1L sphere natural L
Error executing template "Designs/Swift/Paragraph/CustomProductSlider.cshtml"
System.NullReferenceException: Object reference not set to an instance of an object.
   at CompiledRazorTemplates.Dynamic.RazorEngine_3562354021b44d5c892fe73dc2806e4f.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 Dynamicweb.Ecommerce.ProductCatalog 3 @using Dynamicweb.Ecommerce.CustomerExperienceCenter.Favorites 4 @using Dynamicweb.Files 5 @using System.IO 6 @using System.Net 7 @using Dynamicweb.Security.UserManagement 8 9 10 @{ 11 ProductViewModel product = null; 12 if (Dynamicweb.Context.Current.Items.Contains("ProductDetails")) 13 { 14 product = (ProductViewModel)Dynamicweb.Context.Current.Items["ProductDetails"]; 15 } 16 else if (Pageview.Page.Item["DummyProduct"] != null && Pageview.IsVisualEditorMode) 17 { 18 var pageViewModel = Dynamicweb.Frontend.ContentViewModelFactory.CreatePageInfoViewModel(Pageview.Page); 19 ProductListViewModel productList = pageViewModel.Item.GetValue("DummyProduct") != null ? pageViewModel.Item.GetValue("DummyProduct") as ProductListViewModel : new ProductListViewModel(); 20 21 if (productList?.Products is object) 22 { 23 product = productList.Products[0]; 24 } 25 } 26 } 27 28 @{ 29 var currentUser = Pageview?.User; 30 var customerNumber = !string.IsNullOrEmpty(currentUser?.CustomerNumber) 31 ? currentUser.CustomerNumber 32 : ""; 33 } 34 @if (product is object) 35 { 36 string imagePath = product?.DefaultImage?.Value ?? ""; 37 string imagePathUrlEncoded = Dynamicweb.Context.Current.Server.UrlEncode(imagePath); 38 39 string ratio = Model.Item.GetRawValueString("ImageAspectRatio", ""); 40 ratio = ratio != "0" ? ratio : ""; 41 string ratioCssClass = ratio != "" ? " ratio" : ""; 42 string ratioVariable = ratio != "" ? "--bs-aspect-ratio: " + ratio + ";" : ""; 43 44 string width = Model.Item.GetRawValueString("Width", "auto"); 45 int smallImageSize = 640; 46 int largeImageSize = width == "auto" ? 1280 : Convert.ToInt32(width); 47 48 string ImageObjectFit = Model.Item.GetRawValueString("ImageObjectFit", "contain"); 49 50 string imagePathXs = "/Admin/Public/GetImage.ashx?width=" + smallImageSize + "&image=" + imagePathUrlEncoded + "&format=webp"; 51 string imagePathS = "/Admin/Public/GetImage.ashx?width=" + largeImageSize + "&image=" + imagePathUrlEncoded + "&format=webp"; 52 string imagePathFallBack = "/Admin/Public/GetImage.ashx?width=" + largeImageSize + "&image=" + imagePathUrlEncoded + "&format=webp"; 53 54 var badgeParms = new Dictionary<string, object>(); 55 badgeParms.Add("size", "h7"); 56 badgeParms.Add("saleBadgeType", Model.Item.GetRawValue("SaleBadgeType")); 57 badgeParms.Add("saleBadgeCssClassName", Model.Item.GetRawValue("SaleBadgeDesign")); 58 badgeParms.Add("newBadgeCssClassName", Model.Item.GetRawValue("NewBadgeDesign")); 59 badgeParms.Add("newPublicationDays", Model.Item.GetInt32("NewPublicationDays")); 60 badgeParms.Add("campaignBadgesValues", Model.Item.GetList("CampaignBadges")?.GetRawValue().OfType<string>().ToList()); 61 62 string badgeSize = Model.Item.GetRawValueString("BadgeSize", "fs-2"); 63 bool saleBadgeEnabled = !string.IsNullOrWhiteSpace(Model.Item.GetRawValueString("SaleBadgeDesign")) && Model.Item.GetRawValueString("SaleBadgeDesign") != "none" ? true : false; 64 bool newBadgeEnabled = !string.IsNullOrWhiteSpace(Model.Item.GetRawValueString("NewBadgeDesign")) && Model.Item.GetRawValueString("NewBadgeDesign") != "none" ? true : false; 65 66 /*Custom badge*/ 67 var productService = new Dynamicweb.Ecommerce.Products.ProductService(); 68 var currency = Dynamicweb.Ecommerce.Common.Context.Currency.Code; 69 var formatProvider = new System.Globalization.NumberFormatInfo(); 70 formatProvider.NumberDecimalSeparator = "."; 71 formatProvider.NumberGroupSeparator = ","; 72 var MainVariant = productService.GetProductById(product.Id, product.VariantId, false); 73 var fieldValueBlocked = MainVariant?.ProductFieldValues?.GetProductFieldValue("BlockedCustomerList")?.Value; 74 75 76 string isNewProduct = MainVariant?.ProductFieldValues?.GetProductFieldValue("New")?.Value?.ToString().ToLower() ?? ""; 77 string MainisSale = MainVariant?.ProductFieldValues?.GetProductFieldValue("Sale")?.Value?.ToString().ToLower() ?? ""; 78 bool showNewBadge = isNewProduct == "true" ? true : false; 79 bool showSaleBadge = MainisSale == "true" ? true : false; 80 string showNewSaleBadge = "d-none"; 81 if (showSaleBadge) 82 { 83 badgeParms.Add("isSale", "true"); 84 85 } 86 else 87 { 88 badgeParms.Add("isSale", "false"); 89 } 90 if (showNewBadge) 91 { 92 badgeParms.Add("isNew", "true"); 93 } 94 else 95 { 96 badgeParms.Add("isNew", "false"); 97 } 98 /*End Custom badge*/ 99 if (showSaleBadge || showNewBadge) 100 { 101 showNewSaleBadge = ""; 102 } 103 DateTime createdDate = product.Created.Value; 104 bool showBadges = saleBadgeEnabled && product.Discount.Price != 0 ? true : false; 105 106 bool showFavoritesSelector = !string.IsNullOrEmpty(Model.Item.GetString("ShowAddToFavorites")) ? Model.Item.GetBoolean("ShowAddToFavorites") : false; 107 string anonymousUsersLimitations = Pageview.AreaSettings.GetRawValueString("AnonymousUsers", ""); 108 bool anonymousUser = Pageview.User == null; 109 110 var favoriteParameters = new Dictionary<string, object>(); 111 if (!anonymousUser && showFavoritesSelector) 112 { 113 int defaultFavoriteListId = 0; 114 115 IEnumerable<FavoriteList> favoreiteLists = Pageview.User.GetFavoriteLists(); 116 if (favoreiteLists.Count() == 1) 117 { 118 foreach (FavoriteList list in favoreiteLists) 119 { 120 defaultFavoriteListId = list.ListId; 121 } 122 } 123 124 favoriteParameters.Add("ListId", defaultFavoriteListId); 125 } 126 127 MediaViewModel alternativeImage = new MediaViewModel(); 128 if (Model.Item.GetBoolean("ShowAlternativeImageOnHover")) 129 { 130 var selectedImageCategories = Model.Item.GetList("GetAlternativeImageFrom")?.GetRawValue().OfType<string>().ToList(); 131 List<MediaViewModel> allAssetsImages = product.AssetCategories.Where(x => selectedImageCategories.Contains(x.SystemName)).SelectMany(x => x.Assets).ToList(); 132 allAssetsImages.RemoveAll(x => x.Value == product.DefaultImage.Value); 133 alternativeImage = allAssetsImages.FirstOrDefault(); 134 } 135 136 string altImagePathXs = string.Empty; 137 string altImagePathS = string.Empty; 138 139 if (!string.IsNullOrEmpty(alternativeImage?.Value)) 140 { 141 altImagePathXs = "/Admin/Public/GetImage.ashx?width=" + smallImageSize + "&image=" + Dynamicweb.Context.Current.Server.UrlEncode(alternativeImage.Value) + "&format=webp"; 142 altImagePathS = "/Admin/Public/GetImage.ashx?width=" + largeImageSize + "&image=" + Dynamicweb.Context.Current.Server.UrlEncode(alternativeImage.Value) + "&format=webp"; 143 } 144 145 @* Theme settings *@ 146 string theme = !string.IsNullOrWhiteSpace(Model.Item.GetRawValueString("Theme")) ? " theme " + Model.Item.GetRawValueString("Theme").Replace(" ", "").Trim().ToLower() : ""; 147 string themeBorder = !string.IsNullOrWhiteSpace(theme) ? "border: 1px solid rgba(0,0,0,0)" : ""; 148 string themePadding = !string.IsNullOrWhiteSpace(theme) ? "p-2 p-lg-3" : ""; 149 150 string imageId = "ProductImage_" + product.Id; 151 152 153 154 string fullWidth = width == "auto" ? "w-100" : ""; 155 string customWidth = width != "auto" ? "style=\"width: " + width + "px\"" : "style=\"min-width: 60px\""; 156 157 string altImageZindex = Model.Item.GetBoolean("ShowAlternativeImageOnHover") && !string.IsNullOrEmpty(alternativeImage?.Value) ? " z-index: 1" : string.Empty; 158 string groupid = !string.IsNullOrEmpty(Dynamicweb.Context.Current.Request.QueryString.Get("GroupID")) ? Dynamicweb.Context.Current.Request.QueryString.Get("GroupID"):"" ; 159 string link = product.GetProductLink(GetPageIdByNavigationTag("Shop"), false); 160 var productVariantGroups = product.VariantGroups(); 161 string MainOutStock = "<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"25\" height=\"25\" fill=\"#CA0D0D\" class=\"bi bi-x-lg\" viewBox=\"0 0 16 16\"><path d=\"M4.646 4.646a.5.5 0 0 1 .708 0L8 7.293l2.646-2.647a.5.5 0 0 1 .708.708L8.707 8l2.647 2.646a.5.5 0 0 1-.708.708L8 8.707l-2.646 2.647a.5.5 0 0 1-.708-.708L7.293 8 4.646 5.354a.5.5 0 0 1 0-.708\"/></svg>"; 162 163 @if (!string.IsNullOrEmpty(imagePath)) 164 { 165 <div class="@fullWidth @theme position-relative item_@Model.Item.SystemName.ToLower() main-image-container" @customWidth> 166 <div class="" style="@(ratioVariable)@(altImageZindex)"> 167 <div class="d-flex justify-content-center align-items-center"> 168 <a class="main-link-link" href="@link"> 169 @if (imagePath.StartsWith("/Files/", StringComparison.OrdinalIgnoreCase)) 170 { 171 <img id="@imageId" 172 srcset=" 173 @imagePathXs @(smallImageSize)w, 174 @imagePathS @(largeImageSize)w" 175 sizes="(max-width: 992px) 50vw, 25vw" 176 src="@imagePathFallBack" 177 loading="lazy" 178 decoding="async" 179 class="h-100 w-100 @themePadding main-image" 180 style="object-fit: @ImageObjectFit; @themeBorder " 181 alt="@product.Name" 182 itemprop="image"> 183 } 184 else 185 { 186 <img src="@product.DefaultImage.Value" 187 loading="lazy" 188 class="h-100 w-100 @themePadding main-image" 189 style="object-fit: contain; @themeBorder" 190 alt="@product.Name" 191 itemprop="image"> 192 } 193 </a> 194 </div> 195 </div> 196 197 <div class="position-absolute top-0 left-0 p-2 pb-0 custom-badge-product-list @showNewSaleBadge"> 198 @{ 199 @RenderPartial("Components/Custom_EcommerceBadge.cshtml", product, badgeParms) 200 } 201 </div> 202 203 204 </div> 205 } 206 207 <div class="product-info h-100"> 208 <div class="fs-7 pt-1 opacity-85 start item_@Model.Item.SystemName.ToLower() product-number" itemprop="sku">@product.Id / @product.VariantId - @product.VariantName</div> 209 <div class="py-2" data-col-size="12"> 210 <h2 class="h6 start m-0 item_swift_productheader product-name" itemprop="name"><b>@product.Name</b></h2> 211 </div> 212 </div> 213 var sliderId = $"thumb-scroll-{product.Id}"; 214 if (productVariantGroups.Any() && product?.VariantInfo?.VariantInfo != null) 215 216 { 217 @using Dynamicweb.Ecommerce.Prices 218 @{ 219 string[] variantId = product.VariantId.Split('.'); 220 string showPricesWithVat = Pageview.Area.EcomPricesWithVat.ToLower(); 221 bool neverShowVat = string.IsNullOrEmpty(showPricesWithVat); 222 bool showInformativePrice = Model.Item.GetBoolean("ShowInformativePrice"); 223 string productInfoFeed = ""; 224 bool isLazyLoadingForProductInfoEnabled = Dynamicweb.Core.Converter.ToBoolean(Dynamicweb.Context.Current.Items["IsLazyLoadingForProductInfoEnabled"]); 225 if (isLazyLoadingForProductInfoEnabled) 226 { 227 if (Dynamicweb.Context.Current.Items.Contains("ProductInfoFeed")) 228 { 229 productInfoFeed = Dynamicweb.Context.Current.Items["ProductInfoFeed"]?.ToString(); 230 if (!string.IsNullOrEmpty(productInfoFeed)) 231 { 232 productInfoFeed =productInfoFeed; 233 } 234 } 235 236 } 237 string priceMin = ""; 238 string priceMax = ""; 239 int groupNumber = 1; 240 241 242 243 244 string baseUrl = $"Default.aspx?ID={GetPageIdByNavigationTag("Shop")}&GroupID={product.PrimaryOrDefaultGroup.Id}&ProductID={product.Id}"; 245 if (!string.IsNullOrEmpty(baseUrl)) 246 { 247 baseUrl = $"/{baseUrl.TrimStart('/')}"; 248 } 249 string variantUrl = string.Empty; 250 251 252 Dictionary<string, string> 253 variantImages = new Dictionary<string, string> 254 (); 255 <div class="last-row mt-auto"> 256 257 @foreach (var variantGroup in productVariantGroups) 258 { 259 <div class="thumbnail-wrapper"> 260 <button class="thumb-nav prev" onclick="scrollThumbs('@sliderId', -1)"> 261 <svg width="20px" height="20px" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" fill="#1D98A5"> 262 263 <g stroke="none" stroke-width="1" fill="none" fill-rule="evenodd"> 264 <g transform="translate(-336.000000, 0.000000)"> 265 <g id="left_line" transform="translate(336.000000, 0.000000)"> 266 <path d="M24,0 L24,24 L0,24 L0,0 L24,0 Z M12.5934901,23.257841 L12.5819402,23.2595131 L12.5108777,23.2950439 L12.4918791,23.2987469 L12.4918791,23.2987469 L12.4767152,23.2950439 L12.4056548,23.2595131 C12.3958229,23.2563662 12.3870493,23.2590235 12.3821421,23.2649074 L12.3780323,23.275831 L12.360941,23.7031097 L12.3658947,23.7234994 L12.3769048,23.7357139 L12.4804777,23.8096931 L12.4953491,23.8136134 L12.4953491,23.8136134 L12.5071152,23.8096931 L12.6106902,23.7357139 L12.6232938,23.7196733 L12.6232938,23.7196733 L12.6266527,23.7031097 L12.609561,23.275831 C12.6075724,23.2657013 12.6010112,23.2592993 12.5934901,23.257841 L12.5934901,23.257841 Z M12.8583906,23.1452862 L12.8445485,23.1473072 L12.6598443,23.2396597 L12.6498822,23.2499052 L12.6498822,23.2499052 L12.6471943,23.2611114 L12.6650943,23.6906389 L12.6699349,23.7034178 L12.6699349,23.7034178 L12.678386,23.7104931 L12.8793402,23.8032389 C12.8914285,23.8068999 12.9022333,23.8029875 12.9078286,23.7952264 L12.9118235,23.7811639 L12.8776777,23.1665331 C12.8752882,23.1545897 12.8674102,23.1470016 12.8583906,23.1452862 L12.8583906,23.1452862 Z M12.1430473,23.1473072 C12.1332178,23.1423925 12.1221763,23.1452606 12.1156365,23.1525954 L12.1099173,23.1665331 L12.0757714,23.7811639 C12.0751323,23.7926639 12.0828099,23.8018602 12.0926481,23.8045676 L12.108256,23.8032389 L12.3092106,23.7104931 L12.3186497,23.7024347 L12.3186497,23.7024347 L12.3225043,23.6906389 L12.340401,23.2611114 L12.337245,23.2485176 L12.337245,23.2485176 L12.3277531,23.2396597 L12.1430473,23.1473072 Z" id="MingCute" fill-rule="nonzero"> </path> 267 <path d="M8.29292,12.7071 C7.9024,12.3166 7.9024,11.6834 8.29292,11.2929 L13.9498,5.63604 C14.3403,5.24551 14.9735,5.24551 15.364,5.63604 C15.7545,6.02656 15.7545,6.65973 15.364,7.05025 L10.4142,12 L15.364,16.9497 C15.7545,17.3403 15.7545,17.9734 15.364,18.364 C14.9735,18.7545 14.3403,18.7545 13.9498,18.364 L8.29292,12.7071 Z" id="路径" fill="#1D98A5"> </path> 268 </g> 269 </g> 270 </g> 271 </svg> 272 273 </button> 274 <div class="thumbnail-scroll" id="@sliderId"> 275 @{ 276 VariantGroupViewModel group = variantGroup; 277 foreach (var option in group.Options.OrderBy(o => o.Id)) 278 { 279 var productVariant = productService.GetProductById(product.Id, option.Id, false); 280 281 var productSelection = new PriceProductSelection(productVariant, null, 0); 282 283 var currencyCode = string.IsNullOrWhiteSpace(Pageview.User.Currency) ? Pageview.Area.EcomCurrencyId : Pageview.User.Currency; 284 var countryCode = string.IsNullOrWhiteSpace(Pageview.User.CountryCode) ? Pageview.Area.EcomCountryCode : Pageview.User.CountryCode; 285 286 var userCurrency = Dynamicweb.Ecommerce.Services.Currencies.GetCurrency(currencyCode); 287 var userCountry = Dynamicweb.Ecommerce.Services.Countries.GetCountry(countryCode); 288 289 var priceContext = new PriceContext(userCurrency, userCountry, null, Pageview.User, false, null); 290 var productPrice = Dynamicweb.Ecommerce.Services.Prices.FindPrices(priceContext, productSelection, false); 291 292 //throw new Exception(System.Text.Json.JsonSerializer.Serialize(productPrice)); 293 294 var fieldValue = productVariant?.ProductFieldValues?.GetProductFieldValue("BlockedCustomerList")?.Value; 295 296 if ((fieldValue != null && !fieldValue.ToString().Contains(customerNumber)) || String.IsNullOrWhiteSpace(customerNumber)) 297 { 298 299 300 string active = variantId != null && variantId.Contains(option.Id) ? "active" : string.Empty; 301 string buttonId = $"{product.Id}_{option.Id}_{Pageview.CurrentParagraph.ID}"; 302 string contrastColor = string.Empty; 303 304 string searchKey = $"{product.Id}_{option.Id}_"; 305 /*Images*/ 306 var imagePathVariant = option.Image?.Value ?? ""; 307 308 309 var folderPath = Path.GetDirectoryName(imagePathVariant); 310 311 string physicalFolderPath = Dynamicweb.Context.Current.Server.MapPath(folderPath); 312 313 string lastImage = null; 314 315 if (Directory.Exists(physicalFolderPath)) 316 { 317 318 var fileWith15 = Directory.GetFiles(physicalFolderPath) 319 .FirstOrDefault(f => Path.GetFileName(f).Contains($"{product.Id}_{option.Id}_9")); 320 321 if (fileWith15 != null) 322 { 323 lastImage = fileWith15; 324 } 325 else 326 { 327 var files = Directory.GetFiles(physicalFolderPath) 328 .Where(f => Path.GetFileName(f).StartsWith($"{product.Id}_{option.Id}_")) 329 .OrderByDescending(f => 330 { 331 var filename = Path.GetFileNameWithoutExtension(f); 332 var match = System.Text.RegularExpressions.Regex.Match(filename, @"_(\d+)$"); 333 if (match.Success && int.TryParse(match.Groups[1].Value, out int index)) 334 { 335 return index; 336 } 337 return 0; 338 }) 339 .ToList(); 340 341 if (files.Any()) 342 { 343 lastImage = files.First(); 344 } 345 } 346 } 347 348 var lastImageUrl = lastImage != null ? lastImage : "/Files/Images/zijlstra/Afbeeldingen_overig/Coming_Soon.jpg"; 349 int index = lastImageUrl.IndexOf("Files"); 350 string relativePath = index >= 0 ? lastImageUrl.Substring(index).Replace("\\", "/") : lastImageUrl.Replace("\\", "/"); 351 lastImageUrl = "/" + relativePath; 352 lastImageUrl = Dynamicweb.Context.Current.Server.UrlEncode(lastImageUrl); 353 var variantImg = option.Image is object ? Dynamicweb.Context.Current.Server.UrlEncode(option.Image.Value) : null; 354 var variantLink = "/Default.aspx?ID=" + GetPageIdByNavigationTag("Shop") + "&GroupID=" + product.PrimaryOrDefaultGroup.Id + "&ProductID=" + product.Id + "&VariantID=" + option.Id; 355 356 string variantImage = string.Empty; 357 variantImages.TryGetValue(option.Id, out variantImage); 358 /*End Images*/ 359 360 /*stock state*/ 361 double variantStock = productVariant.Stock; 362 string svgInStock = "<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"16\" height=\"16\" fill=\"#44B11A\" class=\"bi bi-check-lg\" viewBox=\"0 0 16 16\"><path d=\"M12.736 3.97a.733.733 0 0 1 1.047 0c.286.289.29.756.01 1.05L7.88 12.01a.733.733 0 0 1-1.065.02L3.217 8.384a.757.757 0 0 1 0-1.06.733.733 0 0 1 1.047 0l3.052 3.093 5.4-6.425z\"/></svg>"; 363 string svgOutStock = "<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"25\" height=\"25\" fill=\"#CA0D0D\" class=\"bi bi-x-lg\" viewBox=\"0 0 16 16\"><path d=\"M4.646 4.646a.5.5 0 0 1 .708 0L8 7.293l2.646-2.647a.5.5 0 0 1 .708.708L8.707 8l2.647 2.646a.5.5 0 0 1-.708.708L8 8.707l-2.646 2.647a.5.5 0 0 1-.708-.708L7.293 8 4.646 5.354a.5.5 0 0 1 0-.708\"/></svg>"; 364 365 string infoStock = "<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"16\" height=\"16\" fill=\"currentColor\" class=\"bi bi-info-circle-fill\" viewBox=\"0 0 16 16\"><path d=\"M8 16A8 8 0 1 0 8 0a8 8 0 0 0 0 16m.93-9.412-1 4.705c-.07.34.029.533.304.533.194 0 .487-.07.686-.246l-.088.416c-.287.346-.92.598-1.465.598-.703 0-1.002-.422-.808-1.319l.738-3.468c.064-.293.006-.399-.287-.47l-.451-.081.082-.381 2.29-.287zM8 5.5a1 1 0 1 1 0-2 1 1 0 0 1 0 2\" /></svg>"; 366 string isNew = productVariant?.ProductFieldValues?.GetProductFieldValue("New")?.Value?.ToString().ToLower() ?? ""; 367 string isNewSvg = "<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"16\" height=\"16\" fill=\"#F2C400\" class=\"bi bi-star-fill\" viewBox=\"0 0 16 16\"><path d = \"M3.612 15.443c-.386.198-.824-.149-.746-.592l.83-4.73L.173 6.765c-.329-.314-.158-.888.283-.95l4.898-.696L7.538.792c.197-.39.73-.39.927 0l2.184 4.327 4.898.696c.441.062.612.636.282.95l-3.522 3.356.83 4.73c.078.443-.36.79-.746.592L8 13.187l-4.389 2.256z\" /></svg> "; 368 string stockState = ""; 369 370 string isSale = productVariant?.ProductFieldValues?.GetProductFieldValue("Sale")?.Value?.ToString().ToLower() ?? ""; 371 string isSaleSvg = "<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"16\" height=\"16\" fill=\"#F03232\" class=\"bi bi-star-fill\" viewBox=\"0 0 16 16\"><path d = \"M3.612 15.443c-.386.198-.824-.149-.746-.592l.83-4.73L.173 6.765c-.329-.314-.158-.888.283-.95l4.898-.696L7.538.792c.197-.39.73-.39.927 0l2.184 4.327 4.898.696c.441.062.612.636.282.95l-3.522 3.356.83 4.73c.078.443-.36.79-.746.592L8 13.187l-4.389 2.256z\" /></svg> "; 372 373 string expectedDeliveryDate = ""; 374 375 if (DateTime.Compare(productVariant.ExpectedDelivery, new DateTime(1900, 1, 1)) != 0) //In DW, if the Date is not set, it is defaulted 01-01-1900 and not null.. 376 { 377 expectedDeliveryDate = productVariant.ExpectedDelivery.ToShortDateString(); 378 } 379 380 string expectedDeliveryDateText = !String.IsNullOrWhiteSpace(expectedDeliveryDate) ? Translate("Verwacht:") + "&nbsp;" + expectedDeliveryDate : ""; 381 382 @if (!(bool?)productVariant.ProductFieldValues.Where(o => o.ProductField.SystemName == "ProductToBeDiscontinued").SingleOrDefault()?.Value ?? false) 383 { 384 if (variantStock > 0) 385 { 386 if (isNew == "true" || isSale == "true") 387 { 388 if (isSale == "true") 389 { 390 stockState += isSaleSvg + "&nbsp; &nbsp;" + Translate("Sale!") + "<br/>"; 391 } 392 393 if (isNew == "true") 394 { 395 stockState += isNewSvg + "&nbsp; &nbsp;" + Translate("New!") + "<br/>"; 396 } 397 398 stockState += "&nbsp;" + Translate("Nu leverbaar"); 399 } 400 else 401 { 402 stockState = svgInStock + "&nbsp; " + Translate("Op voorraad"); 403 404 } 405 } 406 else 407 { 408 stockState = svgOutStock + "&nbsp;" + Translate("Geen voorraad") + "<br/>" + expectedDeliveryDateText; 409 410 } 411 } 412 else 413 { 414 415 stockState = svgOutStock + "&nbsp;" + Translate("Discontinued:") + "<br/>" + variantStock + "&nbsp;" + @Translate("left in stock"); 416 417 } 418 /*End stock state*/ 419 /*Price variants*/ 420 double price = productVariant.DefaultPrice; 421 double cost = productVariant.Cost; 422 423 string priceFormated = Dynamicweb.Ecommerce.Services.Currencies.Format(Dynamicweb.Ecommerce.Services.Currencies.GetCurrency(currency), Convert.ToDouble(productPrice.ToList()[0].Amount, formatProvider)); 424 //string priceFormated = Dynamicweb.Ecommerce.Services.Currencies.Format(Dynamicweb.Ecommerce.Services.Currencies.GetCurrency(currency), Convert.ToDouble(price, formatProvider)); 425 426 427 428 /*End Price variants*/ 429 430 <img class="theme thumbnail" data-stockstate="@WebUtility.HtmlEncode(stockState)" src="/Admin/Public/GetImage.ashx?image=@(lastImageUrl)&width=64&format=webp" onclick="selectVariant('@(product.Id)','/Admin/Public/GetImage.ashx?image=@(variantImg)&format=webp','@variantLink','@product.Id','@option.Id','@option.Name',this.dataset.stockstate,'@isNew','@isSale','@priceFormated','@cost')" /> 431 432 433 } 434 } 435 436 } 437 </div> 438 <button class="thumb-nav next" onclick="scrollThumbs('@sliderId', 1)"> 439 <svg width="20px" height="20px" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" fill="#1D98A5"> 440 441 <g stroke="none" stroke-width="1" fill="none" fill-rule="evenodd"> 442 <g transform="translate(-384.000000, 0.000000)"> 443 <g id="right_line" transform="translate(384.000000, 0.000000)"> 444 <path d="M24,0 L24,24 L0,24 L0,0 L24,0 Z M12.5934901,23.257841 L12.5819402,23.2595131 L12.5108777,23.2950439 L12.4918791,23.2987469 L12.4918791,23.2987469 L12.4767152,23.2950439 L12.4056548,23.2595131 C12.3958229,23.2563662 12.3870493,23.2590235 12.3821421,23.2649074 L12.3780323,23.275831 L12.360941,23.7031097 L12.3658947,23.7234994 L12.3769048,23.7357139 L12.4804777,23.8096931 L12.4953491,23.8136134 L12.4953491,23.8136134 L12.5071152,23.8096931 L12.6106902,23.7357139 L12.6232938,23.7196733 L12.6232938,23.7196733 L12.6266527,23.7031097 L12.609561,23.275831 C12.6075724,23.2657013 12.6010112,23.2592993 12.5934901,23.257841 L12.5934901,23.257841 Z M12.8583906,23.1452862 L12.8445485,23.1473072 L12.6598443,23.2396597 L12.6498822,23.2499052 L12.6498822,23.2499052 L12.6471943,23.2611114 L12.6650943,23.6906389 L12.6699349,23.7034178 L12.6699349,23.7034178 L12.678386,23.7104931 L12.8793402,23.8032389 C12.8914285,23.8068999 12.9022333,23.8029875 12.9078286,23.7952264 L12.9118235,23.7811639 L12.8776777,23.1665331 C12.8752882,23.1545897 12.8674102,23.1470016 12.8583906,23.1452862 L12.8583906,23.1452862 Z M12.1430473,23.1473072 C12.1332178,23.1423925 12.1221763,23.1452606 12.1156365,23.1525954 L12.1099173,23.1665331 L12.0757714,23.7811639 C12.0751323,23.7926639 12.0828099,23.8018602 12.0926481,23.8045676 L12.108256,23.8032389 L12.3092106,23.7104931 L12.3186497,23.7024347 L12.3186497,23.7024347 L12.3225043,23.6906389 L12.340401,23.2611114 L12.337245,23.2485176 L12.337245,23.2485176 L12.3277531,23.2396597 L12.1430473,23.1473072 Z" id="MingCute" fill-rule="nonzero"> </path> 445 <path d="M15.7072,11.2929 C16.0977,11.6834 16.0977,12.3166 15.7072,12.7071 L10.0503,18.364 C9.65982,18.7545 9.02666,18.7545 8.63613,18.364 C8.24561,17.9734 8.24561,17.3403 8.63613,16.9497 L13.5859,12 L8.63613,7.05025 C8.24561,6.65973 8.24561,6.02656 8.63613,5.63604 C9.02666,5.24551 9.65982,5.24551 10.0503,5.63604 L15.7072,11.2929 Z" id="路径" fill="#1D98A5"> </path> 446 </g> 447 </g> 448 449 </svg> 450 451 </button> 452 </div> 453 } 454 455 456 </div> 457 458 } 459 if ((fieldValueBlocked != null && !fieldValueBlocked.ToString().Contains(customerNumber)) || String.IsNullOrWhiteSpace(customerNumber)) 460 { 461 <div class="stock-state pt-2 mt-auto"> 462 @{ 463 464 /*stock state*/ 465 double MainvariantStock = MainVariant.Stock; 466 string MainsvgInStock = "<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"16\" height=\"16\" fill=\"#44B11A\" class=\"bi bi-check-lg\" viewBox=\"0 0 16 16\"><path d=\"M12.736 3.97a.733.733 0 0 1 1.047 0c.286.289.29.756.01 1.05L7.88 12.01a.733.733 0 0 1-1.065.02L3.217 8.384a.757.757 0 0 1 0-1.06.733.733 0 0 1 1.047 0l3.052 3.093 5.4-6.425z\"/></svg>"; 467 string MainsvgOutStock = "<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"25\" height=\"25\" fill=\"#CA0D0D\" class=\"bi bi-x-lg\" viewBox=\"0 0 16 16\"><path d=\"M4.646 4.646a.5.5 0 0 1 .708 0L8 7.293l2.646-2.647a.5.5 0 0 1 .708.708L8.707 8l2.647 2.646a.5.5 0 0 1-.708.708L8 8.707l-2.646 2.647a.5.5 0 0 1-.708-.708L7.293 8 4.646 5.354a.5.5 0 0 1 0-.708\"/></svg>"; 468 469 string MaininfoStock = "<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"16\" height=\"16\" fill=\"currentColor\" class=\"bi bi-info-circle-fill\" viewBox=\"0 0 16 16\"><path d=\"M8 16A8 8 0 1 0 8 0a8 8 0 0 0 0 16m.93-9.412-1 4.705c-.07.34.029.533.304.533.194 0 .487-.07.686-.246l-.088.416c-.287.346-.92.598-1.465.598-.703 0-1.002-.422-.808-1.319l.738-3.468c.064-.293.006-.399-.287-.47l-.451-.081.082-.381 2.29-.287zM8 5.5a1 1 0 1 1 0-2 1 1 0 0 1 0 2\" /></svg>"; 470 string MainisNew = MainVariant?.ProductFieldValues?.GetProductFieldValue("New")?.Value?.ToString().ToLower() ?? ""; 471 string MainisNewSvg = "<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"16\" height=\"16\" fill=\"#F2C400\" class=\"bi bi-star-fill\" viewBox=\"0 0 16 16\"><path d = \"M3.612 15.443c-.386.198-.824-.149-.746-.592l.83-4.73L.173 6.765c-.329-.314-.158-.888.283-.95l4.898-.696L7.538.792c.197-.39.73-.39.927 0l2.184 4.327 4.898.696c.441.062.612.636.282.95l-3.522 3.356.83 4.73c.078.443-.36.79-.746.592L8 13.187l-4.389 2.256z\" /></svg> "; 472 string MainstockState = ""; 473 string MainIsSale = MainVariant?.ProductFieldValues?.GetProductFieldValue("Sale")?.Value?.ToString().ToLower() ?? ""; 474 string MainIsSaleSvg = "<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"16\" height=\"16\" fill=\"#F03232\" class=\"bi bi-star-fill\" viewBox=\"0 0 16 16\"><path d = \"M3.612 15.443c-.386.198-.824-.149-.746-.592l.83-4.73L.173 6.765c-.329-.314-.158-.888.283-.95l4.898-.696L7.538.792c.197-.39.73-.39.927 0l2.184 4.327 4.898.696c.441.062.612.636.282.95l-3.522 3.356.83 4.73c.078.443-.36.79-.746.592L8 13.187l-4.389 2.256z\" /></svg> "; 475 string MainexpectedDeliveryDate = ""; 476 477 if (DateTime.Compare(MainVariant.ExpectedDelivery, new DateTime(1900, 1, 1)) != 0) //In DW, if the Date is not set, it is defaulted 01-01-1900 and not null.. 478 { 479 MainexpectedDeliveryDate = MainVariant.ExpectedDelivery.ToShortDateString(); 480 } 481 482 string MainexpectedDeliveryDateText = !String.IsNullOrWhiteSpace(MainexpectedDeliveryDate) ? Translate("Verwacht:") + "&nbsp;" + MainexpectedDeliveryDate : ""; 483 484 @if (!(bool?)MainVariant.ProductFieldValues.Where(o => o.ProductField.SystemName == "ProductToBeDiscontinued").SingleOrDefault()?.Value ?? false) 485 { 486 if (MainvariantStock > 0) 487 { 488 if (MainisNew == "true" || MainIsSale == "true") 489 { 490 if (MainIsSale == "true") 491 { 492 MainstockState += MainIsSaleSvg + "&nbsp; &nbsp;" + Translate("Sale!") + "<br/>"; 493 } 494 495 if (MainisNew == "true") 496 { 497 MainstockState += MainisNewSvg + "&nbsp; &nbsp;" + Translate("New!") + "<br/>"; 498 } 499 500 MainstockState += "&nbsp;" + Translate("Nu leverbaar"); 501 } 502 else 503 { 504 MainstockState = MainsvgInStock + "&nbsp; " + Translate("Op voorraad"); 505 506 } 507 } 508 else 509 { 510 MainstockState = MainsvgOutStock + "&nbsp;" + Translate("Geen voorraad") + "<br/>" + MainexpectedDeliveryDateText; 511 512 } 513 } 514 else 515 { 516 517 MainstockState = MainsvgOutStock + "&nbsp;" + Translate("Discontinued:") + "<br/>" + MainvariantStock + "&nbsp;" + @Translate("left in stock"); 518 519 } 520 /*End stock state*/ 521 522 523 @MainstockState 524 525 526 } 527 </div> 528 } 529 else 530 { 531 <div class="stock-state pt-2 mt-auto"> 532 @MainOutStock @Translate("Discontinued") 533 </div> 534 } 535 <div class="custom-price mt-auto"> 536 @{ 537 538 539 540 541 bool isErpConnectionDown = !Dynamicweb.Core.Converter.ToBoolean(Dynamicweb.Context.Current.Items["IsWebServiceConnectionAvailable"]); 542 bool hidePrice = anonymousUsersLimitations.Contains("price") && anonymousUser || Pageview.AreaSettings.GetBoolean("ErpDownHidePrices") && isErpConnectionDown; 543 544 bool productIsDiscontinued = product is object && product.Discontinued; 545 bool doNotShowPriceIfProductIsDiscontinued = Model.Item.GetBoolean("DoNotShowPriceIfProductIsDiscontinued"); 546 var isDiscontinued = productIsDiscontinued && doNotShowPriceIfProductIsDiscontinued; 547 } 548 549 @if (product is object && !hidePrice && !isDiscontinued) 550 { 551 string unitId = !string.IsNullOrEmpty(Dynamicweb.Context.Current.Request.Form.Get("UnitId")) ? Dynamicweb.Context.Current.Request.Form.Get("UnitId") : string.Empty; 552 553 string priceFontSize = Model.Item.GetRawValueString("PriceSize", "fs-4"); 554 string horizontalAlign = Model.Item.GetRawValueString("HorizontalAlignment", ""); 555 string layout = Model.Item.GetRawValueString("Layout", "horizontal"); 556 string textAlign = horizontalAlign == "center" ? "text-center" : string.Empty; 557 textAlign = horizontalAlign == "end" ? "text-end" : textAlign; 558 559 horizontalAlign = horizontalAlign == "center" && layout == "horizontal" ? "justify-content-center" : horizontalAlign; 560 horizontalAlign = horizontalAlign == "end" && layout == "horizontal" ? "justify-content-end" : horizontalAlign; 561 horizontalAlign = horizontalAlign == "center" && layout == "vertical" ? "align-items-center" : horizontalAlign; 562 horizontalAlign = horizontalAlign == "end" && layout == "vertical" ? "align-items-end" : horizontalAlign; 563 564 string flexDirection = layout == "horizontal" ? string.Empty : "flex-column"; 565 string flexGap = layout == "horizontal" ? "gap-3" : string.Empty; 566 string order = layout == "horizontal" ? string.Empty : "order-2"; 567 568 569 string contentPadding = Model.Item.GetRawValueString("ContentPadding", ""); 570 contentPadding = contentPadding == "none" ? "p-0" : contentPadding; 571 contentPadding = contentPadding == "small" ? "p-1 px-md-2 py-md-1" : contentPadding; 572 contentPadding = contentPadding == "large" ? "p-2 px-md-3 py-md-2" : contentPadding; 573 string liveInfoClass = ""; 574 575 576 577 578 579 580 if (isLazyLoadingForProductInfoEnabled) 581 { 582 if (Dynamicweb.Context.Current.Items.Contains("ProductInfoFeed")) 583 { 584 productInfoFeed = Dynamicweb.Context.Current.Items["ProductInfoFeed"]?.ToString(); 585 if (!string.IsNullOrEmpty(productInfoFeed)) 586 { 587 productInfoFeed = $"data-product-info-feed=\"{productInfoFeed}\""; 588 } 589 } 590 liveInfoClass = "js-live-info"; 591 } 592 593 <div class="@textAlign @liveInfoClass item_@Model.Item.SystemName.ToLower()" data-product-id="@product.Id" data-variant-id="@product.VariantId" @productInfoFeed> 594 @if (showInformativePrice && product.PriceInformative.Price != 0) 595 { 596 <div class="opacity-50"> 597 <span>@Translate("RRP") </span> 598 <span class="text-decoration-line-through text-price">@product.PriceInformative.PriceFormatted</span> 599 </div> 600 } 601 <div class="@priceFontSize m-0 d-flex flex-wrap @flexDirection @flexGap @horizontalAlign" style="row-gap: 0 !important" itemprop="offers" itemscope itemtype="https://schema.org/Offer"> 602 <span itemprop="priceCurrency" content="@product.Price.CurrencyCode" class="d-none"></span> 603 604 605 @if (showPricesWithVat == "false" && !neverShowVat) 606 { 607 if (isLazyLoadingForProductInfoEnabled && !Pageview.IsVisualEditorMode) 608 { 609 <span itemprop="price" content="" class="d-none"></span> 610 <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> 611 } 612 else 613 { 614 string beforePrice = !string.IsNullOrEmpty(unitId) ? product.GetPrice(unitId).PriceBeforeDiscount.PriceWithoutVatFormatted : product.PriceBeforeDiscount.PriceWithoutVatFormatted; 615 616 <span itemprop="price" content="@product.Price.PriceWithoutVat.ToString("0.00", System.Globalization.CultureInfo.InvariantCulture)" class="d-none"></span> 617 if (product.Price.Price != product.PriceBeforeDiscount.Price) 618 { 619 <span class="text-decoration-line-through opacity-75 @order">@beforePrice</span> 620 } 621 } 622 } 623 else 624 { 625 if (isLazyLoadingForProductInfoEnabled && !Pageview.IsVisualEditorMode) 626 { 627 <span itemprop="price" content="" class="d-none"></span> 628 <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> 629 } 630 else 631 { 632 string beforePrice = !string.IsNullOrEmpty(unitId) ? product.GetPrice(unitId).PriceBeforeDiscount.PriceFormatted : product.PriceBeforeDiscount.PriceFormatted; 633 634 <span itemprop="price" content="@product.Price.Price.ToString("0.00", System.Globalization.CultureInfo.InvariantCulture)" class="d-none"></span> 635 636 if (product.Price.Price != product.PriceBeforeDiscount.Price) 637 { 638 <span class="text-decoration-line-through opacity-75 @order"> 639 <span class="text-price">@beforePrice</span> 640 </span> 641 } 642 } 643 } 644 645 @if (showPricesWithVat == "false" && !neverShowVat) 646 { 647 if (isLazyLoadingForProductInfoEnabled && !Pageview.IsVisualEditorMode) 648 { 649 <span class="text-price js-text-price"> 650 <span class="spinner-border" role="status"></span> 651 </span> 652 } 653 else 654 { 655 string price = !string.IsNullOrEmpty(unitId) ? product.GetPrice(unitId).Price.PriceWithoutVatFormatted : product.Price.PriceWithoutVatFormatted; 656 657 if (product?.VariantInfo?.VariantInfo != null) 658 { 659 priceMin = product?.VariantInfo?.PriceMin?.PriceWithoutVatFormatted != null ? product.VariantInfo.PriceMin.PriceWithoutVatFormatted : ""; 660 priceMax = product?.VariantInfo?.PriceMax?.PriceWithoutVatFormatted != null ? product.VariantInfo.PriceMax.PriceWithoutVatFormatted : ""; 661 } 662 if (priceMin != priceMax) 663 { 664 price = priceMin + " - " + priceMax; 665 } 666 <span class="@theme @contentPadding"> 667 <span class="text-price">@price</span> 668 </span> 669 } 670 } 671 else 672 { 673 if (isLazyLoadingForProductInfoEnabled && !Pageview.IsVisualEditorMode) 674 { 675 <span class="text-price js-text-price"> 676 <span class="spinner-border" role="status"></span> 677 </span> 678 } 679 else 680 { 681 string price = !string.IsNullOrEmpty(unitId) ? product.GetPrice(unitId).Price.PriceFormatted : product.Price.PriceFormatted; 682 683 if (product?.VariantInfo?.VariantInfo != null) 684 { 685 priceMin = product?.VariantInfo?.PriceMin?.PriceFormatted != null ? product.VariantInfo.PriceMin.PriceFormatted : ""; 686 priceMax = product?.VariantInfo?.PriceMax?.PriceFormatted != null ? product.VariantInfo.PriceMax.PriceFormatted : ""; 687 } 688 if (priceMin != priceMax) 689 { 690 price = priceMin + " - " + priceMax; 691 } 692 <span class="@theme @contentPadding"> 693 <span class="text-price">@price</span> 694 </span> 695 } 696 } 697 698 @* Stock state for Schema.org, start *@ 699 @{ 700 Uri url = Dynamicweb.Context.Current.Request.Url; 701 } 702 703 <link itemprop="url" href="@url"> 704 705 @{ 706 bool IsNeverOutOfStock = product.NeverOutOfstock; 707 } 708 709 @if (IsNeverOutOfStock) 710 { 711 <span itemprop="availability" class="d-none">@Translate("Available in stock")</span> 712 } 713 else 714 { 715 if (product.StockLevel > 0) 716 { 717 <span itemprop="availability" class="d-none">InStock</span> 718 } 719 else 720 { 721 <span itemprop="availability" class="d-none">OutOfStock</span> 722 } 723 } 724 @* Stock state for Schema.org, stop *@ 725 726 </div> 727 728 @if (showPricesWithVat == "false" && !neverShowVat) 729 { 730 if (isLazyLoadingForProductInfoEnabled && !Pageview.IsVisualEditorMode) 731 { 732 <small class="opacity-85 fst-normal js-text-price-with-vat d-none" data-suffix="@Translate("Incl. VAT")"></small> 733 } 734 else 735 { 736 string price = !string.IsNullOrEmpty(unitId) ? product.GetPrice(unitId).Price.PriceWithVatFormatted : product.Price.PriceWithVatFormatted; 737 738 if (product?.VariantInfo?.VariantInfo != null) 739 { 740 priceMin = product?.VariantInfo?.PriceMin?.PriceWithVatFormatted != null ? product.VariantInfo.PriceMin.PriceWithVatFormatted : ""; 741 priceMax = product?.VariantInfo?.PriceMax?.PriceWithVatFormatted != null ? product.VariantInfo.PriceMax.PriceWithVatFormatted : ""; 742 } 743 if (priceMin != priceMax) 744 { 745 price = priceMin + " - " + priceMax; 746 } 747 <!-- <small class="opacity-85 fst-normal">@price @Translate("Incl. VAT")</small> --> 748 } 749 } 750 </div> 751 } 752 else if (Pageview.IsVisualEditorMode) 753 { 754 <div class="alert alert-dark m-0" role="alert"> 755 <span>@Translate("No products available")</span> 756 </div> 757 } 758 759 </div> 760 } 761 } 762
Tischlampe Ø22 Korb
Error executing template "Designs/Swift/Paragraph/CustomProductSlider.cshtml"
System.NullReferenceException: Object reference not set to an instance of an object.
   at CompiledRazorTemplates.Dynamic.RazorEngine_3562354021b44d5c892fe73dc2806e4f.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 Dynamicweb.Ecommerce.ProductCatalog 3 @using Dynamicweb.Ecommerce.CustomerExperienceCenter.Favorites 4 @using Dynamicweb.Files 5 @using System.IO 6 @using System.Net 7 @using Dynamicweb.Security.UserManagement 8 9 10 @{ 11 ProductViewModel product = null; 12 if (Dynamicweb.Context.Current.Items.Contains("ProductDetails")) 13 { 14 product = (ProductViewModel)Dynamicweb.Context.Current.Items["ProductDetails"]; 15 } 16 else if (Pageview.Page.Item["DummyProduct"] != null && Pageview.IsVisualEditorMode) 17 { 18 var pageViewModel = Dynamicweb.Frontend.ContentViewModelFactory.CreatePageInfoViewModel(Pageview.Page); 19 ProductListViewModel productList = pageViewModel.Item.GetValue("DummyProduct") != null ? pageViewModel.Item.GetValue("DummyProduct") as ProductListViewModel : new ProductListViewModel(); 20 21 if (productList?.Products is object) 22 { 23 product = productList.Products[0]; 24 } 25 } 26 } 27 28 @{ 29 var currentUser = Pageview?.User; 30 var customerNumber = !string.IsNullOrEmpty(currentUser?.CustomerNumber) 31 ? currentUser.CustomerNumber 32 : ""; 33 } 34 @if (product is object) 35 { 36 string imagePath = product?.DefaultImage?.Value ?? ""; 37 string imagePathUrlEncoded = Dynamicweb.Context.Current.Server.UrlEncode(imagePath); 38 39 string ratio = Model.Item.GetRawValueString("ImageAspectRatio", ""); 40 ratio = ratio != "0" ? ratio : ""; 41 string ratioCssClass = ratio != "" ? " ratio" : ""; 42 string ratioVariable = ratio != "" ? "--bs-aspect-ratio: " + ratio + ";" : ""; 43 44 string width = Model.Item.GetRawValueString("Width", "auto"); 45 int smallImageSize = 640; 46 int largeImageSize = width == "auto" ? 1280 : Convert.ToInt32(width); 47 48 string ImageObjectFit = Model.Item.GetRawValueString("ImageObjectFit", "contain"); 49 50 string imagePathXs = "/Admin/Public/GetImage.ashx?width=" + smallImageSize + "&image=" + imagePathUrlEncoded + "&format=webp"; 51 string imagePathS = "/Admin/Public/GetImage.ashx?width=" + largeImageSize + "&image=" + imagePathUrlEncoded + "&format=webp"; 52 string imagePathFallBack = "/Admin/Public/GetImage.ashx?width=" + largeImageSize + "&image=" + imagePathUrlEncoded + "&format=webp"; 53 54 var badgeParms = new Dictionary<string, object>(); 55 badgeParms.Add("size", "h7"); 56 badgeParms.Add("saleBadgeType", Model.Item.GetRawValue("SaleBadgeType")); 57 badgeParms.Add("saleBadgeCssClassName", Model.Item.GetRawValue("SaleBadgeDesign")); 58 badgeParms.Add("newBadgeCssClassName", Model.Item.GetRawValue("NewBadgeDesign")); 59 badgeParms.Add("newPublicationDays", Model.Item.GetInt32("NewPublicationDays")); 60 badgeParms.Add("campaignBadgesValues", Model.Item.GetList("CampaignBadges")?.GetRawValue().OfType<string>().ToList()); 61 62 string badgeSize = Model.Item.GetRawValueString("BadgeSize", "fs-2"); 63 bool saleBadgeEnabled = !string.IsNullOrWhiteSpace(Model.Item.GetRawValueString("SaleBadgeDesign")) && Model.Item.GetRawValueString("SaleBadgeDesign") != "none" ? true : false; 64 bool newBadgeEnabled = !string.IsNullOrWhiteSpace(Model.Item.GetRawValueString("NewBadgeDesign")) && Model.Item.GetRawValueString("NewBadgeDesign") != "none" ? true : false; 65 66 /*Custom badge*/ 67 var productService = new Dynamicweb.Ecommerce.Products.ProductService(); 68 var currency = Dynamicweb.Ecommerce.Common.Context.Currency.Code; 69 var formatProvider = new System.Globalization.NumberFormatInfo(); 70 formatProvider.NumberDecimalSeparator = "."; 71 formatProvider.NumberGroupSeparator = ","; 72 var MainVariant = productService.GetProductById(product.Id, product.VariantId, false); 73 var fieldValueBlocked = MainVariant?.ProductFieldValues?.GetProductFieldValue("BlockedCustomerList")?.Value; 74 75 76 string isNewProduct = MainVariant?.ProductFieldValues?.GetProductFieldValue("New")?.Value?.ToString().ToLower() ?? ""; 77 string MainisSale = MainVariant?.ProductFieldValues?.GetProductFieldValue("Sale")?.Value?.ToString().ToLower() ?? ""; 78 bool showNewBadge = isNewProduct == "true" ? true : false; 79 bool showSaleBadge = MainisSale == "true" ? true : false; 80 string showNewSaleBadge = "d-none"; 81 if (showSaleBadge) 82 { 83 badgeParms.Add("isSale", "true"); 84 85 } 86 else 87 { 88 badgeParms.Add("isSale", "false"); 89 } 90 if (showNewBadge) 91 { 92 badgeParms.Add("isNew", "true"); 93 } 94 else 95 { 96 badgeParms.Add("isNew", "false"); 97 } 98 /*End Custom badge*/ 99 if (showSaleBadge || showNewBadge) 100 { 101 showNewSaleBadge = ""; 102 } 103 DateTime createdDate = product.Created.Value; 104 bool showBadges = saleBadgeEnabled && product.Discount.Price != 0 ? true : false; 105 106 bool showFavoritesSelector = !string.IsNullOrEmpty(Model.Item.GetString("ShowAddToFavorites")) ? Model.Item.GetBoolean("ShowAddToFavorites") : false; 107 string anonymousUsersLimitations = Pageview.AreaSettings.GetRawValueString("AnonymousUsers", ""); 108 bool anonymousUser = Pageview.User == null; 109 110 var favoriteParameters = new Dictionary<string, object>(); 111 if (!anonymousUser && showFavoritesSelector) 112 { 113 int defaultFavoriteListId = 0; 114 115 IEnumerable<FavoriteList> favoreiteLists = Pageview.User.GetFavoriteLists(); 116 if (favoreiteLists.Count() == 1) 117 { 118 foreach (FavoriteList list in favoreiteLists) 119 { 120 defaultFavoriteListId = list.ListId; 121 } 122 } 123 124 favoriteParameters.Add("ListId", defaultFavoriteListId); 125 } 126 127 MediaViewModel alternativeImage = new MediaViewModel(); 128 if (Model.Item.GetBoolean("ShowAlternativeImageOnHover")) 129 { 130 var selectedImageCategories = Model.Item.GetList("GetAlternativeImageFrom")?.GetRawValue().OfType<string>().ToList(); 131 List<MediaViewModel> allAssetsImages = product.AssetCategories.Where(x => selectedImageCategories.Contains(x.SystemName)).SelectMany(x => x.Assets).ToList(); 132 allAssetsImages.RemoveAll(x => x.Value == product.DefaultImage.Value); 133 alternativeImage = allAssetsImages.FirstOrDefault(); 134 } 135 136 string altImagePathXs = string.Empty; 137 string altImagePathS = string.Empty; 138 139 if (!string.IsNullOrEmpty(alternativeImage?.Value)) 140 { 141 altImagePathXs = "/Admin/Public/GetImage.ashx?width=" + smallImageSize + "&image=" + Dynamicweb.Context.Current.Server.UrlEncode(alternativeImage.Value) + "&format=webp"; 142 altImagePathS = "/Admin/Public/GetImage.ashx?width=" + largeImageSize + "&image=" + Dynamicweb.Context.Current.Server.UrlEncode(alternativeImage.Value) + "&format=webp"; 143 } 144 145 @* Theme settings *@ 146 string theme = !string.IsNullOrWhiteSpace(Model.Item.GetRawValueString("Theme")) ? " theme " + Model.Item.GetRawValueString("Theme").Replace(" ", "").Trim().ToLower() : ""; 147 string themeBorder = !string.IsNullOrWhiteSpace(theme) ? "border: 1px solid rgba(0,0,0,0)" : ""; 148 string themePadding = !string.IsNullOrWhiteSpace(theme) ? "p-2 p-lg-3" : ""; 149 150 string imageId = "ProductImage_" + product.Id; 151 152 153 154 string fullWidth = width == "auto" ? "w-100" : ""; 155 string customWidth = width != "auto" ? "style=\"width: " + width + "px\"" : "style=\"min-width: 60px\""; 156 157 string altImageZindex = Model.Item.GetBoolean("ShowAlternativeImageOnHover") && !string.IsNullOrEmpty(alternativeImage?.Value) ? " z-index: 1" : string.Empty; 158 string groupid = !string.IsNullOrEmpty(Dynamicweb.Context.Current.Request.QueryString.Get("GroupID")) ? Dynamicweb.Context.Current.Request.QueryString.Get("GroupID"):"" ; 159 string link = product.GetProductLink(GetPageIdByNavigationTag("Shop"), false); 160 var productVariantGroups = product.VariantGroups(); 161 string MainOutStock = "<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"25\" height=\"25\" fill=\"#CA0D0D\" class=\"bi bi-x-lg\" viewBox=\"0 0 16 16\"><path d=\"M4.646 4.646a.5.5 0 0 1 .708 0L8 7.293l2.646-2.647a.5.5 0 0 1 .708.708L8.707 8l2.647 2.646a.5.5 0 0 1-.708.708L8 8.707l-2.646 2.647a.5.5 0 0 1-.708-.708L7.293 8 4.646 5.354a.5.5 0 0 1 0-.708\"/></svg>"; 162 163 @if (!string.IsNullOrEmpty(imagePath)) 164 { 165 <div class="@fullWidth @theme position-relative item_@Model.Item.SystemName.ToLower() main-image-container" @customWidth> 166 <div class="" style="@(ratioVariable)@(altImageZindex)"> 167 <div class="d-flex justify-content-center align-items-center"> 168 <a class="main-link-link" href="@link"> 169 @if (imagePath.StartsWith("/Files/", StringComparison.OrdinalIgnoreCase)) 170 { 171 <img id="@imageId" 172 srcset=" 173 @imagePathXs @(smallImageSize)w, 174 @imagePathS @(largeImageSize)w" 175 sizes="(max-width: 992px) 50vw, 25vw" 176 src="@imagePathFallBack" 177 loading="lazy" 178 decoding="async" 179 class="h-100 w-100 @themePadding main-image" 180 style="object-fit: @ImageObjectFit; @themeBorder " 181 alt="@product.Name" 182 itemprop="image"> 183 } 184 else 185 { 186 <img src="@product.DefaultImage.Value" 187 loading="lazy" 188 class="h-100 w-100 @themePadding main-image" 189 style="object-fit: contain; @themeBorder" 190 alt="@product.Name" 191 itemprop="image"> 192 } 193 </a> 194 </div> 195 </div> 196 197 <div class="position-absolute top-0 left-0 p-2 pb-0 custom-badge-product-list @showNewSaleBadge"> 198 @{ 199 @RenderPartial("Components/Custom_EcommerceBadge.cshtml", product, badgeParms) 200 } 201 </div> 202 203 204 </div> 205 } 206 207 <div class="product-info h-100"> 208 <div class="fs-7 pt-1 opacity-85 start item_@Model.Item.SystemName.ToLower() product-number" itemprop="sku">@product.Id / @product.VariantId - @product.VariantName</div> 209 <div class="py-2" data-col-size="12"> 210 <h2 class="h6 start m-0 item_swift_productheader product-name" itemprop="name"><b>@product.Name</b></h2> 211 </div> 212 </div> 213 var sliderId = $"thumb-scroll-{product.Id}"; 214 if (productVariantGroups.Any() && product?.VariantInfo?.VariantInfo != null) 215 216 { 217 @using Dynamicweb.Ecommerce.Prices 218 @{ 219 string[] variantId = product.VariantId.Split('.'); 220 string showPricesWithVat = Pageview.Area.EcomPricesWithVat.ToLower(); 221 bool neverShowVat = string.IsNullOrEmpty(showPricesWithVat); 222 bool showInformativePrice = Model.Item.GetBoolean("ShowInformativePrice"); 223 string productInfoFeed = ""; 224 bool isLazyLoadingForProductInfoEnabled = Dynamicweb.Core.Converter.ToBoolean(Dynamicweb.Context.Current.Items["IsLazyLoadingForProductInfoEnabled"]); 225 if (isLazyLoadingForProductInfoEnabled) 226 { 227 if (Dynamicweb.Context.Current.Items.Contains("ProductInfoFeed")) 228 { 229 productInfoFeed = Dynamicweb.Context.Current.Items["ProductInfoFeed"]?.ToString(); 230 if (!string.IsNullOrEmpty(productInfoFeed)) 231 { 232 productInfoFeed =productInfoFeed; 233 } 234 } 235 236 } 237 string priceMin = ""; 238 string priceMax = ""; 239 int groupNumber = 1; 240 241 242 243 244 string baseUrl = $"Default.aspx?ID={GetPageIdByNavigationTag("Shop")}&GroupID={product.PrimaryOrDefaultGroup.Id}&ProductID={product.Id}"; 245 if (!string.IsNullOrEmpty(baseUrl)) 246 { 247 baseUrl = $"/{baseUrl.TrimStart('/')}"; 248 } 249 string variantUrl = string.Empty; 250 251 252 Dictionary<string, string> 253 variantImages = new Dictionary<string, string> 254 (); 255 <div class="last-row mt-auto"> 256 257 @foreach (var variantGroup in productVariantGroups) 258 { 259 <div class="thumbnail-wrapper"> 260 <button class="thumb-nav prev" onclick="scrollThumbs('@sliderId', -1)"> 261 <svg width="20px" height="20px" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" fill="#1D98A5"> 262 263 <g stroke="none" stroke-width="1" fill="none" fill-rule="evenodd"> 264 <g transform="translate(-336.000000, 0.000000)"> 265 <g id="left_line" transform="translate(336.000000, 0.000000)"> 266 <path d="M24,0 L24,24 L0,24 L0,0 L24,0 Z M12.5934901,23.257841 L12.5819402,23.2595131 L12.5108777,23.2950439 L12.4918791,23.2987469 L12.4918791,23.2987469 L12.4767152,23.2950439 L12.4056548,23.2595131 C12.3958229,23.2563662 12.3870493,23.2590235 12.3821421,23.2649074 L12.3780323,23.275831 L12.360941,23.7031097 L12.3658947,23.7234994 L12.3769048,23.7357139 L12.4804777,23.8096931 L12.4953491,23.8136134 L12.4953491,23.8136134 L12.5071152,23.8096931 L12.6106902,23.7357139 L12.6232938,23.7196733 L12.6232938,23.7196733 L12.6266527,23.7031097 L12.609561,23.275831 C12.6075724,23.2657013 12.6010112,23.2592993 12.5934901,23.257841 L12.5934901,23.257841 Z M12.8583906,23.1452862 L12.8445485,23.1473072 L12.6598443,23.2396597 L12.6498822,23.2499052 L12.6498822,23.2499052 L12.6471943,23.2611114 L12.6650943,23.6906389 L12.6699349,23.7034178 L12.6699349,23.7034178 L12.678386,23.7104931 L12.8793402,23.8032389 C12.8914285,23.8068999 12.9022333,23.8029875 12.9078286,23.7952264 L12.9118235,23.7811639 L12.8776777,23.1665331 C12.8752882,23.1545897 12.8674102,23.1470016 12.8583906,23.1452862 L12.8583906,23.1452862 Z M12.1430473,23.1473072 C12.1332178,23.1423925 12.1221763,23.1452606 12.1156365,23.1525954 L12.1099173,23.1665331 L12.0757714,23.7811639 C12.0751323,23.7926639 12.0828099,23.8018602 12.0926481,23.8045676 L12.108256,23.8032389 L12.3092106,23.7104931 L12.3186497,23.7024347 L12.3186497,23.7024347 L12.3225043,23.6906389 L12.340401,23.2611114 L12.337245,23.2485176 L12.337245,23.2485176 L12.3277531,23.2396597 L12.1430473,23.1473072 Z" id="MingCute" fill-rule="nonzero"> </path> 267 <path d="M8.29292,12.7071 C7.9024,12.3166 7.9024,11.6834 8.29292,11.2929 L13.9498,5.63604 C14.3403,5.24551 14.9735,5.24551 15.364,5.63604 C15.7545,6.02656 15.7545,6.65973 15.364,7.05025 L10.4142,12 L15.364,16.9497 C15.7545,17.3403 15.7545,17.9734 15.364,18.364 C14.9735,18.7545 14.3403,18.7545 13.9498,18.364 L8.29292,12.7071 Z" id="路径" fill="#1D98A5"> </path> 268 </g> 269 </g> 270 </g> 271 </svg> 272 273 </button> 274 <div class="thumbnail-scroll" id="@sliderId"> 275 @{ 276 VariantGroupViewModel group = variantGroup; 277 foreach (var option in group.Options.OrderBy(o => o.Id)) 278 { 279 var productVariant = productService.GetProductById(product.Id, option.Id, false); 280 281 var productSelection = new PriceProductSelection(productVariant, null, 0); 282 283 var currencyCode = string.IsNullOrWhiteSpace(Pageview.User.Currency) ? Pageview.Area.EcomCurrencyId : Pageview.User.Currency; 284 var countryCode = string.IsNullOrWhiteSpace(Pageview.User.CountryCode) ? Pageview.Area.EcomCountryCode : Pageview.User.CountryCode; 285 286 var userCurrency = Dynamicweb.Ecommerce.Services.Currencies.GetCurrency(currencyCode); 287 var userCountry = Dynamicweb.Ecommerce.Services.Countries.GetCountry(countryCode); 288 289 var priceContext = new PriceContext(userCurrency, userCountry, null, Pageview.User, false, null); 290 var productPrice = Dynamicweb.Ecommerce.Services.Prices.FindPrices(priceContext, productSelection, false); 291 292 //throw new Exception(System.Text.Json.JsonSerializer.Serialize(productPrice)); 293 294 var fieldValue = productVariant?.ProductFieldValues?.GetProductFieldValue("BlockedCustomerList")?.Value; 295 296 if ((fieldValue != null && !fieldValue.ToString().Contains(customerNumber)) || String.IsNullOrWhiteSpace(customerNumber)) 297 { 298 299 300 string active = variantId != null && variantId.Contains(option.Id) ? "active" : string.Empty; 301 string buttonId = $"{product.Id}_{option.Id}_{Pageview.CurrentParagraph.ID}"; 302 string contrastColor = string.Empty; 303 304 string searchKey = $"{product.Id}_{option.Id}_"; 305 /*Images*/ 306 var imagePathVariant = option.Image?.Value ?? ""; 307 308 309 var folderPath = Path.GetDirectoryName(imagePathVariant); 310 311 string physicalFolderPath = Dynamicweb.Context.Current.Server.MapPath(folderPath); 312 313 string lastImage = null; 314 315 if (Directory.Exists(physicalFolderPath)) 316 { 317 318 var fileWith15 = Directory.GetFiles(physicalFolderPath) 319 .FirstOrDefault(f => Path.GetFileName(f).Contains($"{product.Id}_{option.Id}_9")); 320 321 if (fileWith15 != null) 322 { 323 lastImage = fileWith15; 324 } 325 else 326 { 327 var files = Directory.GetFiles(physicalFolderPath) 328 .Where(f => Path.GetFileName(f).StartsWith($"{product.Id}_{option.Id}_")) 329 .OrderByDescending(f => 330 { 331 var filename = Path.GetFileNameWithoutExtension(f); 332 var match = System.Text.RegularExpressions.Regex.Match(filename, @"_(\d+)$"); 333 if (match.Success && int.TryParse(match.Groups[1].Value, out int index)) 334 { 335 return index; 336 } 337 return 0; 338 }) 339 .ToList(); 340 341 if (files.Any()) 342 { 343 lastImage = files.First(); 344 } 345 } 346 } 347 348 var lastImageUrl = lastImage != null ? lastImage : "/Files/Images/zijlstra/Afbeeldingen_overig/Coming_Soon.jpg"; 349 int index = lastImageUrl.IndexOf("Files"); 350 string relativePath = index >= 0 ? lastImageUrl.Substring(index).Replace("\\", "/") : lastImageUrl.Replace("\\", "/"); 351 lastImageUrl = "/" + relativePath; 352 lastImageUrl = Dynamicweb.Context.Current.Server.UrlEncode(lastImageUrl); 353 var variantImg = option.Image is object ? Dynamicweb.Context.Current.Server.UrlEncode(option.Image.Value) : null; 354 var variantLink = "/Default.aspx?ID=" + GetPageIdByNavigationTag("Shop") + "&GroupID=" + product.PrimaryOrDefaultGroup.Id + "&ProductID=" + product.Id + "&VariantID=" + option.Id; 355 356 string variantImage = string.Empty; 357 variantImages.TryGetValue(option.Id, out variantImage); 358 /*End Images*/ 359 360 /*stock state*/ 361 double variantStock = productVariant.Stock; 362 string svgInStock = "<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"16\" height=\"16\" fill=\"#44B11A\" class=\"bi bi-check-lg\" viewBox=\"0 0 16 16\"><path d=\"M12.736 3.97a.733.733 0 0 1 1.047 0c.286.289.29.756.01 1.05L7.88 12.01a.733.733 0 0 1-1.065.02L3.217 8.384a.757.757 0 0 1 0-1.06.733.733 0 0 1 1.047 0l3.052 3.093 5.4-6.425z\"/></svg>"; 363 string svgOutStock = "<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"25\" height=\"25\" fill=\"#CA0D0D\" class=\"bi bi-x-lg\" viewBox=\"0 0 16 16\"><path d=\"M4.646 4.646a.5.5 0 0 1 .708 0L8 7.293l2.646-2.647a.5.5 0 0 1 .708.708L8.707 8l2.647 2.646a.5.5 0 0 1-.708.708L8 8.707l-2.646 2.647a.5.5 0 0 1-.708-.708L7.293 8 4.646 5.354a.5.5 0 0 1 0-.708\"/></svg>"; 364 365 string infoStock = "<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"16\" height=\"16\" fill=\"currentColor\" class=\"bi bi-info-circle-fill\" viewBox=\"0 0 16 16\"><path d=\"M8 16A8 8 0 1 0 8 0a8 8 0 0 0 0 16m.93-9.412-1 4.705c-.07.34.029.533.304.533.194 0 .487-.07.686-.246l-.088.416c-.287.346-.92.598-1.465.598-.703 0-1.002-.422-.808-1.319l.738-3.468c.064-.293.006-.399-.287-.47l-.451-.081.082-.381 2.29-.287zM8 5.5a1 1 0 1 1 0-2 1 1 0 0 1 0 2\" /></svg>"; 366 string isNew = productVariant?.ProductFieldValues?.GetProductFieldValue("New")?.Value?.ToString().ToLower() ?? ""; 367 string isNewSvg = "<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"16\" height=\"16\" fill=\"#F2C400\" class=\"bi bi-star-fill\" viewBox=\"0 0 16 16\"><path d = \"M3.612 15.443c-.386.198-.824-.149-.746-.592l.83-4.73L.173 6.765c-.329-.314-.158-.888.283-.95l4.898-.696L7.538.792c.197-.39.73-.39.927 0l2.184 4.327 4.898.696c.441.062.612.636.282.95l-3.522 3.356.83 4.73c.078.443-.36.79-.746.592L8 13.187l-4.389 2.256z\" /></svg> "; 368 string stockState = ""; 369 370 string isSale = productVariant?.ProductFieldValues?.GetProductFieldValue("Sale")?.Value?.ToString().ToLower() ?? ""; 371 string isSaleSvg = "<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"16\" height=\"16\" fill=\"#F03232\" class=\"bi bi-star-fill\" viewBox=\"0 0 16 16\"><path d = \"M3.612 15.443c-.386.198-.824-.149-.746-.592l.83-4.73L.173 6.765c-.329-.314-.158-.888.283-.95l4.898-.696L7.538.792c.197-.39.73-.39.927 0l2.184 4.327 4.898.696c.441.062.612.636.282.95l-3.522 3.356.83 4.73c.078.443-.36.79-.746.592L8 13.187l-4.389 2.256z\" /></svg> "; 372 373 string expectedDeliveryDate = ""; 374 375 if (DateTime.Compare(productVariant.ExpectedDelivery, new DateTime(1900, 1, 1)) != 0) //In DW, if the Date is not set, it is defaulted 01-01-1900 and not null.. 376 { 377 expectedDeliveryDate = productVariant.ExpectedDelivery.ToShortDateString(); 378 } 379 380 string expectedDeliveryDateText = !String.IsNullOrWhiteSpace(expectedDeliveryDate) ? Translate("Verwacht:") + "&nbsp;" + expectedDeliveryDate : ""; 381 382 @if (!(bool?)productVariant.ProductFieldValues.Where(o => o.ProductField.SystemName == "ProductToBeDiscontinued").SingleOrDefault()?.Value ?? false) 383 { 384 if (variantStock > 0) 385 { 386 if (isNew == "true" || isSale == "true") 387 { 388 if (isSale == "true") 389 { 390 stockState += isSaleSvg + "&nbsp; &nbsp;" + Translate("Sale!") + "<br/>"; 391 } 392 393 if (isNew == "true") 394 { 395 stockState += isNewSvg + "&nbsp; &nbsp;" + Translate("New!") + "<br/>"; 396 } 397 398 stockState += "&nbsp;" + Translate("Nu leverbaar"); 399 } 400 else 401 { 402 stockState = svgInStock + "&nbsp; " + Translate("Op voorraad"); 403 404 } 405 } 406 else 407 { 408 stockState = svgOutStock + "&nbsp;" + Translate("Geen voorraad") + "<br/>" + expectedDeliveryDateText; 409 410 } 411 } 412 else 413 { 414 415 stockState = svgOutStock + "&nbsp;" + Translate("Discontinued:") + "<br/>" + variantStock + "&nbsp;" + @Translate("left in stock"); 416 417 } 418 /*End stock state*/ 419 /*Price variants*/ 420 double price = productVariant.DefaultPrice; 421 double cost = productVariant.Cost; 422 423 string priceFormated = Dynamicweb.Ecommerce.Services.Currencies.Format(Dynamicweb.Ecommerce.Services.Currencies.GetCurrency(currency), Convert.ToDouble(productPrice.ToList()[0].Amount, formatProvider)); 424 //string priceFormated = Dynamicweb.Ecommerce.Services.Currencies.Format(Dynamicweb.Ecommerce.Services.Currencies.GetCurrency(currency), Convert.ToDouble(price, formatProvider)); 425 426 427 428 /*End Price variants*/ 429 430 <img class="theme thumbnail" data-stockstate="@WebUtility.HtmlEncode(stockState)" src="/Admin/Public/GetImage.ashx?image=@(lastImageUrl)&width=64&format=webp" onclick="selectVariant('@(product.Id)','/Admin/Public/GetImage.ashx?image=@(variantImg)&format=webp','@variantLink','@product.Id','@option.Id','@option.Name',this.dataset.stockstate,'@isNew','@isSale','@priceFormated','@cost')" /> 431 432 433 } 434 } 435 436 } 437 </div> 438 <button class="thumb-nav next" onclick="scrollThumbs('@sliderId', 1)"> 439 <svg width="20px" height="20px" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" fill="#1D98A5"> 440 441 <g stroke="none" stroke-width="1" fill="none" fill-rule="evenodd"> 442 <g transform="translate(-384.000000, 0.000000)"> 443 <g id="right_line" transform="translate(384.000000, 0.000000)"> 444 <path d="M24,0 L24,24 L0,24 L0,0 L24,0 Z M12.5934901,23.257841 L12.5819402,23.2595131 L12.5108777,23.2950439 L12.4918791,23.2987469 L12.4918791,23.2987469 L12.4767152,23.2950439 L12.4056548,23.2595131 C12.3958229,23.2563662 12.3870493,23.2590235 12.3821421,23.2649074 L12.3780323,23.275831 L12.360941,23.7031097 L12.3658947,23.7234994 L12.3769048,23.7357139 L12.4804777,23.8096931 L12.4953491,23.8136134 L12.4953491,23.8136134 L12.5071152,23.8096931 L12.6106902,23.7357139 L12.6232938,23.7196733 L12.6232938,23.7196733 L12.6266527,23.7031097 L12.609561,23.275831 C12.6075724,23.2657013 12.6010112,23.2592993 12.5934901,23.257841 L12.5934901,23.257841 Z M12.8583906,23.1452862 L12.8445485,23.1473072 L12.6598443,23.2396597 L12.6498822,23.2499052 L12.6498822,23.2499052 L12.6471943,23.2611114 L12.6650943,23.6906389 L12.6699349,23.7034178 L12.6699349,23.7034178 L12.678386,23.7104931 L12.8793402,23.8032389 C12.8914285,23.8068999 12.9022333,23.8029875 12.9078286,23.7952264 L12.9118235,23.7811639 L12.8776777,23.1665331 C12.8752882,23.1545897 12.8674102,23.1470016 12.8583906,23.1452862 L12.8583906,23.1452862 Z M12.1430473,23.1473072 C12.1332178,23.1423925 12.1221763,23.1452606 12.1156365,23.1525954 L12.1099173,23.1665331 L12.0757714,23.7811639 C12.0751323,23.7926639 12.0828099,23.8018602 12.0926481,23.8045676 L12.108256,23.8032389 L12.3092106,23.7104931 L12.3186497,23.7024347 L12.3186497,23.7024347 L12.3225043,23.6906389 L12.340401,23.2611114 L12.337245,23.2485176 L12.337245,23.2485176 L12.3277531,23.2396597 L12.1430473,23.1473072 Z" id="MingCute" fill-rule="nonzero"> </path> 445 <path d="M15.7072,11.2929 C16.0977,11.6834 16.0977,12.3166 15.7072,12.7071 L10.0503,18.364 C9.65982,18.7545 9.02666,18.7545 8.63613,18.364 C8.24561,17.9734 8.24561,17.3403 8.63613,16.9497 L13.5859,12 L8.63613,7.05025 C8.24561,6.65973 8.24561,6.02656 8.63613,5.63604 C9.02666,5.24551 9.65982,5.24551 10.0503,5.63604 L15.7072,11.2929 Z" id="路径" fill="#1D98A5"> </path> 446 </g> 447 </g> 448 449 </svg> 450 451 </button> 452 </div> 453 } 454 455 456 </div> 457 458 } 459 if ((fieldValueBlocked != null && !fieldValueBlocked.ToString().Contains(customerNumber)) || String.IsNullOrWhiteSpace(customerNumber)) 460 { 461 <div class="stock-state pt-2 mt-auto"> 462 @{ 463 464 /*stock state*/ 465 double MainvariantStock = MainVariant.Stock; 466 string MainsvgInStock = "<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"16\" height=\"16\" fill=\"#44B11A\" class=\"bi bi-check-lg\" viewBox=\"0 0 16 16\"><path d=\"M12.736 3.97a.733.733 0 0 1 1.047 0c.286.289.29.756.01 1.05L7.88 12.01a.733.733 0 0 1-1.065.02L3.217 8.384a.757.757 0 0 1 0-1.06.733.733 0 0 1 1.047 0l3.052 3.093 5.4-6.425z\"/></svg>"; 467 string MainsvgOutStock = "<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"25\" height=\"25\" fill=\"#CA0D0D\" class=\"bi bi-x-lg\" viewBox=\"0 0 16 16\"><path d=\"M4.646 4.646a.5.5 0 0 1 .708 0L8 7.293l2.646-2.647a.5.5 0 0 1 .708.708L8.707 8l2.647 2.646a.5.5 0 0 1-.708.708L8 8.707l-2.646 2.647a.5.5 0 0 1-.708-.708L7.293 8 4.646 5.354a.5.5 0 0 1 0-.708\"/></svg>"; 468 469 string MaininfoStock = "<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"16\" height=\"16\" fill=\"currentColor\" class=\"bi bi-info-circle-fill\" viewBox=\"0 0 16 16\"><path d=\"M8 16A8 8 0 1 0 8 0a8 8 0 0 0 0 16m.93-9.412-1 4.705c-.07.34.029.533.304.533.194 0 .487-.07.686-.246l-.088.416c-.287.346-.92.598-1.465.598-.703 0-1.002-.422-.808-1.319l.738-3.468c.064-.293.006-.399-.287-.47l-.451-.081.082-.381 2.29-.287zM8 5.5a1 1 0 1 1 0-2 1 1 0 0 1 0 2\" /></svg>"; 470 string MainisNew = MainVariant?.ProductFieldValues?.GetProductFieldValue("New")?.Value?.ToString().ToLower() ?? ""; 471 string MainisNewSvg = "<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"16\" height=\"16\" fill=\"#F2C400\" class=\"bi bi-star-fill\" viewBox=\"0 0 16 16\"><path d = \"M3.612 15.443c-.386.198-.824-.149-.746-.592l.83-4.73L.173 6.765c-.329-.314-.158-.888.283-.95l4.898-.696L7.538.792c.197-.39.73-.39.927 0l2.184 4.327 4.898.696c.441.062.612.636.282.95l-3.522 3.356.83 4.73c.078.443-.36.79-.746.592L8 13.187l-4.389 2.256z\" /></svg> "; 472 string MainstockState = ""; 473 string MainIsSale = MainVariant?.ProductFieldValues?.GetProductFieldValue("Sale")?.Value?.ToString().ToLower() ?? ""; 474 string MainIsSaleSvg = "<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"16\" height=\"16\" fill=\"#F03232\" class=\"bi bi-star-fill\" viewBox=\"0 0 16 16\"><path d = \"M3.612 15.443c-.386.198-.824-.149-.746-.592l.83-4.73L.173 6.765c-.329-.314-.158-.888.283-.95l4.898-.696L7.538.792c.197-.39.73-.39.927 0l2.184 4.327 4.898.696c.441.062.612.636.282.95l-3.522 3.356.83 4.73c.078.443-.36.79-.746.592L8 13.187l-4.389 2.256z\" /></svg> "; 475 string MainexpectedDeliveryDate = ""; 476 477 if (DateTime.Compare(MainVariant.ExpectedDelivery, new DateTime(1900, 1, 1)) != 0) //In DW, if the Date is not set, it is defaulted 01-01-1900 and not null.. 478 { 479 MainexpectedDeliveryDate = MainVariant.ExpectedDelivery.ToShortDateString(); 480 } 481 482 string MainexpectedDeliveryDateText = !String.IsNullOrWhiteSpace(MainexpectedDeliveryDate) ? Translate("Verwacht:") + "&nbsp;" + MainexpectedDeliveryDate : ""; 483 484 @if (!(bool?)MainVariant.ProductFieldValues.Where(o => o.ProductField.SystemName == "ProductToBeDiscontinued").SingleOrDefault()?.Value ?? false) 485 { 486 if (MainvariantStock > 0) 487 { 488 if (MainisNew == "true" || MainIsSale == "true") 489 { 490 if (MainIsSale == "true") 491 { 492 MainstockState += MainIsSaleSvg + "&nbsp; &nbsp;" + Translate("Sale!") + "<br/>"; 493 } 494 495 if (MainisNew == "true") 496 { 497 MainstockState += MainisNewSvg + "&nbsp; &nbsp;" + Translate("New!") + "<br/>"; 498 } 499 500 MainstockState += "&nbsp;" + Translate("Nu leverbaar"); 501 } 502 else 503 { 504 MainstockState = MainsvgInStock + "&nbsp; " + Translate("Op voorraad"); 505 506 } 507 } 508 else 509 { 510 MainstockState = MainsvgOutStock + "&nbsp;" + Translate("Geen voorraad") + "<br/>" + MainexpectedDeliveryDateText; 511 512 } 513 } 514 else 515 { 516 517 MainstockState = MainsvgOutStock + "&nbsp;" + Translate("Discontinued:") + "<br/>" + MainvariantStock + "&nbsp;" + @Translate("left in stock"); 518 519 } 520 /*End stock state*/ 521 522 523 @MainstockState 524 525 526 } 527 </div> 528 } 529 else 530 { 531 <div class="stock-state pt-2 mt-auto"> 532 @MainOutStock @Translate("Discontinued") 533 </div> 534 } 535 <div class="custom-price mt-auto"> 536 @{ 537 538 539 540 541 bool isErpConnectionDown = !Dynamicweb.Core.Converter.ToBoolean(Dynamicweb.Context.Current.Items["IsWebServiceConnectionAvailable"]); 542 bool hidePrice = anonymousUsersLimitations.Contains("price") && anonymousUser || Pageview.AreaSettings.GetBoolean("ErpDownHidePrices") && isErpConnectionDown; 543 544 bool productIsDiscontinued = product is object && product.Discontinued; 545 bool doNotShowPriceIfProductIsDiscontinued = Model.Item.GetBoolean("DoNotShowPriceIfProductIsDiscontinued"); 546 var isDiscontinued = productIsDiscontinued && doNotShowPriceIfProductIsDiscontinued; 547 } 548 549 @if (product is object && !hidePrice && !isDiscontinued) 550 { 551 string unitId = !string.IsNullOrEmpty(Dynamicweb.Context.Current.Request.Form.Get("UnitId")) ? Dynamicweb.Context.Current.Request.Form.Get("UnitId") : string.Empty; 552 553 string priceFontSize = Model.Item.GetRawValueString("PriceSize", "fs-4"); 554 string horizontalAlign = Model.Item.GetRawValueString("HorizontalAlignment", ""); 555 string layout = Model.Item.GetRawValueString("Layout", "horizontal"); 556 string textAlign = horizontalAlign == "center" ? "text-center" : string.Empty; 557 textAlign = horizontalAlign == "end" ? "text-end" : textAlign; 558 559 horizontalAlign = horizontalAlign == "center" && layout == "horizontal" ? "justify-content-center" : horizontalAlign; 560 horizontalAlign = horizontalAlign == "end" && layout == "horizontal" ? "justify-content-end" : horizontalAlign; 561 horizontalAlign = horizontalAlign == "center" && layout == "vertical" ? "align-items-center" : horizontalAlign; 562 horizontalAlign = horizontalAlign == "end" && layout == "vertical" ? "align-items-end" : horizontalAlign; 563 564 string flexDirection = layout == "horizontal" ? string.Empty : "flex-column"; 565 string flexGap = layout == "horizontal" ? "gap-3" : string.Empty; 566 string order = layout == "horizontal" ? string.Empty : "order-2"; 567 568 569 string contentPadding = Model.Item.GetRawValueString("ContentPadding", ""); 570 contentPadding = contentPadding == "none" ? "p-0" : contentPadding; 571 contentPadding = contentPadding == "small" ? "p-1 px-md-2 py-md-1" : contentPadding; 572 contentPadding = contentPadding == "large" ? "p-2 px-md-3 py-md-2" : contentPadding; 573 string liveInfoClass = ""; 574 575 576 577 578 579 580 if (isLazyLoadingForProductInfoEnabled) 581 { 582 if (Dynamicweb.Context.Current.Items.Contains("ProductInfoFeed")) 583 { 584 productInfoFeed = Dynamicweb.Context.Current.Items["ProductInfoFeed"]?.ToString(); 585 if (!string.IsNullOrEmpty(productInfoFeed)) 586 { 587 productInfoFeed = $"data-product-info-feed=\"{productInfoFeed}\""; 588 } 589 } 590 liveInfoClass = "js-live-info"; 591 } 592 593 <div class="@textAlign @liveInfoClass item_@Model.Item.SystemName.ToLower()" data-product-id="@product.Id" data-variant-id="@product.VariantId" @productInfoFeed> 594 @if (showInformativePrice && product.PriceInformative.Price != 0) 595 { 596 <div class="opacity-50"> 597 <span>@Translate("RRP") </span> 598 <span class="text-decoration-line-through text-price">@product.PriceInformative.PriceFormatted</span> 599 </div> 600 } 601 <div class="@priceFontSize m-0 d-flex flex-wrap @flexDirection @flexGap @horizontalAlign" style="row-gap: 0 !important" itemprop="offers" itemscope itemtype="https://schema.org/Offer"> 602 <span itemprop="priceCurrency" content="@product.Price.CurrencyCode" class="d-none"></span> 603 604 605 @if (showPricesWithVat == "false" && !neverShowVat) 606 { 607 if (isLazyLoadingForProductInfoEnabled && !Pageview.IsVisualEditorMode) 608 { 609 <span itemprop="price" content="" class="d-none"></span> 610 <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> 611 } 612 else 613 { 614 string beforePrice = !string.IsNullOrEmpty(unitId) ? product.GetPrice(unitId).PriceBeforeDiscount.PriceWithoutVatFormatted : product.PriceBeforeDiscount.PriceWithoutVatFormatted; 615 616 <span itemprop="price" content="@product.Price.PriceWithoutVat.ToString("0.00", System.Globalization.CultureInfo.InvariantCulture)" class="d-none"></span> 617 if (product.Price.Price != product.PriceBeforeDiscount.Price) 618 { 619 <span class="text-decoration-line-through opacity-75 @order">@beforePrice</span> 620 } 621 } 622 } 623 else 624 { 625 if (isLazyLoadingForProductInfoEnabled && !Pageview.IsVisualEditorMode) 626 { 627 <span itemprop="price" content="" class="d-none"></span> 628 <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> 629 } 630 else 631 { 632 string beforePrice = !string.IsNullOrEmpty(unitId) ? product.GetPrice(unitId).PriceBeforeDiscount.PriceFormatted : product.PriceBeforeDiscount.PriceFormatted; 633 634 <span itemprop="price" content="@product.Price.Price.ToString("0.00", System.Globalization.CultureInfo.InvariantCulture)" class="d-none"></span> 635 636 if (product.Price.Price != product.PriceBeforeDiscount.Price) 637 { 638 <span class="text-decoration-line-through opacity-75 @order"> 639 <span class="text-price">@beforePrice</span> 640 </span> 641 } 642 } 643 } 644 645 @if (showPricesWithVat == "false" && !neverShowVat) 646 { 647 if (isLazyLoadingForProductInfoEnabled && !Pageview.IsVisualEditorMode) 648 { 649 <span class="text-price js-text-price"> 650 <span class="spinner-border" role="status"></span> 651 </span> 652 } 653 else 654 { 655 string price = !string.IsNullOrEmpty(unitId) ? product.GetPrice(unitId).Price.PriceWithoutVatFormatted : product.Price.PriceWithoutVatFormatted; 656 657 if (product?.VariantInfo?.VariantInfo != null) 658 { 659 priceMin = product?.VariantInfo?.PriceMin?.PriceWithoutVatFormatted != null ? product.VariantInfo.PriceMin.PriceWithoutVatFormatted : ""; 660 priceMax = product?.VariantInfo?.PriceMax?.PriceWithoutVatFormatted != null ? product.VariantInfo.PriceMax.PriceWithoutVatFormatted : ""; 661 } 662 if (priceMin != priceMax) 663 { 664 price = priceMin + " - " + priceMax; 665 } 666 <span class="@theme @contentPadding"> 667 <span class="text-price">@price</span> 668 </span> 669 } 670 } 671 else 672 { 673 if (isLazyLoadingForProductInfoEnabled && !Pageview.IsVisualEditorMode) 674 { 675 <span class="text-price js-text-price"> 676 <span class="spinner-border" role="status"></span> 677 </span> 678 } 679 else 680 { 681 string price = !string.IsNullOrEmpty(unitId) ? product.GetPrice(unitId).Price.PriceFormatted : product.Price.PriceFormatted; 682 683 if (product?.VariantInfo?.VariantInfo != null) 684 { 685 priceMin = product?.VariantInfo?.PriceMin?.PriceFormatted != null ? product.VariantInfo.PriceMin.PriceFormatted : ""; 686 priceMax = product?.VariantInfo?.PriceMax?.PriceFormatted != null ? product.VariantInfo.PriceMax.PriceFormatted : ""; 687 } 688 if (priceMin != priceMax) 689 { 690 price = priceMin + " - " + priceMax; 691 } 692 <span class="@theme @contentPadding"> 693 <span class="text-price">@price</span> 694 </span> 695 } 696 } 697 698 @* Stock state for Schema.org, start *@ 699 @{ 700 Uri url = Dynamicweb.Context.Current.Request.Url; 701 } 702 703 <link itemprop="url" href="@url"> 704 705 @{ 706 bool IsNeverOutOfStock = product.NeverOutOfstock; 707 } 708 709 @if (IsNeverOutOfStock) 710 { 711 <span itemprop="availability" class="d-none">@Translate("Available in stock")</span> 712 } 713 else 714 { 715 if (product.StockLevel > 0) 716 { 717 <span itemprop="availability" class="d-none">InStock</span> 718 } 719 else 720 { 721 <span itemprop="availability" class="d-none">OutOfStock</span> 722 } 723 } 724 @* Stock state for Schema.org, stop *@ 725 726 </div> 727 728 @if (showPricesWithVat == "false" && !neverShowVat) 729 { 730 if (isLazyLoadingForProductInfoEnabled && !Pageview.IsVisualEditorMode) 731 { 732 <small class="opacity-85 fst-normal js-text-price-with-vat d-none" data-suffix="@Translate("Incl. VAT")"></small> 733 } 734 else 735 { 736 string price = !string.IsNullOrEmpty(unitId) ? product.GetPrice(unitId).Price.PriceWithVatFormatted : product.Price.PriceWithVatFormatted; 737 738 if (product?.VariantInfo?.VariantInfo != null) 739 { 740 priceMin = product?.VariantInfo?.PriceMin?.PriceWithVatFormatted != null ? product.VariantInfo.PriceMin.PriceWithVatFormatted : ""; 741 priceMax = product?.VariantInfo?.PriceMax?.PriceWithVatFormatted != null ? product.VariantInfo.PriceMax.PriceWithVatFormatted : ""; 742 } 743 if (priceMin != priceMax) 744 { 745 price = priceMin + " - " + priceMax; 746 } 747 <!-- <small class="opacity-85 fst-normal">@price @Translate("Incl. VAT")</small> --> 748 } 749 } 750 </div> 751 } 752 else if (Pageview.IsVisualEditorMode) 753 { 754 <div class="alert alert-dark m-0" role="alert"> 755 <span>@Translate("No products available")</span> 756 </div> 757 } 758 759 </div> 760 } 761 } 762
Tischlampe Ø28 Korb
Error executing template "Designs/Swift/Paragraph/CustomProductSlider.cshtml"
System.NullReferenceException: Object reference not set to an instance of an object.
   at CompiledRazorTemplates.Dynamic.RazorEngine_3562354021b44d5c892fe73dc2806e4f.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 Dynamicweb.Ecommerce.ProductCatalog 3 @using Dynamicweb.Ecommerce.CustomerExperienceCenter.Favorites 4 @using Dynamicweb.Files 5 @using System.IO 6 @using System.Net 7 @using Dynamicweb.Security.UserManagement 8 9 10 @{ 11 ProductViewModel product = null; 12 if (Dynamicweb.Context.Current.Items.Contains("ProductDetails")) 13 { 14 product = (ProductViewModel)Dynamicweb.Context.Current.Items["ProductDetails"]; 15 } 16 else if (Pageview.Page.Item["DummyProduct"] != null && Pageview.IsVisualEditorMode) 17 { 18 var pageViewModel = Dynamicweb.Frontend.ContentViewModelFactory.CreatePageInfoViewModel(Pageview.Page); 19 ProductListViewModel productList = pageViewModel.Item.GetValue("DummyProduct") != null ? pageViewModel.Item.GetValue("DummyProduct") as ProductListViewModel : new ProductListViewModel(); 20 21 if (productList?.Products is object) 22 { 23 product = productList.Products[0]; 24 } 25 } 26 } 27 28 @{ 29 var currentUser = Pageview?.User; 30 var customerNumber = !string.IsNullOrEmpty(currentUser?.CustomerNumber) 31 ? currentUser.CustomerNumber 32 : ""; 33 } 34 @if (product is object) 35 { 36 string imagePath = product?.DefaultImage?.Value ?? ""; 37 string imagePathUrlEncoded = Dynamicweb.Context.Current.Server.UrlEncode(imagePath); 38 39 string ratio = Model.Item.GetRawValueString("ImageAspectRatio", ""); 40 ratio = ratio != "0" ? ratio : ""; 41 string ratioCssClass = ratio != "" ? " ratio" : ""; 42 string ratioVariable = ratio != "" ? "--bs-aspect-ratio: " + ratio + ";" : ""; 43 44 string width = Model.Item.GetRawValueString("Width", "auto"); 45 int smallImageSize = 640; 46 int largeImageSize = width == "auto" ? 1280 : Convert.ToInt32(width); 47 48 string ImageObjectFit = Model.Item.GetRawValueString("ImageObjectFit", "contain"); 49 50 string imagePathXs = "/Admin/Public/GetImage.ashx?width=" + smallImageSize + "&image=" + imagePathUrlEncoded + "&format=webp"; 51 string imagePathS = "/Admin/Public/GetImage.ashx?width=" + largeImageSize + "&image=" + imagePathUrlEncoded + "&format=webp"; 52 string imagePathFallBack = "/Admin/Public/GetImage.ashx?width=" + largeImageSize + "&image=" + imagePathUrlEncoded + "&format=webp"; 53 54 var badgeParms = new Dictionary<string, object>(); 55 badgeParms.Add("size", "h7"); 56 badgeParms.Add("saleBadgeType", Model.Item.GetRawValue("SaleBadgeType")); 57 badgeParms.Add("saleBadgeCssClassName", Model.Item.GetRawValue("SaleBadgeDesign")); 58 badgeParms.Add("newBadgeCssClassName", Model.Item.GetRawValue("NewBadgeDesign")); 59 badgeParms.Add("newPublicationDays", Model.Item.GetInt32("NewPublicationDays")); 60 badgeParms.Add("campaignBadgesValues", Model.Item.GetList("CampaignBadges")?.GetRawValue().OfType<string>().ToList()); 61 62 string badgeSize = Model.Item.GetRawValueString("BadgeSize", "fs-2"); 63 bool saleBadgeEnabled = !string.IsNullOrWhiteSpace(Model.Item.GetRawValueString("SaleBadgeDesign")) && Model.Item.GetRawValueString("SaleBadgeDesign") != "none" ? true : false; 64 bool newBadgeEnabled = !string.IsNullOrWhiteSpace(Model.Item.GetRawValueString("NewBadgeDesign")) && Model.Item.GetRawValueString("NewBadgeDesign") != "none" ? true : false; 65 66 /*Custom badge*/ 67 var productService = new Dynamicweb.Ecommerce.Products.ProductService(); 68 var currency = Dynamicweb.Ecommerce.Common.Context.Currency.Code; 69 var formatProvider = new System.Globalization.NumberFormatInfo(); 70 formatProvider.NumberDecimalSeparator = "."; 71 formatProvider.NumberGroupSeparator = ","; 72 var MainVariant = productService.GetProductById(product.Id, product.VariantId, false); 73 var fieldValueBlocked = MainVariant?.ProductFieldValues?.GetProductFieldValue("BlockedCustomerList")?.Value; 74 75 76 string isNewProduct = MainVariant?.ProductFieldValues?.GetProductFieldValue("New")?.Value?.ToString().ToLower() ?? ""; 77 string MainisSale = MainVariant?.ProductFieldValues?.GetProductFieldValue("Sale")?.Value?.ToString().ToLower() ?? ""; 78 bool showNewBadge = isNewProduct == "true" ? true : false; 79 bool showSaleBadge = MainisSale == "true" ? true : false; 80 string showNewSaleBadge = "d-none"; 81 if (showSaleBadge) 82 { 83 badgeParms.Add("isSale", "true"); 84 85 } 86 else 87 { 88 badgeParms.Add("isSale", "false"); 89 } 90 if (showNewBadge) 91 { 92 badgeParms.Add("isNew", "true"); 93 } 94 else 95 { 96 badgeParms.Add("isNew", "false"); 97 } 98 /*End Custom badge*/ 99 if (showSaleBadge || showNewBadge) 100 { 101 showNewSaleBadge = ""; 102 } 103 DateTime createdDate = product.Created.Value; 104 bool showBadges = saleBadgeEnabled && product.Discount.Price != 0 ? true : false; 105 106 bool showFavoritesSelector = !string.IsNullOrEmpty(Model.Item.GetString("ShowAddToFavorites")) ? Model.Item.GetBoolean("ShowAddToFavorites") : false; 107 string anonymousUsersLimitations = Pageview.AreaSettings.GetRawValueString("AnonymousUsers", ""); 108 bool anonymousUser = Pageview.User == null; 109 110 var favoriteParameters = new Dictionary<string, object>(); 111 if (!anonymousUser && showFavoritesSelector) 112 { 113 int defaultFavoriteListId = 0; 114 115 IEnumerable<FavoriteList> favoreiteLists = Pageview.User.GetFavoriteLists(); 116 if (favoreiteLists.Count() == 1) 117 { 118 foreach (FavoriteList list in favoreiteLists) 119 { 120 defaultFavoriteListId = list.ListId; 121 } 122 } 123 124 favoriteParameters.Add("ListId", defaultFavoriteListId); 125 } 126 127 MediaViewModel alternativeImage = new MediaViewModel(); 128 if (Model.Item.GetBoolean("ShowAlternativeImageOnHover")) 129 { 130 var selectedImageCategories = Model.Item.GetList("GetAlternativeImageFrom")?.GetRawValue().OfType<string>().ToList(); 131 List<MediaViewModel> allAssetsImages = product.AssetCategories.Where(x => selectedImageCategories.Contains(x.SystemName)).SelectMany(x => x.Assets).ToList(); 132 allAssetsImages.RemoveAll(x => x.Value == product.DefaultImage.Value); 133 alternativeImage = allAssetsImages.FirstOrDefault(); 134 } 135 136 string altImagePathXs = string.Empty; 137 string altImagePathS = string.Empty; 138 139 if (!string.IsNullOrEmpty(alternativeImage?.Value)) 140 { 141 altImagePathXs = "/Admin/Public/GetImage.ashx?width=" + smallImageSize + "&image=" + Dynamicweb.Context.Current.Server.UrlEncode(alternativeImage.Value) + "&format=webp"; 142 altImagePathS = "/Admin/Public/GetImage.ashx?width=" + largeImageSize + "&image=" + Dynamicweb.Context.Current.Server.UrlEncode(alternativeImage.Value) + "&format=webp"; 143 } 144 145 @* Theme settings *@ 146 string theme = !string.IsNullOrWhiteSpace(Model.Item.GetRawValueString("Theme")) ? " theme " + Model.Item.GetRawValueString("Theme").Replace(" ", "").Trim().ToLower() : ""; 147 string themeBorder = !string.IsNullOrWhiteSpace(theme) ? "border: 1px solid rgba(0,0,0,0)" : ""; 148 string themePadding = !string.IsNullOrWhiteSpace(theme) ? "p-2 p-lg-3" : ""; 149 150 string imageId = "ProductImage_" + product.Id; 151 152 153 154 string fullWidth = width == "auto" ? "w-100" : ""; 155 string customWidth = width != "auto" ? "style=\"width: " + width + "px\"" : "style=\"min-width: 60px\""; 156 157 string altImageZindex = Model.Item.GetBoolean("ShowAlternativeImageOnHover") && !string.IsNullOrEmpty(alternativeImage?.Value) ? " z-index: 1" : string.Empty; 158 string groupid = !string.IsNullOrEmpty(Dynamicweb.Context.Current.Request.QueryString.Get("GroupID")) ? Dynamicweb.Context.Current.Request.QueryString.Get("GroupID"):"" ; 159 string link = product.GetProductLink(GetPageIdByNavigationTag("Shop"), false); 160 var productVariantGroups = product.VariantGroups(); 161 string MainOutStock = "<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"25\" height=\"25\" fill=\"#CA0D0D\" class=\"bi bi-x-lg\" viewBox=\"0 0 16 16\"><path d=\"M4.646 4.646a.5.5 0 0 1 .708 0L8 7.293l2.646-2.647a.5.5 0 0 1 .708.708L8.707 8l2.647 2.646a.5.5 0 0 1-.708.708L8 8.707l-2.646 2.647a.5.5 0 0 1-.708-.708L7.293 8 4.646 5.354a.5.5 0 0 1 0-.708\"/></svg>"; 162 163 @if (!string.IsNullOrEmpty(imagePath)) 164 { 165 <div class="@fullWidth @theme position-relative item_@Model.Item.SystemName.ToLower() main-image-container" @customWidth> 166 <div class="" style="@(ratioVariable)@(altImageZindex)"> 167 <div class="d-flex justify-content-center align-items-center"> 168 <a class="main-link-link" href="@link"> 169 @if (imagePath.StartsWith("/Files/", StringComparison.OrdinalIgnoreCase)) 170 { 171 <img id="@imageId" 172 srcset=" 173 @imagePathXs @(smallImageSize)w, 174 @imagePathS @(largeImageSize)w" 175 sizes="(max-width: 992px) 50vw, 25vw" 176 src="@imagePathFallBack" 177 loading="lazy" 178 decoding="async" 179 class="h-100 w-100 @themePadding main-image" 180 style="object-fit: @ImageObjectFit; @themeBorder " 181 alt="@product.Name" 182 itemprop="image"> 183 } 184 else 185 { 186 <img src="@product.DefaultImage.Value" 187 loading="lazy" 188 class="h-100 w-100 @themePadding main-image" 189 style="object-fit: contain; @themeBorder" 190 alt="@product.Name" 191 itemprop="image"> 192 } 193 </a> 194 </div> 195 </div> 196 197 <div class="position-absolute top-0 left-0 p-2 pb-0 custom-badge-product-list @showNewSaleBadge"> 198 @{ 199 @RenderPartial("Components/Custom_EcommerceBadge.cshtml", product, badgeParms) 200 } 201 </div> 202 203 204 </div> 205 } 206 207 <div class="product-info h-100"> 208 <div class="fs-7 pt-1 opacity-85 start item_@Model.Item.SystemName.ToLower() product-number" itemprop="sku">@product.Id / @product.VariantId - @product.VariantName</div> 209 <div class="py-2" data-col-size="12"> 210 <h2 class="h6 start m-0 item_swift_productheader product-name" itemprop="name"><b>@product.Name</b></h2> 211 </div> 212 </div> 213 var sliderId = $"thumb-scroll-{product.Id}"; 214 if (productVariantGroups.Any() && product?.VariantInfo?.VariantInfo != null) 215 216 { 217 @using Dynamicweb.Ecommerce.Prices 218 @{ 219 string[] variantId = product.VariantId.Split('.'); 220 string showPricesWithVat = Pageview.Area.EcomPricesWithVat.ToLower(); 221 bool neverShowVat = string.IsNullOrEmpty(showPricesWithVat); 222 bool showInformativePrice = Model.Item.GetBoolean("ShowInformativePrice"); 223 string productInfoFeed = ""; 224 bool isLazyLoadingForProductInfoEnabled = Dynamicweb.Core.Converter.ToBoolean(Dynamicweb.Context.Current.Items["IsLazyLoadingForProductInfoEnabled"]); 225 if (isLazyLoadingForProductInfoEnabled) 226 { 227 if (Dynamicweb.Context.Current.Items.Contains("ProductInfoFeed")) 228 { 229 productInfoFeed = Dynamicweb.Context.Current.Items["ProductInfoFeed"]?.ToString(); 230 if (!string.IsNullOrEmpty(productInfoFeed)) 231 { 232 productInfoFeed =productInfoFeed; 233 } 234 } 235 236 } 237 string priceMin = ""; 238 string priceMax = ""; 239 int groupNumber = 1; 240 241 242 243 244 string baseUrl = $"Default.aspx?ID={GetPageIdByNavigationTag("Shop")}&GroupID={product.PrimaryOrDefaultGroup.Id}&ProductID={product.Id}"; 245 if (!string.IsNullOrEmpty(baseUrl)) 246 { 247 baseUrl = $"/{baseUrl.TrimStart('/')}"; 248 } 249 string variantUrl = string.Empty; 250 251 252 Dictionary<string, string> 253 variantImages = new Dictionary<string, string> 254 (); 255 <div class="last-row mt-auto"> 256 257 @foreach (var variantGroup in productVariantGroups) 258 { 259 <div class="thumbnail-wrapper"> 260 <button class="thumb-nav prev" onclick="scrollThumbs('@sliderId', -1)"> 261 <svg width="20px" height="20px" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" fill="#1D98A5"> 262 263 <g stroke="none" stroke-width="1" fill="none" fill-rule="evenodd"> 264 <g transform="translate(-336.000000, 0.000000)"> 265 <g id="left_line" transform="translate(336.000000, 0.000000)"> 266 <path d="M24,0 L24,24 L0,24 L0,0 L24,0 Z M12.5934901,23.257841 L12.5819402,23.2595131 L12.5108777,23.2950439 L12.4918791,23.2987469 L12.4918791,23.2987469 L12.4767152,23.2950439 L12.4056548,23.2595131 C12.3958229,23.2563662 12.3870493,23.2590235 12.3821421,23.2649074 L12.3780323,23.275831 L12.360941,23.7031097 L12.3658947,23.7234994 L12.3769048,23.7357139 L12.4804777,23.8096931 L12.4953491,23.8136134 L12.4953491,23.8136134 L12.5071152,23.8096931 L12.6106902,23.7357139 L12.6232938,23.7196733 L12.6232938,23.7196733 L12.6266527,23.7031097 L12.609561,23.275831 C12.6075724,23.2657013 12.6010112,23.2592993 12.5934901,23.257841 L12.5934901,23.257841 Z M12.8583906,23.1452862 L12.8445485,23.1473072 L12.6598443,23.2396597 L12.6498822,23.2499052 L12.6498822,23.2499052 L12.6471943,23.2611114 L12.6650943,23.6906389 L12.6699349,23.7034178 L12.6699349,23.7034178 L12.678386,23.7104931 L12.8793402,23.8032389 C12.8914285,23.8068999 12.9022333,23.8029875 12.9078286,23.7952264 L12.9118235,23.7811639 L12.8776777,23.1665331 C12.8752882,23.1545897 12.8674102,23.1470016 12.8583906,23.1452862 L12.8583906,23.1452862 Z M12.1430473,23.1473072 C12.1332178,23.1423925 12.1221763,23.1452606 12.1156365,23.1525954 L12.1099173,23.1665331 L12.0757714,23.7811639 C12.0751323,23.7926639 12.0828099,23.8018602 12.0926481,23.8045676 L12.108256,23.8032389 L12.3092106,23.7104931 L12.3186497,23.7024347 L12.3186497,23.7024347 L12.3225043,23.6906389 L12.340401,23.2611114 L12.337245,23.2485176 L12.337245,23.2485176 L12.3277531,23.2396597 L12.1430473,23.1473072 Z" id="MingCute" fill-rule="nonzero"> </path> 267 <path d="M8.29292,12.7071 C7.9024,12.3166 7.9024,11.6834 8.29292,11.2929 L13.9498,5.63604 C14.3403,5.24551 14.9735,5.24551 15.364,5.63604 C15.7545,6.02656 15.7545,6.65973 15.364,7.05025 L10.4142,12 L15.364,16.9497 C15.7545,17.3403 15.7545,17.9734 15.364,18.364 C14.9735,18.7545 14.3403,18.7545 13.9498,18.364 L8.29292,12.7071 Z" id="路径" fill="#1D98A5"> </path> 268 </g> 269 </g> 270 </g> 271 </svg> 272 273 </button> 274 <div class="thumbnail-scroll" id="@sliderId"> 275 @{ 276 VariantGroupViewModel group = variantGroup; 277 foreach (var option in group.Options.OrderBy(o => o.Id)) 278 { 279 var productVariant = productService.GetProductById(product.Id, option.Id, false); 280 281 var productSelection = new PriceProductSelection(productVariant, null, 0); 282 283 var currencyCode = string.IsNullOrWhiteSpace(Pageview.User.Currency) ? Pageview.Area.EcomCurrencyId : Pageview.User.Currency; 284 var countryCode = string.IsNullOrWhiteSpace(Pageview.User.CountryCode) ? Pageview.Area.EcomCountryCode : Pageview.User.CountryCode; 285 286 var userCurrency = Dynamicweb.Ecommerce.Services.Currencies.GetCurrency(currencyCode); 287 var userCountry = Dynamicweb.Ecommerce.Services.Countries.GetCountry(countryCode); 288 289 var priceContext = new PriceContext(userCurrency, userCountry, null, Pageview.User, false, null); 290 var productPrice = Dynamicweb.Ecommerce.Services.Prices.FindPrices(priceContext, productSelection, false); 291 292 //throw new Exception(System.Text.Json.JsonSerializer.Serialize(productPrice)); 293 294 var fieldValue = productVariant?.ProductFieldValues?.GetProductFieldValue("BlockedCustomerList")?.Value; 295 296 if ((fieldValue != null && !fieldValue.ToString().Contains(customerNumber)) || String.IsNullOrWhiteSpace(customerNumber)) 297 { 298 299 300 string active = variantId != null && variantId.Contains(option.Id) ? "active" : string.Empty; 301 string buttonId = $"{product.Id}_{option.Id}_{Pageview.CurrentParagraph.ID}"; 302 string contrastColor = string.Empty; 303 304 string searchKey = $"{product.Id}_{option.Id}_"; 305 /*Images*/ 306 var imagePathVariant = option.Image?.Value ?? ""; 307 308 309 var folderPath = Path.GetDirectoryName(imagePathVariant); 310 311 string physicalFolderPath = Dynamicweb.Context.Current.Server.MapPath(folderPath); 312 313 string lastImage = null; 314 315 if (Directory.Exists(physicalFolderPath)) 316 { 317 318 var fileWith15 = Directory.GetFiles(physicalFolderPath) 319 .FirstOrDefault(f => Path.GetFileName(f).Contains($"{product.Id}_{option.Id}_9")); 320 321 if (fileWith15 != null) 322 { 323 lastImage = fileWith15; 324 } 325 else 326 { 327 var files = Directory.GetFiles(physicalFolderPath) 328 .Where(f => Path.GetFileName(f).StartsWith($"{product.Id}_{option.Id}_")) 329 .OrderByDescending(f => 330 { 331 var filename = Path.GetFileNameWithoutExtension(f); 332 var match = System.Text.RegularExpressions.Regex.Match(filename, @"_(\d+)$"); 333 if (match.Success && int.TryParse(match.Groups[1].Value, out int index)) 334 { 335 return index; 336 } 337 return 0; 338 }) 339 .ToList(); 340 341 if (files.Any()) 342 { 343 lastImage = files.First(); 344 } 345 } 346 } 347 348 var lastImageUrl = lastImage != null ? lastImage : "/Files/Images/zijlstra/Afbeeldingen_overig/Coming_Soon.jpg"; 349 int index = lastImageUrl.IndexOf("Files"); 350 string relativePath = index >= 0 ? lastImageUrl.Substring(index).Replace("\\", "/") : lastImageUrl.Replace("\\", "/"); 351 lastImageUrl = "/" + relativePath; 352 lastImageUrl = Dynamicweb.Context.Current.Server.UrlEncode(lastImageUrl); 353 var variantImg = option.Image is object ? Dynamicweb.Context.Current.Server.UrlEncode(option.Image.Value) : null; 354 var variantLink = "/Default.aspx?ID=" + GetPageIdByNavigationTag("Shop") + "&GroupID=" + product.PrimaryOrDefaultGroup.Id + "&ProductID=" + product.Id + "&VariantID=" + option.Id; 355 356 string variantImage = string.Empty; 357 variantImages.TryGetValue(option.Id, out variantImage); 358 /*End Images*/ 359 360 /*stock state*/ 361 double variantStock = productVariant.Stock; 362 string svgInStock = "<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"16\" height=\"16\" fill=\"#44B11A\" class=\"bi bi-check-lg\" viewBox=\"0 0 16 16\"><path d=\"M12.736 3.97a.733.733 0 0 1 1.047 0c.286.289.29.756.01 1.05L7.88 12.01a.733.733 0 0 1-1.065.02L3.217 8.384a.757.757 0 0 1 0-1.06.733.733 0 0 1 1.047 0l3.052 3.093 5.4-6.425z\"/></svg>"; 363 string svgOutStock = "<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"25\" height=\"25\" fill=\"#CA0D0D\" class=\"bi bi-x-lg\" viewBox=\"0 0 16 16\"><path d=\"M4.646 4.646a.5.5 0 0 1 .708 0L8 7.293l2.646-2.647a.5.5 0 0 1 .708.708L8.707 8l2.647 2.646a.5.5 0 0 1-.708.708L8 8.707l-2.646 2.647a.5.5 0 0 1-.708-.708L7.293 8 4.646 5.354a.5.5 0 0 1 0-.708\"/></svg>"; 364 365 string infoStock = "<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"16\" height=\"16\" fill=\"currentColor\" class=\"bi bi-info-circle-fill\" viewBox=\"0 0 16 16\"><path d=\"M8 16A8 8 0 1 0 8 0a8 8 0 0 0 0 16m.93-9.412-1 4.705c-.07.34.029.533.304.533.194 0 .487-.07.686-.246l-.088.416c-.287.346-.92.598-1.465.598-.703 0-1.002-.422-.808-1.319l.738-3.468c.064-.293.006-.399-.287-.47l-.451-.081.082-.381 2.29-.287zM8 5.5a1 1 0 1 1 0-2 1 1 0 0 1 0 2\" /></svg>"; 366 string isNew = productVariant?.ProductFieldValues?.GetProductFieldValue("New")?.Value?.ToString().ToLower() ?? ""; 367 string isNewSvg = "<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"16\" height=\"16\" fill=\"#F2C400\" class=\"bi bi-star-fill\" viewBox=\"0 0 16 16\"><path d = \"M3.612 15.443c-.386.198-.824-.149-.746-.592l.83-4.73L.173 6.765c-.329-.314-.158-.888.283-.95l4.898-.696L7.538.792c.197-.39.73-.39.927 0l2.184 4.327 4.898.696c.441.062.612.636.282.95l-3.522 3.356.83 4.73c.078.443-.36.79-.746.592L8 13.187l-4.389 2.256z\" /></svg> "; 368 string stockState = ""; 369 370 string isSale = productVariant?.ProductFieldValues?.GetProductFieldValue("Sale")?.Value?.ToString().ToLower() ?? ""; 371 string isSaleSvg = "<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"16\" height=\"16\" fill=\"#F03232\" class=\"bi bi-star-fill\" viewBox=\"0 0 16 16\"><path d = \"M3.612 15.443c-.386.198-.824-.149-.746-.592l.83-4.73L.173 6.765c-.329-.314-.158-.888.283-.95l4.898-.696L7.538.792c.197-.39.73-.39.927 0l2.184 4.327 4.898.696c.441.062.612.636.282.95l-3.522 3.356.83 4.73c.078.443-.36.79-.746.592L8 13.187l-4.389 2.256z\" /></svg> "; 372 373 string expectedDeliveryDate = ""; 374 375 if (DateTime.Compare(productVariant.ExpectedDelivery, new DateTime(1900, 1, 1)) != 0) //In DW, if the Date is not set, it is defaulted 01-01-1900 and not null.. 376 { 377 expectedDeliveryDate = productVariant.ExpectedDelivery.ToShortDateString(); 378 } 379 380 string expectedDeliveryDateText = !String.IsNullOrWhiteSpace(expectedDeliveryDate) ? Translate("Verwacht:") + "&nbsp;" + expectedDeliveryDate : ""; 381 382 @if (!(bool?)productVariant.ProductFieldValues.Where(o => o.ProductField.SystemName == "ProductToBeDiscontinued").SingleOrDefault()?.Value ?? false) 383 { 384 if (variantStock > 0) 385 { 386 if (isNew == "true" || isSale == "true") 387 { 388 if (isSale == "true") 389 { 390 stockState += isSaleSvg + "&nbsp; &nbsp;" + Translate("Sale!") + "<br/>"; 391 } 392 393 if (isNew == "true") 394 { 395 stockState += isNewSvg + "&nbsp; &nbsp;" + Translate("New!") + "<br/>"; 396 } 397 398 stockState += "&nbsp;" + Translate("Nu leverbaar"); 399 } 400 else 401 { 402 stockState = svgInStock + "&nbsp; " + Translate("Op voorraad"); 403 404 } 405 } 406 else 407 { 408 stockState = svgOutStock + "&nbsp;" + Translate("Geen voorraad") + "<br/>" + expectedDeliveryDateText; 409 410 } 411 } 412 else 413 { 414 415 stockState = svgOutStock + "&nbsp;" + Translate("Discontinued:") + "<br/>" + variantStock + "&nbsp;" + @Translate("left in stock"); 416 417 } 418 /*End stock state*/ 419 /*Price variants*/ 420 double price = productVariant.DefaultPrice; 421 double cost = productVariant.Cost; 422 423 string priceFormated = Dynamicweb.Ecommerce.Services.Currencies.Format(Dynamicweb.Ecommerce.Services.Currencies.GetCurrency(currency), Convert.ToDouble(productPrice.ToList()[0].Amount, formatProvider)); 424 //string priceFormated = Dynamicweb.Ecommerce.Services.Currencies.Format(Dynamicweb.Ecommerce.Services.Currencies.GetCurrency(currency), Convert.ToDouble(price, formatProvider)); 425 426 427 428 /*End Price variants*/ 429 430 <img class="theme thumbnail" data-stockstate="@WebUtility.HtmlEncode(stockState)" src="/Admin/Public/GetImage.ashx?image=@(lastImageUrl)&width=64&format=webp" onclick="selectVariant('@(product.Id)','/Admin/Public/GetImage.ashx?image=@(variantImg)&format=webp','@variantLink','@product.Id','@option.Id','@option.Name',this.dataset.stockstate,'@isNew','@isSale','@priceFormated','@cost')" /> 431 432 433 } 434 } 435 436 } 437 </div> 438 <button class="thumb-nav next" onclick="scrollThumbs('@sliderId', 1)"> 439 <svg width="20px" height="20px" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" fill="#1D98A5"> 440 441 <g stroke="none" stroke-width="1" fill="none" fill-rule="evenodd"> 442 <g transform="translate(-384.000000, 0.000000)"> 443 <g id="right_line" transform="translate(384.000000, 0.000000)"> 444 <path d="M24,0 L24,24 L0,24 L0,0 L24,0 Z M12.5934901,23.257841 L12.5819402,23.2595131 L12.5108777,23.2950439 L12.4918791,23.2987469 L12.4918791,23.2987469 L12.4767152,23.2950439 L12.4056548,23.2595131 C12.3958229,23.2563662 12.3870493,23.2590235 12.3821421,23.2649074 L12.3780323,23.275831 L12.360941,23.7031097 L12.3658947,23.7234994 L12.3769048,23.7357139 L12.4804777,23.8096931 L12.4953491,23.8136134 L12.4953491,23.8136134 L12.5071152,23.8096931 L12.6106902,23.7357139 L12.6232938,23.7196733 L12.6232938,23.7196733 L12.6266527,23.7031097 L12.609561,23.275831 C12.6075724,23.2657013 12.6010112,23.2592993 12.5934901,23.257841 L12.5934901,23.257841 Z M12.8583906,23.1452862 L12.8445485,23.1473072 L12.6598443,23.2396597 L12.6498822,23.2499052 L12.6498822,23.2499052 L12.6471943,23.2611114 L12.6650943,23.6906389 L12.6699349,23.7034178 L12.6699349,23.7034178 L12.678386,23.7104931 L12.8793402,23.8032389 C12.8914285,23.8068999 12.9022333,23.8029875 12.9078286,23.7952264 L12.9118235,23.7811639 L12.8776777,23.1665331 C12.8752882,23.1545897 12.8674102,23.1470016 12.8583906,23.1452862 L12.8583906,23.1452862 Z M12.1430473,23.1473072 C12.1332178,23.1423925 12.1221763,23.1452606 12.1156365,23.1525954 L12.1099173,23.1665331 L12.0757714,23.7811639 C12.0751323,23.7926639 12.0828099,23.8018602 12.0926481,23.8045676 L12.108256,23.8032389 L12.3092106,23.7104931 L12.3186497,23.7024347 L12.3186497,23.7024347 L12.3225043,23.6906389 L12.340401,23.2611114 L12.337245,23.2485176 L12.337245,23.2485176 L12.3277531,23.2396597 L12.1430473,23.1473072 Z" id="MingCute" fill-rule="nonzero"> </path> 445 <path d="M15.7072,11.2929 C16.0977,11.6834 16.0977,12.3166 15.7072,12.7071 L10.0503,18.364 C9.65982,18.7545 9.02666,18.7545 8.63613,18.364 C8.24561,17.9734 8.24561,17.3403 8.63613,16.9497 L13.5859,12 L8.63613,7.05025 C8.24561,6.65973 8.24561,6.02656 8.63613,5.63604 C9.02666,5.24551 9.65982,5.24551 10.0503,5.63604 L15.7072,11.2929 Z" id="路径" fill="#1D98A5"> </path> 446 </g> 447 </g> 448 449 </svg> 450 451 </button> 452 </div> 453 } 454 455 456 </div> 457 458 } 459 if ((fieldValueBlocked != null && !fieldValueBlocked.ToString().Contains(customerNumber)) || String.IsNullOrWhiteSpace(customerNumber)) 460 { 461 <div class="stock-state pt-2 mt-auto"> 462 @{ 463 464 /*stock state*/ 465 double MainvariantStock = MainVariant.Stock; 466 string MainsvgInStock = "<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"16\" height=\"16\" fill=\"#44B11A\" class=\"bi bi-check-lg\" viewBox=\"0 0 16 16\"><path d=\"M12.736 3.97a.733.733 0 0 1 1.047 0c.286.289.29.756.01 1.05L7.88 12.01a.733.733 0 0 1-1.065.02L3.217 8.384a.757.757 0 0 1 0-1.06.733.733 0 0 1 1.047 0l3.052 3.093 5.4-6.425z\"/></svg>"; 467 string MainsvgOutStock = "<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"25\" height=\"25\" fill=\"#CA0D0D\" class=\"bi bi-x-lg\" viewBox=\"0 0 16 16\"><path d=\"M4.646 4.646a.5.5 0 0 1 .708 0L8 7.293l2.646-2.647a.5.5 0 0 1 .708.708L8.707 8l2.647 2.646a.5.5 0 0 1-.708.708L8 8.707l-2.646 2.647a.5.5 0 0 1-.708-.708L7.293 8 4.646 5.354a.5.5 0 0 1 0-.708\"/></svg>"; 468 469 string MaininfoStock = "<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"16\" height=\"16\" fill=\"currentColor\" class=\"bi bi-info-circle-fill\" viewBox=\"0 0 16 16\"><path d=\"M8 16A8 8 0 1 0 8 0a8 8 0 0 0 0 16m.93-9.412-1 4.705c-.07.34.029.533.304.533.194 0 .487-.07.686-.246l-.088.416c-.287.346-.92.598-1.465.598-.703 0-1.002-.422-.808-1.319l.738-3.468c.064-.293.006-.399-.287-.47l-.451-.081.082-.381 2.29-.287zM8 5.5a1 1 0 1 1 0-2 1 1 0 0 1 0 2\" /></svg>"; 470 string MainisNew = MainVariant?.ProductFieldValues?.GetProductFieldValue("New")?.Value?.ToString().ToLower() ?? ""; 471 string MainisNewSvg = "<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"16\" height=\"16\" fill=\"#F2C400\" class=\"bi bi-star-fill\" viewBox=\"0 0 16 16\"><path d = \"M3.612 15.443c-.386.198-.824-.149-.746-.592l.83-4.73L.173 6.765c-.329-.314-.158-.888.283-.95l4.898-.696L7.538.792c.197-.39.73-.39.927 0l2.184 4.327 4.898.696c.441.062.612.636.282.95l-3.522 3.356.83 4.73c.078.443-.36.79-.746.592L8 13.187l-4.389 2.256z\" /></svg> "; 472 string MainstockState = ""; 473 string MainIsSale = MainVariant?.ProductFieldValues?.GetProductFieldValue("Sale")?.Value?.ToString().ToLower() ?? ""; 474 string MainIsSaleSvg = "<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"16\" height=\"16\" fill=\"#F03232\" class=\"bi bi-star-fill\" viewBox=\"0 0 16 16\"><path d = \"M3.612 15.443c-.386.198-.824-.149-.746-.592l.83-4.73L.173 6.765c-.329-.314-.158-.888.283-.95l4.898-.696L7.538.792c.197-.39.73-.39.927 0l2.184 4.327 4.898.696c.441.062.612.636.282.95l-3.522 3.356.83 4.73c.078.443-.36.79-.746.592L8 13.187l-4.389 2.256z\" /></svg> "; 475 string MainexpectedDeliveryDate = ""; 476 477 if (DateTime.Compare(MainVariant.ExpectedDelivery, new DateTime(1900, 1, 1)) != 0) //In DW, if the Date is not set, it is defaulted 01-01-1900 and not null.. 478 { 479 MainexpectedDeliveryDate = MainVariant.ExpectedDelivery.ToShortDateString(); 480 } 481 482 string MainexpectedDeliveryDateText = !String.IsNullOrWhiteSpace(MainexpectedDeliveryDate) ? Translate("Verwacht:") + "&nbsp;" + MainexpectedDeliveryDate : ""; 483 484 @if (!(bool?)MainVariant.ProductFieldValues.Where(o => o.ProductField.SystemName == "ProductToBeDiscontinued").SingleOrDefault()?.Value ?? false) 485 { 486 if (MainvariantStock > 0) 487 { 488 if (MainisNew == "true" || MainIsSale == "true") 489 { 490 if (MainIsSale == "true") 491 { 492 MainstockState += MainIsSaleSvg + "&nbsp; &nbsp;" + Translate("Sale!") + "<br/>"; 493 } 494 495 if (MainisNew == "true") 496 { 497 MainstockState += MainisNewSvg + "&nbsp; &nbsp;" + Translate("New!") + "<br/>"; 498 } 499 500 MainstockState += "&nbsp;" + Translate("Nu leverbaar"); 501 } 502 else 503 { 504 MainstockState = MainsvgInStock + "&nbsp; " + Translate("Op voorraad"); 505 506 } 507 } 508 else 509 { 510 MainstockState = MainsvgOutStock + "&nbsp;" + Translate("Geen voorraad") + "<br/>" + MainexpectedDeliveryDateText; 511 512 } 513 } 514 else 515 { 516 517 MainstockState = MainsvgOutStock + "&nbsp;" + Translate("Discontinued:") + "<br/>" + MainvariantStock + "&nbsp;" + @Translate("left in stock"); 518 519 } 520 /*End stock state*/ 521 522 523 @MainstockState 524 525 526 } 527 </div> 528 } 529 else 530 { 531 <div class="stock-state pt-2 mt-auto"> 532 @MainOutStock @Translate("Discontinued") 533 </div> 534 } 535 <div class="custom-price mt-auto"> 536 @{ 537 538 539 540 541 bool isErpConnectionDown = !Dynamicweb.Core.Converter.ToBoolean(Dynamicweb.Context.Current.Items["IsWebServiceConnectionAvailable"]); 542 bool hidePrice = anonymousUsersLimitations.Contains("price") && anonymousUser || Pageview.AreaSettings.GetBoolean("ErpDownHidePrices") && isErpConnectionDown; 543 544 bool productIsDiscontinued = product is object && product.Discontinued; 545 bool doNotShowPriceIfProductIsDiscontinued = Model.Item.GetBoolean("DoNotShowPriceIfProductIsDiscontinued"); 546 var isDiscontinued = productIsDiscontinued && doNotShowPriceIfProductIsDiscontinued; 547 } 548 549 @if (product is object && !hidePrice && !isDiscontinued) 550 { 551 string unitId = !string.IsNullOrEmpty(Dynamicweb.Context.Current.Request.Form.Get("UnitId")) ? Dynamicweb.Context.Current.Request.Form.Get("UnitId") : string.Empty; 552 553 string priceFontSize = Model.Item.GetRawValueString("PriceSize", "fs-4"); 554 string horizontalAlign = Model.Item.GetRawValueString("HorizontalAlignment", ""); 555 string layout = Model.Item.GetRawValueString("Layout", "horizontal"); 556 string textAlign = horizontalAlign == "center" ? "text-center" : string.Empty; 557 textAlign = horizontalAlign == "end" ? "text-end" : textAlign; 558 559 horizontalAlign = horizontalAlign == "center" && layout == "horizontal" ? "justify-content-center" : horizontalAlign; 560 horizontalAlign = horizontalAlign == "end" && layout == "horizontal" ? "justify-content-end" : horizontalAlign; 561 horizontalAlign = horizontalAlign == "center" && layout == "vertical" ? "align-items-center" : horizontalAlign; 562 horizontalAlign = horizontalAlign == "end" && layout == "vertical" ? "align-items-end" : horizontalAlign; 563 564 string flexDirection = layout == "horizontal" ? string.Empty : "flex-column"; 565 string flexGap = layout == "horizontal" ? "gap-3" : string.Empty; 566 string order = layout == "horizontal" ? string.Empty : "order-2"; 567 568 569 string contentPadding = Model.Item.GetRawValueString("ContentPadding", ""); 570 contentPadding = contentPadding == "none" ? "p-0" : contentPadding; 571 contentPadding = contentPadding == "small" ? "p-1 px-md-2 py-md-1" : contentPadding; 572 contentPadding = contentPadding == "large" ? "p-2 px-md-3 py-md-2" : contentPadding; 573 string liveInfoClass = ""; 574 575 576 577 578 579 580 if (isLazyLoadingForProductInfoEnabled) 581 { 582 if (Dynamicweb.Context.Current.Items.Contains("ProductInfoFeed")) 583 { 584 productInfoFeed = Dynamicweb.Context.Current.Items["ProductInfoFeed"]?.ToString(); 585 if (!string.IsNullOrEmpty(productInfoFeed)) 586 { 587 productInfoFeed = $"data-product-info-feed=\"{productInfoFeed}\""; 588 } 589 } 590 liveInfoClass = "js-live-info"; 591 } 592 593 <div class="@textAlign @liveInfoClass item_@Model.Item.SystemName.ToLower()" data-product-id="@product.Id" data-variant-id="@product.VariantId" @productInfoFeed> 594 @if (showInformativePrice && product.PriceInformative.Price != 0) 595 { 596 <div class="opacity-50"> 597 <span>@Translate("RRP") </span> 598 <span class="text-decoration-line-through text-price">@product.PriceInformative.PriceFormatted</span> 599 </div> 600 } 601 <div class="@priceFontSize m-0 d-flex flex-wrap @flexDirection @flexGap @horizontalAlign" style="row-gap: 0 !important" itemprop="offers" itemscope itemtype="https://schema.org/Offer"> 602 <span itemprop="priceCurrency" content="@product.Price.CurrencyCode" class="d-none"></span> 603 604 605 @if (showPricesWithVat == "false" && !neverShowVat) 606 { 607 if (isLazyLoadingForProductInfoEnabled && !Pageview.IsVisualEditorMode) 608 { 609 <span itemprop="price" content="" class="d-none"></span> 610 <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> 611 } 612 else 613 { 614 string beforePrice = !string.IsNullOrEmpty(unitId) ? product.GetPrice(unitId).PriceBeforeDiscount.PriceWithoutVatFormatted : product.PriceBeforeDiscount.PriceWithoutVatFormatted; 615 616 <span itemprop="price" content="@product.Price.PriceWithoutVat.ToString("0.00", System.Globalization.CultureInfo.InvariantCulture)" class="d-none"></span> 617 if (product.Price.Price != product.PriceBeforeDiscount.Price) 618 { 619 <span class="text-decoration-line-through opacity-75 @order">@beforePrice</span> 620 } 621 } 622 } 623 else 624 { 625 if (isLazyLoadingForProductInfoEnabled && !Pageview.IsVisualEditorMode) 626 { 627 <span itemprop="price" content="" class="d-none"></span> 628 <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> 629 } 630 else 631 { 632 string beforePrice = !string.IsNullOrEmpty(unitId) ? product.GetPrice(unitId).PriceBeforeDiscount.PriceFormatted : product.PriceBeforeDiscount.PriceFormatted; 633 634 <span itemprop="price" content="@product.Price.Price.ToString("0.00", System.Globalization.CultureInfo.InvariantCulture)" class="d-none"></span> 635 636 if (product.Price.Price != product.PriceBeforeDiscount.Price) 637 { 638 <span class="text-decoration-line-through opacity-75 @order"> 639 <span class="text-price">@beforePrice</span> 640 </span> 641 } 642 } 643 } 644 645 @if (showPricesWithVat == "false" && !neverShowVat) 646 { 647 if (isLazyLoadingForProductInfoEnabled && !Pageview.IsVisualEditorMode) 648 { 649 <span class="text-price js-text-price"> 650 <span class="spinner-border" role="status"></span> 651 </span> 652 } 653 else 654 { 655 string price = !string.IsNullOrEmpty(unitId) ? product.GetPrice(unitId).Price.PriceWithoutVatFormatted : product.Price.PriceWithoutVatFormatted; 656 657 if (product?.VariantInfo?.VariantInfo != null) 658 { 659 priceMin = product?.VariantInfo?.PriceMin?.PriceWithoutVatFormatted != null ? product.VariantInfo.PriceMin.PriceWithoutVatFormatted : ""; 660 priceMax = product?.VariantInfo?.PriceMax?.PriceWithoutVatFormatted != null ? product.VariantInfo.PriceMax.PriceWithoutVatFormatted : ""; 661 } 662 if (priceMin != priceMax) 663 { 664 price = priceMin + " - " + priceMax; 665 } 666 <span class="@theme @contentPadding"> 667 <span class="text-price">@price</span> 668 </span> 669 } 670 } 671 else 672 { 673 if (isLazyLoadingForProductInfoEnabled && !Pageview.IsVisualEditorMode) 674 { 675 <span class="text-price js-text-price"> 676 <span class="spinner-border" role="status"></span> 677 </span> 678 } 679 else 680 { 681 string price = !string.IsNullOrEmpty(unitId) ? product.GetPrice(unitId).Price.PriceFormatted : product.Price.PriceFormatted; 682 683 if (product?.VariantInfo?.VariantInfo != null) 684 { 685 priceMin = product?.VariantInfo?.PriceMin?.PriceFormatted != null ? product.VariantInfo.PriceMin.PriceFormatted : ""; 686 priceMax = product?.VariantInfo?.PriceMax?.PriceFormatted != null ? product.VariantInfo.PriceMax.PriceFormatted : ""; 687 } 688 if (priceMin != priceMax) 689 { 690 price = priceMin + " - " + priceMax; 691 } 692 <span class="@theme @contentPadding"> 693 <span class="text-price">@price</span> 694 </span> 695 } 696 } 697 698 @* Stock state for Schema.org, start *@ 699 @{ 700 Uri url = Dynamicweb.Context.Current.Request.Url; 701 } 702 703 <link itemprop="url" href="@url"> 704 705 @{ 706 bool IsNeverOutOfStock = product.NeverOutOfstock; 707 } 708 709 @if (IsNeverOutOfStock) 710 { 711 <span itemprop="availability" class="d-none">@Translate("Available in stock")</span> 712 } 713 else 714 { 715 if (product.StockLevel > 0) 716 { 717 <span itemprop="availability" class="d-none">InStock</span> 718 } 719 else 720 { 721 <span itemprop="availability" class="d-none">OutOfStock</span> 722 } 723 } 724 @* Stock state for Schema.org, stop *@ 725 726 </div> 727 728 @if (showPricesWithVat == "false" && !neverShowVat) 729 { 730 if (isLazyLoadingForProductInfoEnabled && !Pageview.IsVisualEditorMode) 731 { 732 <small class="opacity-85 fst-normal js-text-price-with-vat d-none" data-suffix="@Translate("Incl. VAT")"></small> 733 } 734 else 735 { 736 string price = !string.IsNullOrEmpty(unitId) ? product.GetPrice(unitId).Price.PriceWithVatFormatted : product.Price.PriceWithVatFormatted; 737 738 if (product?.VariantInfo?.VariantInfo != null) 739 { 740 priceMin = product?.VariantInfo?.PriceMin?.PriceWithVatFormatted != null ? product.VariantInfo.PriceMin.PriceWithVatFormatted : ""; 741 priceMax = product?.VariantInfo?.PriceMax?.PriceWithVatFormatted != null ? product.VariantInfo.PriceMax.PriceWithVatFormatted : ""; 742 } 743 if (priceMin != priceMax) 744 { 745 price = priceMin + " - " + priceMax; 746 } 747 <!-- <small class="opacity-85 fst-normal">@price @Translate("Incl. VAT")</small> --> 748 } 749 } 750 </div> 751 } 752 else if (Pageview.IsVisualEditorMode) 753 { 754 <div class="alert alert-dark m-0" role="alert"> 755 <span>@Translate("No products available")</span> 756 </div> 757 } 758 759 </div> 760 } 761 } 762
Tischlampe Ø36 Korb L
Error executing template "Designs/Swift/Paragraph/CustomProductSlider.cshtml"
System.NullReferenceException: Object reference not set to an instance of an object.
   at CompiledRazorTemplates.Dynamic.RazorEngine_3562354021b44d5c892fe73dc2806e4f.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 Dynamicweb.Ecommerce.ProductCatalog 3 @using Dynamicweb.Ecommerce.CustomerExperienceCenter.Favorites 4 @using Dynamicweb.Files 5 @using System.IO 6 @using System.Net 7 @using Dynamicweb.Security.UserManagement 8 9 10 @{ 11 ProductViewModel product = null; 12 if (Dynamicweb.Context.Current.Items.Contains("ProductDetails")) 13 { 14 product = (ProductViewModel)Dynamicweb.Context.Current.Items["ProductDetails"]; 15 } 16 else if (Pageview.Page.Item["DummyProduct"] != null && Pageview.IsVisualEditorMode) 17 { 18 var pageViewModel = Dynamicweb.Frontend.ContentViewModelFactory.CreatePageInfoViewModel(Pageview.Page); 19 ProductListViewModel productList = pageViewModel.Item.GetValue("DummyProduct") != null ? pageViewModel.Item.GetValue("DummyProduct") as ProductListViewModel : new ProductListViewModel(); 20 21 if (productList?.Products is object) 22 { 23 product = productList.Products[0]; 24 } 25 } 26 } 27 28 @{ 29 var currentUser = Pageview?.User; 30 var customerNumber = !string.IsNullOrEmpty(currentUser?.CustomerNumber) 31 ? currentUser.CustomerNumber 32 : ""; 33 } 34 @if (product is object) 35 { 36 string imagePath = product?.DefaultImage?.Value ?? ""; 37 string imagePathUrlEncoded = Dynamicweb.Context.Current.Server.UrlEncode(imagePath); 38 39 string ratio = Model.Item.GetRawValueString("ImageAspectRatio", ""); 40 ratio = ratio != "0" ? ratio : ""; 41 string ratioCssClass = ratio != "" ? " ratio" : ""; 42 string ratioVariable = ratio != "" ? "--bs-aspect-ratio: " + ratio + ";" : ""; 43 44 string width = Model.Item.GetRawValueString("Width", "auto"); 45 int smallImageSize = 640; 46 int largeImageSize = width == "auto" ? 1280 : Convert.ToInt32(width); 47 48 string ImageObjectFit = Model.Item.GetRawValueString("ImageObjectFit", "contain"); 49 50 string imagePathXs = "/Admin/Public/GetImage.ashx?width=" + smallImageSize + "&image=" + imagePathUrlEncoded + "&format=webp"; 51 string imagePathS = "/Admin/Public/GetImage.ashx?width=" + largeImageSize + "&image=" + imagePathUrlEncoded + "&format=webp"; 52 string imagePathFallBack = "/Admin/Public/GetImage.ashx?width=" + largeImageSize + "&image=" + imagePathUrlEncoded + "&format=webp"; 53 54 var badgeParms = new Dictionary<string, object>(); 55 badgeParms.Add("size", "h7"); 56 badgeParms.Add("saleBadgeType", Model.Item.GetRawValue("SaleBadgeType")); 57 badgeParms.Add("saleBadgeCssClassName", Model.Item.GetRawValue("SaleBadgeDesign")); 58 badgeParms.Add("newBadgeCssClassName", Model.Item.GetRawValue("NewBadgeDesign")); 59 badgeParms.Add("newPublicationDays", Model.Item.GetInt32("NewPublicationDays")); 60 badgeParms.Add("campaignBadgesValues", Model.Item.GetList("CampaignBadges")?.GetRawValue().OfType<string>().ToList()); 61 62 string badgeSize = Model.Item.GetRawValueString("BadgeSize", "fs-2"); 63 bool saleBadgeEnabled = !string.IsNullOrWhiteSpace(Model.Item.GetRawValueString("SaleBadgeDesign")) && Model.Item.GetRawValueString("SaleBadgeDesign") != "none" ? true : false; 64 bool newBadgeEnabled = !string.IsNullOrWhiteSpace(Model.Item.GetRawValueString("NewBadgeDesign")) && Model.Item.GetRawValueString("NewBadgeDesign") != "none" ? true : false; 65 66 /*Custom badge*/ 67 var productService = new Dynamicweb.Ecommerce.Products.ProductService(); 68 var currency = Dynamicweb.Ecommerce.Common.Context.Currency.Code; 69 var formatProvider = new System.Globalization.NumberFormatInfo(); 70 formatProvider.NumberDecimalSeparator = "."; 71 formatProvider.NumberGroupSeparator = ","; 72 var MainVariant = productService.GetProductById(product.Id, product.VariantId, false); 73 var fieldValueBlocked = MainVariant?.ProductFieldValues?.GetProductFieldValue("BlockedCustomerList")?.Value; 74 75 76 string isNewProduct = MainVariant?.ProductFieldValues?.GetProductFieldValue("New")?.Value?.ToString().ToLower() ?? ""; 77 string MainisSale = MainVariant?.ProductFieldValues?.GetProductFieldValue("Sale")?.Value?.ToString().ToLower() ?? ""; 78 bool showNewBadge = isNewProduct == "true" ? true : false; 79 bool showSaleBadge = MainisSale == "true" ? true : false; 80 string showNewSaleBadge = "d-none"; 81 if (showSaleBadge) 82 { 83 badgeParms.Add("isSale", "true"); 84 85 } 86 else 87 { 88 badgeParms.Add("isSale", "false"); 89 } 90 if (showNewBadge) 91 { 92 badgeParms.Add("isNew", "true"); 93 } 94 else 95 { 96 badgeParms.Add("isNew", "false"); 97 } 98 /*End Custom badge*/ 99 if (showSaleBadge || showNewBadge) 100 { 101 showNewSaleBadge = ""; 102 } 103 DateTime createdDate = product.Created.Value; 104 bool showBadges = saleBadgeEnabled && product.Discount.Price != 0 ? true : false; 105 106 bool showFavoritesSelector = !string.IsNullOrEmpty(Model.Item.GetString("ShowAddToFavorites")) ? Model.Item.GetBoolean("ShowAddToFavorites") : false; 107 string anonymousUsersLimitations = Pageview.AreaSettings.GetRawValueString("AnonymousUsers", ""); 108 bool anonymousUser = Pageview.User == null; 109 110 var favoriteParameters = new Dictionary<string, object>(); 111 if (!anonymousUser && showFavoritesSelector) 112 { 113 int defaultFavoriteListId = 0; 114 115 IEnumerable<FavoriteList> favoreiteLists = Pageview.User.GetFavoriteLists(); 116 if (favoreiteLists.Count() == 1) 117 { 118 foreach (FavoriteList list in favoreiteLists) 119 { 120 defaultFavoriteListId = list.ListId; 121 } 122 } 123 124 favoriteParameters.Add("ListId", defaultFavoriteListId); 125 } 126 127 MediaViewModel alternativeImage = new MediaViewModel(); 128 if (Model.Item.GetBoolean("ShowAlternativeImageOnHover")) 129 { 130 var selectedImageCategories = Model.Item.GetList("GetAlternativeImageFrom")?.GetRawValue().OfType<string>().ToList(); 131 List<MediaViewModel> allAssetsImages = product.AssetCategories.Where(x => selectedImageCategories.Contains(x.SystemName)).SelectMany(x => x.Assets).ToList(); 132 allAssetsImages.RemoveAll(x => x.Value == product.DefaultImage.Value); 133 alternativeImage = allAssetsImages.FirstOrDefault(); 134 } 135 136 string altImagePathXs = string.Empty; 137 string altImagePathS = string.Empty; 138 139 if (!string.IsNullOrEmpty(alternativeImage?.Value)) 140 { 141 altImagePathXs = "/Admin/Public/GetImage.ashx?width=" + smallImageSize + "&image=" + Dynamicweb.Context.Current.Server.UrlEncode(alternativeImage.Value) + "&format=webp"; 142 altImagePathS = "/Admin/Public/GetImage.ashx?width=" + largeImageSize + "&image=" + Dynamicweb.Context.Current.Server.UrlEncode(alternativeImage.Value) + "&format=webp"; 143 } 144 145 @* Theme settings *@ 146 string theme = !string.IsNullOrWhiteSpace(Model.Item.GetRawValueString("Theme")) ? " theme " + Model.Item.GetRawValueString("Theme").Replace(" ", "").Trim().ToLower() : ""; 147 string themeBorder = !string.IsNullOrWhiteSpace(theme) ? "border: 1px solid rgba(0,0,0,0)" : ""; 148 string themePadding = !string.IsNullOrWhiteSpace(theme) ? "p-2 p-lg-3" : ""; 149 150 string imageId = "ProductImage_" + product.Id; 151 152 153 154 string fullWidth = width == "auto" ? "w-100" : ""; 155 string customWidth = width != "auto" ? "style=\"width: " + width + "px\"" : "style=\"min-width: 60px\""; 156 157 string altImageZindex = Model.Item.GetBoolean("ShowAlternativeImageOnHover") && !string.IsNullOrEmpty(alternativeImage?.Value) ? " z-index: 1" : string.Empty; 158 string groupid = !string.IsNullOrEmpty(Dynamicweb.Context.Current.Request.QueryString.Get("GroupID")) ? Dynamicweb.Context.Current.Request.QueryString.Get("GroupID"):"" ; 159 string link = product.GetProductLink(GetPageIdByNavigationTag("Shop"), false); 160 var productVariantGroups = product.VariantGroups(); 161 string MainOutStock = "<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"25\" height=\"25\" fill=\"#CA0D0D\" class=\"bi bi-x-lg\" viewBox=\"0 0 16 16\"><path d=\"M4.646 4.646a.5.5 0 0 1 .708 0L8 7.293l2.646-2.647a.5.5 0 0 1 .708.708L8.707 8l2.647 2.646a.5.5 0 0 1-.708.708L8 8.707l-2.646 2.647a.5.5 0 0 1-.708-.708L7.293 8 4.646 5.354a.5.5 0 0 1 0-.708\"/></svg>"; 162 163 @if (!string.IsNullOrEmpty(imagePath)) 164 { 165 <div class="@fullWidth @theme position-relative item_@Model.Item.SystemName.ToLower() main-image-container" @customWidth> 166 <div class="" style="@(ratioVariable)@(altImageZindex)"> 167 <div class="d-flex justify-content-center align-items-center"> 168 <a class="main-link-link" href="@link"> 169 @if (imagePath.StartsWith("/Files/", StringComparison.OrdinalIgnoreCase)) 170 { 171 <img id="@imageId" 172 srcset=" 173 @imagePathXs @(smallImageSize)w, 174 @imagePathS @(largeImageSize)w" 175 sizes="(max-width: 992px) 50vw, 25vw" 176 src="@imagePathFallBack" 177 loading="lazy" 178 decoding="async" 179 class="h-100 w-100 @themePadding main-image" 180 style="object-fit: @ImageObjectFit; @themeBorder " 181 alt="@product.Name" 182 itemprop="image"> 183 } 184 else 185 { 186 <img src="@product.DefaultImage.Value" 187 loading="lazy" 188 class="h-100 w-100 @themePadding main-image" 189 style="object-fit: contain; @themeBorder" 190 alt="@product.Name" 191 itemprop="image"> 192 } 193 </a> 194 </div> 195 </div> 196 197 <div class="position-absolute top-0 left-0 p-2 pb-0 custom-badge-product-list @showNewSaleBadge"> 198 @{ 199 @RenderPartial("Components/Custom_EcommerceBadge.cshtml", product, badgeParms) 200 } 201 </div> 202 203 204 </div> 205 } 206 207 <div class="product-info h-100"> 208 <div class="fs-7 pt-1 opacity-85 start item_@Model.Item.SystemName.ToLower() product-number" itemprop="sku">@product.Id / @product.VariantId - @product.VariantName</div> 209 <div class="py-2" data-col-size="12"> 210 <h2 class="h6 start m-0 item_swift_productheader product-name" itemprop="name"><b>@product.Name</b></h2> 211 </div> 212 </div> 213 var sliderId = $"thumb-scroll-{product.Id}"; 214 if (productVariantGroups.Any() && product?.VariantInfo?.VariantInfo != null) 215 216 { 217 @using Dynamicweb.Ecommerce.Prices 218 @{ 219 string[] variantId = product.VariantId.Split('.'); 220 string showPricesWithVat = Pageview.Area.EcomPricesWithVat.ToLower(); 221 bool neverShowVat = string.IsNullOrEmpty(showPricesWithVat); 222 bool showInformativePrice = Model.Item.GetBoolean("ShowInformativePrice"); 223 string productInfoFeed = ""; 224 bool isLazyLoadingForProductInfoEnabled = Dynamicweb.Core.Converter.ToBoolean(Dynamicweb.Context.Current.Items["IsLazyLoadingForProductInfoEnabled"]); 225 if (isLazyLoadingForProductInfoEnabled) 226 { 227 if (Dynamicweb.Context.Current.Items.Contains("ProductInfoFeed")) 228 { 229 productInfoFeed = Dynamicweb.Context.Current.Items["ProductInfoFeed"]?.ToString(); 230 if (!string.IsNullOrEmpty(productInfoFeed)) 231 { 232 productInfoFeed =productInfoFeed; 233 } 234 } 235 236 } 237 string priceMin = ""; 238 string priceMax = ""; 239 int groupNumber = 1; 240 241 242 243 244 string baseUrl = $"Default.aspx?ID={GetPageIdByNavigationTag("Shop")}&GroupID={product.PrimaryOrDefaultGroup.Id}&ProductID={product.Id}"; 245 if (!string.IsNullOrEmpty(baseUrl)) 246 { 247 baseUrl = $"/{baseUrl.TrimStart('/')}"; 248 } 249 string variantUrl = string.Empty; 250 251 252 Dictionary<string, string> 253 variantImages = new Dictionary<string, string> 254 (); 255 <div class="last-row mt-auto"> 256 257 @foreach (var variantGroup in productVariantGroups) 258 { 259 <div class="thumbnail-wrapper"> 260 <button class="thumb-nav prev" onclick="scrollThumbs('@sliderId', -1)"> 261 <svg width="20px" height="20px" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" fill="#1D98A5"> 262 263 <g stroke="none" stroke-width="1" fill="none" fill-rule="evenodd"> 264 <g transform="translate(-336.000000, 0.000000)"> 265 <g id="left_line" transform="translate(336.000000, 0.000000)"> 266 <path d="M24,0 L24,24 L0,24 L0,0 L24,0 Z M12.5934901,23.257841 L12.5819402,23.2595131 L12.5108777,23.2950439 L12.4918791,23.2987469 L12.4918791,23.2987469 L12.4767152,23.2950439 L12.4056548,23.2595131 C12.3958229,23.2563662 12.3870493,23.2590235 12.3821421,23.2649074 L12.3780323,23.275831 L12.360941,23.7031097 L12.3658947,23.7234994 L12.3769048,23.7357139 L12.4804777,23.8096931 L12.4953491,23.8136134 L12.4953491,23.8136134 L12.5071152,23.8096931 L12.6106902,23.7357139 L12.6232938,23.7196733 L12.6232938,23.7196733 L12.6266527,23.7031097 L12.609561,23.275831 C12.6075724,23.2657013 12.6010112,23.2592993 12.5934901,23.257841 L12.5934901,23.257841 Z M12.8583906,23.1452862 L12.8445485,23.1473072 L12.6598443,23.2396597 L12.6498822,23.2499052 L12.6498822,23.2499052 L12.6471943,23.2611114 L12.6650943,23.6906389 L12.6699349,23.7034178 L12.6699349,23.7034178 L12.678386,23.7104931 L12.8793402,23.8032389 C12.8914285,23.8068999 12.9022333,23.8029875 12.9078286,23.7952264 L12.9118235,23.7811639 L12.8776777,23.1665331 C12.8752882,23.1545897 12.8674102,23.1470016 12.8583906,23.1452862 L12.8583906,23.1452862 Z M12.1430473,23.1473072 C12.1332178,23.1423925 12.1221763,23.1452606 12.1156365,23.1525954 L12.1099173,23.1665331 L12.0757714,23.7811639 C12.0751323,23.7926639 12.0828099,23.8018602 12.0926481,23.8045676 L12.108256,23.8032389 L12.3092106,23.7104931 L12.3186497,23.7024347 L12.3186497,23.7024347 L12.3225043,23.6906389 L12.340401,23.2611114 L12.337245,23.2485176 L12.337245,23.2485176 L12.3277531,23.2396597 L12.1430473,23.1473072 Z" id="MingCute" fill-rule="nonzero"> </path> 267 <path d="M8.29292,12.7071 C7.9024,12.3166 7.9024,11.6834 8.29292,11.2929 L13.9498,5.63604 C14.3403,5.24551 14.9735,5.24551 15.364,5.63604 C15.7545,6.02656 15.7545,6.65973 15.364,7.05025 L10.4142,12 L15.364,16.9497 C15.7545,17.3403 15.7545,17.9734 15.364,18.364 C14.9735,18.7545 14.3403,18.7545 13.9498,18.364 L8.29292,12.7071 Z" id="路径" fill="#1D98A5"> </path> 268 </g> 269 </g> 270 </g> 271 </svg> 272 273 </button> 274 <div class="thumbnail-scroll" id="@sliderId"> 275 @{ 276 VariantGroupViewModel group = variantGroup; 277 foreach (var option in group.Options.OrderBy(o => o.Id)) 278 { 279 var productVariant = productService.GetProductById(product.Id, option.Id, false); 280 281 var productSelection = new PriceProductSelection(productVariant, null, 0); 282 283 var currencyCode = string.IsNullOrWhiteSpace(Pageview.User.Currency) ? Pageview.Area.EcomCurrencyId : Pageview.User.Currency; 284 var countryCode = string.IsNullOrWhiteSpace(Pageview.User.CountryCode) ? Pageview.Area.EcomCountryCode : Pageview.User.CountryCode; 285 286 var userCurrency = Dynamicweb.Ecommerce.Services.Currencies.GetCurrency(currencyCode); 287 var userCountry = Dynamicweb.Ecommerce.Services.Countries.GetCountry(countryCode); 288 289 var priceContext = new PriceContext(userCurrency, userCountry, null, Pageview.User, false, null); 290 var productPrice = Dynamicweb.Ecommerce.Services.Prices.FindPrices(priceContext, productSelection, false); 291 292 //throw new Exception(System.Text.Json.JsonSerializer.Serialize(productPrice)); 293 294 var fieldValue = productVariant?.ProductFieldValues?.GetProductFieldValue("BlockedCustomerList")?.Value; 295 296 if ((fieldValue != null && !fieldValue.ToString().Contains(customerNumber)) || String.IsNullOrWhiteSpace(customerNumber)) 297 { 298 299 300 string active = variantId != null && variantId.Contains(option.Id) ? "active" : string.Empty; 301 string buttonId = $"{product.Id}_{option.Id}_{Pageview.CurrentParagraph.ID}"; 302 string contrastColor = string.Empty; 303 304 string searchKey = $"{product.Id}_{option.Id}_"; 305 /*Images*/ 306 var imagePathVariant = option.Image?.Value ?? ""; 307 308 309 var folderPath = Path.GetDirectoryName(imagePathVariant); 310 311 string physicalFolderPath = Dynamicweb.Context.Current.Server.MapPath(folderPath); 312 313 string lastImage = null; 314 315 if (Directory.Exists(physicalFolderPath)) 316 { 317 318 var fileWith15 = Directory.GetFiles(physicalFolderPath) 319 .FirstOrDefault(f => Path.GetFileName(f).Contains($"{product.Id}_{option.Id}_9")); 320 321 if (fileWith15 != null) 322 { 323 lastImage = fileWith15; 324 } 325 else 326 { 327 var files = Directory.GetFiles(physicalFolderPath) 328 .Where(f => Path.GetFileName(f).StartsWith($"{product.Id}_{option.Id}_")) 329 .OrderByDescending(f => 330 { 331 var filename = Path.GetFileNameWithoutExtension(f); 332 var match = System.Text.RegularExpressions.Regex.Match(filename, @"_(\d+)$"); 333 if (match.Success && int.TryParse(match.Groups[1].Value, out int index)) 334 { 335 return index; 336 } 337 return 0; 338 }) 339 .ToList(); 340 341 if (files.Any()) 342 { 343 lastImage = files.First(); 344 } 345 } 346 } 347 348 var lastImageUrl = lastImage != null ? lastImage : "/Files/Images/zijlstra/Afbeeldingen_overig/Coming_Soon.jpg"; 349 int index = lastImageUrl.IndexOf("Files"); 350 string relativePath = index >= 0 ? lastImageUrl.Substring(index).Replace("\\", "/") : lastImageUrl.Replace("\\", "/"); 351 lastImageUrl = "/" + relativePath; 352 lastImageUrl = Dynamicweb.Context.Current.Server.UrlEncode(lastImageUrl); 353 var variantImg = option.Image is object ? Dynamicweb.Context.Current.Server.UrlEncode(option.Image.Value) : null; 354 var variantLink = "/Default.aspx?ID=" + GetPageIdByNavigationTag("Shop") + "&GroupID=" + product.PrimaryOrDefaultGroup.Id + "&ProductID=" + product.Id + "&VariantID=" + option.Id; 355 356 string variantImage = string.Empty; 357 variantImages.TryGetValue(option.Id, out variantImage); 358 /*End Images*/ 359 360 /*stock state*/ 361 double variantStock = productVariant.Stock; 362 string svgInStock = "<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"16\" height=\"16\" fill=\"#44B11A\" class=\"bi bi-check-lg\" viewBox=\"0 0 16 16\"><path d=\"M12.736 3.97a.733.733 0 0 1 1.047 0c.286.289.29.756.01 1.05L7.88 12.01a.733.733 0 0 1-1.065.02L3.217 8.384a.757.757 0 0 1 0-1.06.733.733 0 0 1 1.047 0l3.052 3.093 5.4-6.425z\"/></svg>"; 363 string svgOutStock = "<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"25\" height=\"25\" fill=\"#CA0D0D\" class=\"bi bi-x-lg\" viewBox=\"0 0 16 16\"><path d=\"M4.646 4.646a.5.5 0 0 1 .708 0L8 7.293l2.646-2.647a.5.5 0 0 1 .708.708L8.707 8l2.647 2.646a.5.5 0 0 1-.708.708L8 8.707l-2.646 2.647a.5.5 0 0 1-.708-.708L7.293 8 4.646 5.354a.5.5 0 0 1 0-.708\"/></svg>"; 364 365 string infoStock = "<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"16\" height=\"16\" fill=\"currentColor\" class=\"bi bi-info-circle-fill\" viewBox=\"0 0 16 16\"><path d=\"M8 16A8 8 0 1 0 8 0a8 8 0 0 0 0 16m.93-9.412-1 4.705c-.07.34.029.533.304.533.194 0 .487-.07.686-.246l-.088.416c-.287.346-.92.598-1.465.598-.703 0-1.002-.422-.808-1.319l.738-3.468c.064-.293.006-.399-.287-.47l-.451-.081.082-.381 2.29-.287zM8 5.5a1 1 0 1 1 0-2 1 1 0 0 1 0 2\" /></svg>"; 366 string isNew = productVariant?.ProductFieldValues?.GetProductFieldValue("New")?.Value?.ToString().ToLower() ?? ""; 367 string isNewSvg = "<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"16\" height=\"16\" fill=\"#F2C400\" class=\"bi bi-star-fill\" viewBox=\"0 0 16 16\"><path d = \"M3.612 15.443c-.386.198-.824-.149-.746-.592l.83-4.73L.173 6.765c-.329-.314-.158-.888.283-.95l4.898-.696L7.538.792c.197-.39.73-.39.927 0l2.184 4.327 4.898.696c.441.062.612.636.282.95l-3.522 3.356.83 4.73c.078.443-.36.79-.746.592L8 13.187l-4.389 2.256z\" /></svg> "; 368 string stockState = ""; 369 370 string isSale = productVariant?.ProductFieldValues?.GetProductFieldValue("Sale")?.Value?.ToString().ToLower() ?? ""; 371 string isSaleSvg = "<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"16\" height=\"16\" fill=\"#F03232\" class=\"bi bi-star-fill\" viewBox=\"0 0 16 16\"><path d = \"M3.612 15.443c-.386.198-.824-.149-.746-.592l.83-4.73L.173 6.765c-.329-.314-.158-.888.283-.95l4.898-.696L7.538.792c.197-.39.73-.39.927 0l2.184 4.327 4.898.696c.441.062.612.636.282.95l-3.522 3.356.83 4.73c.078.443-.36.79-.746.592L8 13.187l-4.389 2.256z\" /></svg> "; 372 373 string expectedDeliveryDate = ""; 374 375 if (DateTime.Compare(productVariant.ExpectedDelivery, new DateTime(1900, 1, 1)) != 0) //In DW, if the Date is not set, it is defaulted 01-01-1900 and not null.. 376 { 377 expectedDeliveryDate = productVariant.ExpectedDelivery.ToShortDateString(); 378 } 379 380 string expectedDeliveryDateText = !String.IsNullOrWhiteSpace(expectedDeliveryDate) ? Translate("Verwacht:") + "&nbsp;" + expectedDeliveryDate : ""; 381 382 @if (!(bool?)productVariant.ProductFieldValues.Where(o => o.ProductField.SystemName == "ProductToBeDiscontinued").SingleOrDefault()?.Value ?? false) 383 { 384 if (variantStock > 0) 385 { 386 if (isNew == "true" || isSale == "true") 387 { 388 if (isSale == "true") 389 { 390 stockState += isSaleSvg + "&nbsp; &nbsp;" + Translate("Sale!") + "<br/>"; 391 } 392 393 if (isNew == "true") 394 { 395 stockState += isNewSvg + "&nbsp; &nbsp;" + Translate("New!") + "<br/>"; 396 } 397 398 stockState += "&nbsp;" + Translate("Nu leverbaar"); 399 } 400 else 401 { 402 stockState = svgInStock + "&nbsp; " + Translate("Op voorraad"); 403 404 } 405 } 406 else 407 { 408 stockState = svgOutStock + "&nbsp;" + Translate("Geen voorraad") + "<br/>" + expectedDeliveryDateText; 409 410 } 411 } 412 else 413 { 414 415 stockState = svgOutStock + "&nbsp;" + Translate("Discontinued:") + "<br/>" + variantStock + "&nbsp;" + @Translate("left in stock"); 416 417 } 418 /*End stock state*/ 419 /*Price variants*/ 420 double price = productVariant.DefaultPrice; 421 double cost = productVariant.Cost; 422 423 string priceFormated = Dynamicweb.Ecommerce.Services.Currencies.Format(Dynamicweb.Ecommerce.Services.Currencies.GetCurrency(currency), Convert.ToDouble(productPrice.ToList()[0].Amount, formatProvider)); 424 //string priceFormated = Dynamicweb.Ecommerce.Services.Currencies.Format(Dynamicweb.Ecommerce.Services.Currencies.GetCurrency(currency), Convert.ToDouble(price, formatProvider)); 425 426 427 428 /*End Price variants*/ 429 430 <img class="theme thumbnail" data-stockstate="@WebUtility.HtmlEncode(stockState)" src="/Admin/Public/GetImage.ashx?image=@(lastImageUrl)&width=64&format=webp" onclick="selectVariant('@(product.Id)','/Admin/Public/GetImage.ashx?image=@(variantImg)&format=webp','@variantLink','@product.Id','@option.Id','@option.Name',this.dataset.stockstate,'@isNew','@isSale','@priceFormated','@cost')" /> 431 432 433 } 434 } 435 436 } 437 </div> 438 <button class="thumb-nav next" onclick="scrollThumbs('@sliderId', 1)"> 439 <svg width="20px" height="20px" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" fill="#1D98A5"> 440 441 <g stroke="none" stroke-width="1" fill="none" fill-rule="evenodd"> 442 <g transform="translate(-384.000000, 0.000000)"> 443 <g id="right_line" transform="translate(384.000000, 0.000000)"> 444 <path d="M24,0 L24,24 L0,24 L0,0 L24,0 Z M12.5934901,23.257841 L12.5819402,23.2595131 L12.5108777,23.2950439 L12.4918791,23.2987469 L12.4918791,23.2987469 L12.4767152,23.2950439 L12.4056548,23.2595131 C12.3958229,23.2563662 12.3870493,23.2590235 12.3821421,23.2649074 L12.3780323,23.275831 L12.360941,23.7031097 L12.3658947,23.7234994 L12.3769048,23.7357139 L12.4804777,23.8096931 L12.4953491,23.8136134 L12.4953491,23.8136134 L12.5071152,23.8096931 L12.6106902,23.7357139 L12.6232938,23.7196733 L12.6232938,23.7196733 L12.6266527,23.7031097 L12.609561,23.275831 C12.6075724,23.2657013 12.6010112,23.2592993 12.5934901,23.257841 L12.5934901,23.257841 Z M12.8583906,23.1452862 L12.8445485,23.1473072 L12.6598443,23.2396597 L12.6498822,23.2499052 L12.6498822,23.2499052 L12.6471943,23.2611114 L12.6650943,23.6906389 L12.6699349,23.7034178 L12.6699349,23.7034178 L12.678386,23.7104931 L12.8793402,23.8032389 C12.8914285,23.8068999 12.9022333,23.8029875 12.9078286,23.7952264 L12.9118235,23.7811639 L12.8776777,23.1665331 C12.8752882,23.1545897 12.8674102,23.1470016 12.8583906,23.1452862 L12.8583906,23.1452862 Z M12.1430473,23.1473072 C12.1332178,23.1423925 12.1221763,23.1452606 12.1156365,23.1525954 L12.1099173,23.1665331 L12.0757714,23.7811639 C12.0751323,23.7926639 12.0828099,23.8018602 12.0926481,23.8045676 L12.108256,23.8032389 L12.3092106,23.7104931 L12.3186497,23.7024347 L12.3186497,23.7024347 L12.3225043,23.6906389 L12.340401,23.2611114 L12.337245,23.2485176 L12.337245,23.2485176 L12.3277531,23.2396597 L12.1430473,23.1473072 Z" id="MingCute" fill-rule="nonzero"> </path> 445 <path d="M15.7072,11.2929 C16.0977,11.6834 16.0977,12.3166 15.7072,12.7071 L10.0503,18.364 C9.65982,18.7545 9.02666,18.7545 8.63613,18.364 C8.24561,17.9734 8.24561,17.3403 8.63613,16.9497 L13.5859,12 L8.63613,7.05025 C8.24561,6.65973 8.24561,6.02656 8.63613,5.63604 C9.02666,5.24551 9.65982,5.24551 10.0503,5.63604 L15.7072,11.2929 Z" id="路径" fill="#1D98A5"> </path> 446 </g> 447 </g> 448 449 </svg> 450 451 </button> 452 </div> 453 } 454 455 456 </div> 457 458 } 459 if ((fieldValueBlocked != null && !fieldValueBlocked.ToString().Contains(customerNumber)) || String.IsNullOrWhiteSpace(customerNumber)) 460 { 461 <div class="stock-state pt-2 mt-auto"> 462 @{ 463 464 /*stock state*/ 465 double MainvariantStock = MainVariant.Stock; 466 string MainsvgInStock = "<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"16\" height=\"16\" fill=\"#44B11A\" class=\"bi bi-check-lg\" viewBox=\"0 0 16 16\"><path d=\"M12.736 3.97a.733.733 0 0 1 1.047 0c.286.289.29.756.01 1.05L7.88 12.01a.733.733 0 0 1-1.065.02L3.217 8.384a.757.757 0 0 1 0-1.06.733.733 0 0 1 1.047 0l3.052 3.093 5.4-6.425z\"/></svg>"; 467 string MainsvgOutStock = "<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"25\" height=\"25\" fill=\"#CA0D0D\" class=\"bi bi-x-lg\" viewBox=\"0 0 16 16\"><path d=\"M4.646 4.646a.5.5 0 0 1 .708 0L8 7.293l2.646-2.647a.5.5 0 0 1 .708.708L8.707 8l2.647 2.646a.5.5 0 0 1-.708.708L8 8.707l-2.646 2.647a.5.5 0 0 1-.708-.708L7.293 8 4.646 5.354a.5.5 0 0 1 0-.708\"/></svg>"; 468 469 string MaininfoStock = "<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"16\" height=\"16\" fill=\"currentColor\" class=\"bi bi-info-circle-fill\" viewBox=\"0 0 16 16\"><path d=\"M8 16A8 8 0 1 0 8 0a8 8 0 0 0 0 16m.93-9.412-1 4.705c-.07.34.029.533.304.533.194 0 .487-.07.686-.246l-.088.416c-.287.346-.92.598-1.465.598-.703 0-1.002-.422-.808-1.319l.738-3.468c.064-.293.006-.399-.287-.47l-.451-.081.082-.381 2.29-.287zM8 5.5a1 1 0 1 1 0-2 1 1 0 0 1 0 2\" /></svg>"; 470 string MainisNew = MainVariant?.ProductFieldValues?.GetProductFieldValue("New")?.Value?.ToString().ToLower() ?? ""; 471 string MainisNewSvg = "<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"16\" height=\"16\" fill=\"#F2C400\" class=\"bi bi-star-fill\" viewBox=\"0 0 16 16\"><path d = \"M3.612 15.443c-.386.198-.824-.149-.746-.592l.83-4.73L.173 6.765c-.329-.314-.158-.888.283-.95l4.898-.696L7.538.792c.197-.39.73-.39.927 0l2.184 4.327 4.898.696c.441.062.612.636.282.95l-3.522 3.356.83 4.73c.078.443-.36.79-.746.592L8 13.187l-4.389 2.256z\" /></svg> "; 472 string MainstockState = ""; 473 string MainIsSale = MainVariant?.ProductFieldValues?.GetProductFieldValue("Sale")?.Value?.ToString().ToLower() ?? ""; 474 string MainIsSaleSvg = "<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"16\" height=\"16\" fill=\"#F03232\" class=\"bi bi-star-fill\" viewBox=\"0 0 16 16\"><path d = \"M3.612 15.443c-.386.198-.824-.149-.746-.592l.83-4.73L.173 6.765c-.329-.314-.158-.888.283-.95l4.898-.696L7.538.792c.197-.39.73-.39.927 0l2.184 4.327 4.898.696c.441.062.612.636.282.95l-3.522 3.356.83 4.73c.078.443-.36.79-.746.592L8 13.187l-4.389 2.256z\" /></svg> "; 475 string MainexpectedDeliveryDate = ""; 476 477 if (DateTime.Compare(MainVariant.ExpectedDelivery, new DateTime(1900, 1, 1)) != 0) //In DW, if the Date is not set, it is defaulted 01-01-1900 and not null.. 478 { 479 MainexpectedDeliveryDate = MainVariant.ExpectedDelivery.ToShortDateString(); 480 } 481 482 string MainexpectedDeliveryDateText = !String.IsNullOrWhiteSpace(MainexpectedDeliveryDate) ? Translate("Verwacht:") + "&nbsp;" + MainexpectedDeliveryDate : ""; 483 484 @if (!(bool?)MainVariant.ProductFieldValues.Where(o => o.ProductField.SystemName == "ProductToBeDiscontinued").SingleOrDefault()?.Value ?? false) 485 { 486 if (MainvariantStock > 0) 487 { 488 if (MainisNew == "true" || MainIsSale == "true") 489 { 490 if (MainIsSale == "true") 491 { 492 MainstockState += MainIsSaleSvg + "&nbsp; &nbsp;" + Translate("Sale!") + "<br/>"; 493 } 494 495 if (MainisNew == "true") 496 { 497 MainstockState += MainisNewSvg + "&nbsp; &nbsp;" + Translate("New!") + "<br/>"; 498 } 499 500 MainstockState += "&nbsp;" + Translate("Nu leverbaar"); 501 } 502 else 503 { 504 MainstockState = MainsvgInStock + "&nbsp; " + Translate("Op voorraad"); 505 506 } 507 } 508 else 509 { 510 MainstockState = MainsvgOutStock + "&nbsp;" + Translate("Geen voorraad") + "<br/>" + MainexpectedDeliveryDateText; 511 512 } 513 } 514 else 515 { 516 517 MainstockState = MainsvgOutStock + "&nbsp;" + Translate("Discontinued:") + "<br/>" + MainvariantStock + "&nbsp;" + @Translate("left in stock"); 518 519 } 520 /*End stock state*/ 521 522 523 @MainstockState 524 525 526 } 527 </div> 528 } 529 else 530 { 531 <div class="stock-state pt-2 mt-auto"> 532 @MainOutStock @Translate("Discontinued") 533 </div> 534 } 535 <div class="custom-price mt-auto"> 536 @{ 537 538 539 540 541 bool isErpConnectionDown = !Dynamicweb.Core.Converter.ToBoolean(Dynamicweb.Context.Current.Items["IsWebServiceConnectionAvailable"]); 542 bool hidePrice = anonymousUsersLimitations.Contains("price") && anonymousUser || Pageview.AreaSettings.GetBoolean("ErpDownHidePrices") && isErpConnectionDown; 543 544 bool productIsDiscontinued = product is object && product.Discontinued; 545 bool doNotShowPriceIfProductIsDiscontinued = Model.Item.GetBoolean("DoNotShowPriceIfProductIsDiscontinued"); 546 var isDiscontinued = productIsDiscontinued && doNotShowPriceIfProductIsDiscontinued; 547 } 548 549 @if (product is object && !hidePrice && !isDiscontinued) 550 { 551 string unitId = !string.IsNullOrEmpty(Dynamicweb.Context.Current.Request.Form.Get("UnitId")) ? Dynamicweb.Context.Current.Request.Form.Get("UnitId") : string.Empty; 552 553 string priceFontSize = Model.Item.GetRawValueString("PriceSize", "fs-4"); 554 string horizontalAlign = Model.Item.GetRawValueString("HorizontalAlignment", ""); 555 string layout = Model.Item.GetRawValueString("Layout", "horizontal"); 556 string textAlign = horizontalAlign == "center" ? "text-center" : string.Empty; 557 textAlign = horizontalAlign == "end" ? "text-end" : textAlign; 558 559 horizontalAlign = horizontalAlign == "center" && layout == "horizontal" ? "justify-content-center" : horizontalAlign; 560 horizontalAlign = horizontalAlign == "end" && layout == "horizontal" ? "justify-content-end" : horizontalAlign; 561 horizontalAlign = horizontalAlign == "center" && layout == "vertical" ? "align-items-center" : horizontalAlign; 562 horizontalAlign = horizontalAlign == "end" && layout == "vertical" ? "align-items-end" : horizontalAlign; 563 564 string flexDirection = layout == "horizontal" ? string.Empty : "flex-column"; 565 string flexGap = layout == "horizontal" ? "gap-3" : string.Empty; 566 string order = layout == "horizontal" ? string.Empty : "order-2"; 567 568 569 string contentPadding = Model.Item.GetRawValueString("ContentPadding", ""); 570 contentPadding = contentPadding == "none" ? "p-0" : contentPadding; 571 contentPadding = contentPadding == "small" ? "p-1 px-md-2 py-md-1" : contentPadding; 572 contentPadding = contentPadding == "large" ? "p-2 px-md-3 py-md-2" : contentPadding; 573 string liveInfoClass = ""; 574 575 576 577 578 579 580 if (isLazyLoadingForProductInfoEnabled) 581 { 582 if (Dynamicweb.Context.Current.Items.Contains("ProductInfoFeed")) 583 { 584 productInfoFeed = Dynamicweb.Context.Current.Items["ProductInfoFeed"]?.ToString(); 585 if (!string.IsNullOrEmpty(productInfoFeed)) 586 { 587 productInfoFeed = $"data-product-info-feed=\"{productInfoFeed}\""; 588 } 589 } 590 liveInfoClass = "js-live-info"; 591 } 592 593 <div class="@textAlign @liveInfoClass item_@Model.Item.SystemName.ToLower()" data-product-id="@product.Id" data-variant-id="@product.VariantId" @productInfoFeed> 594 @if (showInformativePrice && product.PriceInformative.Price != 0) 595 { 596 <div class="opacity-50"> 597 <span>@Translate("RRP") </span> 598 <span class="text-decoration-line-through text-price">@product.PriceInformative.PriceFormatted</span> 599 </div> 600 } 601 <div class="@priceFontSize m-0 d-flex flex-wrap @flexDirection @flexGap @horizontalAlign" style="row-gap: 0 !important" itemprop="offers" itemscope itemtype="https://schema.org/Offer"> 602 <span itemprop="priceCurrency" content="@product.Price.CurrencyCode" class="d-none"></span> 603 604 605 @if (showPricesWithVat == "false" && !neverShowVat) 606 { 607 if (isLazyLoadingForProductInfoEnabled && !Pageview.IsVisualEditorMode) 608 { 609 <span itemprop="price" content="" class="d-none"></span> 610 <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> 611 } 612 else 613 { 614 string beforePrice = !string.IsNullOrEmpty(unitId) ? product.GetPrice(unitId).PriceBeforeDiscount.PriceWithoutVatFormatted : product.PriceBeforeDiscount.PriceWithoutVatFormatted; 615 616 <span itemprop="price" content="@product.Price.PriceWithoutVat.ToString("0.00", System.Globalization.CultureInfo.InvariantCulture)" class="d-none"></span> 617 if (product.Price.Price != product.PriceBeforeDiscount.Price) 618 { 619 <span class="text-decoration-line-through opacity-75 @order">@beforePrice</span> 620 } 621 } 622 } 623 else 624 { 625 if (isLazyLoadingForProductInfoEnabled && !Pageview.IsVisualEditorMode) 626 { 627 <span itemprop="price" content="" class="d-none"></span> 628 <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> 629 } 630 else 631 { 632 string beforePrice = !string.IsNullOrEmpty(unitId) ? product.GetPrice(unitId).PriceBeforeDiscount.PriceFormatted : product.PriceBeforeDiscount.PriceFormatted; 633 634 <span itemprop="price" content="@product.Price.Price.ToString("0.00", System.Globalization.CultureInfo.InvariantCulture)" class="d-none"></span> 635 636 if (product.Price.Price != product.PriceBeforeDiscount.Price) 637 { 638 <span class="text-decoration-line-through opacity-75 @order"> 639 <span class="text-price">@beforePrice</span> 640 </span> 641 } 642 } 643 } 644 645 @if (showPricesWithVat == "false" && !neverShowVat) 646 { 647 if (isLazyLoadingForProductInfoEnabled && !Pageview.IsVisualEditorMode) 648 { 649 <span class="text-price js-text-price"> 650 <span class="spinner-border" role="status"></span> 651 </span> 652 } 653 else 654 { 655 string price = !string.IsNullOrEmpty(unitId) ? product.GetPrice(unitId).Price.PriceWithoutVatFormatted : product.Price.PriceWithoutVatFormatted; 656 657 if (product?.VariantInfo?.VariantInfo != null) 658 { 659 priceMin = product?.VariantInfo?.PriceMin?.PriceWithoutVatFormatted != null ? product.VariantInfo.PriceMin.PriceWithoutVatFormatted : ""; 660 priceMax = product?.VariantInfo?.PriceMax?.PriceWithoutVatFormatted != null ? product.VariantInfo.PriceMax.PriceWithoutVatFormatted : ""; 661 } 662 if (priceMin != priceMax) 663 { 664 price = priceMin + " - " + priceMax; 665 } 666 <span class="@theme @contentPadding"> 667 <span class="text-price">@price</span> 668 </span> 669 } 670 } 671 else 672 { 673 if (isLazyLoadingForProductInfoEnabled && !Pageview.IsVisualEditorMode) 674 { 675 <span class="text-price js-text-price"> 676 <span class="spinner-border" role="status"></span> 677 </span> 678 } 679 else 680 { 681 string price = !string.IsNullOrEmpty(unitId) ? product.GetPrice(unitId).Price.PriceFormatted : product.Price.PriceFormatted; 682 683 if (product?.VariantInfo?.VariantInfo != null) 684 { 685 priceMin = product?.VariantInfo?.PriceMin?.PriceFormatted != null ? product.VariantInfo.PriceMin.PriceFormatted : ""; 686 priceMax = product?.VariantInfo?.PriceMax?.PriceFormatted != null ? product.VariantInfo.PriceMax.PriceFormatted : ""; 687 } 688 if (priceMin != priceMax) 689 { 690 price = priceMin + " - " + priceMax; 691 } 692 <span class="@theme @contentPadding"> 693 <span class="text-price">@price</span> 694 </span> 695 } 696 } 697 698 @* Stock state for Schema.org, start *@ 699 @{ 700 Uri url = Dynamicweb.Context.Current.Request.Url; 701 } 702 703 <link itemprop="url" href="@url"> 704 705 @{ 706 bool IsNeverOutOfStock = product.NeverOutOfstock; 707 } 708 709 @if (IsNeverOutOfStock) 710 { 711 <span itemprop="availability" class="d-none">@Translate("Available in stock")</span> 712 } 713 else 714 { 715 if (product.StockLevel > 0) 716 { 717 <span itemprop="availability" class="d-none">InStock</span> 718 } 719 else 720 { 721 <span itemprop="availability" class="d-none">OutOfStock</span> 722 } 723 } 724 @* Stock state for Schema.org, stop *@ 725 726 </div> 727 728 @if (showPricesWithVat == "false" && !neverShowVat) 729 { 730 if (isLazyLoadingForProductInfoEnabled && !Pageview.IsVisualEditorMode) 731 { 732 <small class="opacity-85 fst-normal js-text-price-with-vat d-none" data-suffix="@Translate("Incl. VAT")"></small> 733 } 734 else 735 { 736 string price = !string.IsNullOrEmpty(unitId) ? product.GetPrice(unitId).Price.PriceWithVatFormatted : product.Price.PriceWithVatFormatted; 737 738 if (product?.VariantInfo?.VariantInfo != null) 739 { 740 priceMin = product?.VariantInfo?.PriceMin?.PriceWithVatFormatted != null ? product.VariantInfo.PriceMin.PriceWithVatFormatted : ""; 741 priceMax = product?.VariantInfo?.PriceMax?.PriceWithVatFormatted != null ? product.VariantInfo.PriceMax.PriceWithVatFormatted : ""; 742 } 743 if (priceMin != priceMax) 744 { 745 price = priceMin + " - " + priceMax; 746 } 747 <!-- <small class="opacity-85 fst-normal">@price @Translate("Incl. VAT")</small> --> 748 } 749 } 750 </div> 751 } 752 else if (Pageview.IsVisualEditorMode) 753 { 754 <div class="alert alert-dark m-0" role="alert"> 755 <span>@Translate("No products available")</span> 756 </div> 757 } 758 759 </div> 760 } 761 } 762
Tischlampe Ø50 Korb XL
Error executing template "Designs/Swift/Paragraph/CustomProductSlider.cshtml"
System.NullReferenceException: Object reference not set to an instance of an object.
   at CompiledRazorTemplates.Dynamic.RazorEngine_3562354021b44d5c892fe73dc2806e4f.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 Dynamicweb.Ecommerce.ProductCatalog 3 @using Dynamicweb.Ecommerce.CustomerExperienceCenter.Favorites 4 @using Dynamicweb.Files 5 @using System.IO 6 @using System.Net 7 @using Dynamicweb.Security.UserManagement 8 9 10 @{ 11 ProductViewModel product = null; 12 if (Dynamicweb.Context.Current.Items.Contains("ProductDetails")) 13 { 14 product = (ProductViewModel)Dynamicweb.Context.Current.Items["ProductDetails"]; 15 } 16 else if (Pageview.Page.Item["DummyProduct"] != null && Pageview.IsVisualEditorMode) 17 { 18 var pageViewModel = Dynamicweb.Frontend.ContentViewModelFactory.CreatePageInfoViewModel(Pageview.Page); 19 ProductListViewModel productList = pageViewModel.Item.GetValue("DummyProduct") != null ? pageViewModel.Item.GetValue("DummyProduct") as ProductListViewModel : new ProductListViewModel(); 20 21 if (productList?.Products is object) 22 { 23 product = productList.Products[0]; 24 } 25 } 26 } 27 28 @{ 29 var currentUser = Pageview?.User; 30 var customerNumber = !string.IsNullOrEmpty(currentUser?.CustomerNumber) 31 ? currentUser.CustomerNumber 32 : ""; 33 } 34 @if (product is object) 35 { 36 string imagePath = product?.DefaultImage?.Value ?? ""; 37 string imagePathUrlEncoded = Dynamicweb.Context.Current.Server.UrlEncode(imagePath); 38 39 string ratio = Model.Item.GetRawValueString("ImageAspectRatio", ""); 40 ratio = ratio != "0" ? ratio : ""; 41 string ratioCssClass = ratio != "" ? " ratio" : ""; 42 string ratioVariable = ratio != "" ? "--bs-aspect-ratio: " + ratio + ";" : ""; 43 44 string width = Model.Item.GetRawValueString("Width", "auto"); 45 int smallImageSize = 640; 46 int largeImageSize = width == "auto" ? 1280 : Convert.ToInt32(width); 47 48 string ImageObjectFit = Model.Item.GetRawValueString("ImageObjectFit", "contain"); 49 50 string imagePathXs = "/Admin/Public/GetImage.ashx?width=" + smallImageSize + "&image=" + imagePathUrlEncoded + "&format=webp"; 51 string imagePathS = "/Admin/Public/GetImage.ashx?width=" + largeImageSize + "&image=" + imagePathUrlEncoded + "&format=webp"; 52 string imagePathFallBack = "/Admin/Public/GetImage.ashx?width=" + largeImageSize + "&image=" + imagePathUrlEncoded + "&format=webp"; 53 54 var badgeParms = new Dictionary<string, object>(); 55 badgeParms.Add("size", "h7"); 56 badgeParms.Add("saleBadgeType", Model.Item.GetRawValue("SaleBadgeType")); 57 badgeParms.Add("saleBadgeCssClassName", Model.Item.GetRawValue("SaleBadgeDesign")); 58 badgeParms.Add("newBadgeCssClassName", Model.Item.GetRawValue("NewBadgeDesign")); 59 badgeParms.Add("newPublicationDays", Model.Item.GetInt32("NewPublicationDays")); 60 badgeParms.Add("campaignBadgesValues", Model.Item.GetList("CampaignBadges")?.GetRawValue().OfType<string>().ToList()); 61 62 string badgeSize = Model.Item.GetRawValueString("BadgeSize", "fs-2"); 63 bool saleBadgeEnabled = !string.IsNullOrWhiteSpace(Model.Item.GetRawValueString("SaleBadgeDesign")) && Model.Item.GetRawValueString("SaleBadgeDesign") != "none" ? true : false; 64 bool newBadgeEnabled = !string.IsNullOrWhiteSpace(Model.Item.GetRawValueString("NewBadgeDesign")) && Model.Item.GetRawValueString("NewBadgeDesign") != "none" ? true : false; 65 66 /*Custom badge*/ 67 var productService = new Dynamicweb.Ecommerce.Products.ProductService(); 68 var currency = Dynamicweb.Ecommerce.Common.Context.Currency.Code; 69 var formatProvider = new System.Globalization.NumberFormatInfo(); 70 formatProvider.NumberDecimalSeparator = "."; 71 formatProvider.NumberGroupSeparator = ","; 72 var MainVariant = productService.GetProductById(product.Id, product.VariantId, false); 73 var fieldValueBlocked = MainVariant?.ProductFieldValues?.GetProductFieldValue("BlockedCustomerList")?.Value; 74 75 76 string isNewProduct = MainVariant?.ProductFieldValues?.GetProductFieldValue("New")?.Value?.ToString().ToLower() ?? ""; 77 string MainisSale = MainVariant?.ProductFieldValues?.GetProductFieldValue("Sale")?.Value?.ToString().ToLower() ?? ""; 78 bool showNewBadge = isNewProduct == "true" ? true : false; 79 bool showSaleBadge = MainisSale == "true" ? true : false; 80 string showNewSaleBadge = "d-none"; 81 if (showSaleBadge) 82 { 83 badgeParms.Add("isSale", "true"); 84 85 } 86 else 87 { 88 badgeParms.Add("isSale", "false"); 89 } 90 if (showNewBadge) 91 { 92 badgeParms.Add("isNew", "true"); 93 } 94 else 95 { 96 badgeParms.Add("isNew", "false"); 97 } 98 /*End Custom badge*/ 99 if (showSaleBadge || showNewBadge) 100 { 101 showNewSaleBadge = ""; 102 } 103 DateTime createdDate = product.Created.Value; 104 bool showBadges = saleBadgeEnabled && product.Discount.Price != 0 ? true : false; 105 106 bool showFavoritesSelector = !string.IsNullOrEmpty(Model.Item.GetString("ShowAddToFavorites")) ? Model.Item.GetBoolean("ShowAddToFavorites") : false; 107 string anonymousUsersLimitations = Pageview.AreaSettings.GetRawValueString("AnonymousUsers", ""); 108 bool anonymousUser = Pageview.User == null; 109 110 var favoriteParameters = new Dictionary<string, object>(); 111 if (!anonymousUser && showFavoritesSelector) 112 { 113 int defaultFavoriteListId = 0; 114 115 IEnumerable<FavoriteList> favoreiteLists = Pageview.User.GetFavoriteLists(); 116 if (favoreiteLists.Count() == 1) 117 { 118 foreach (FavoriteList list in favoreiteLists) 119 { 120 defaultFavoriteListId = list.ListId; 121 } 122 } 123 124 favoriteParameters.Add("ListId", defaultFavoriteListId); 125 } 126 127 MediaViewModel alternativeImage = new MediaViewModel(); 128 if (Model.Item.GetBoolean("ShowAlternativeImageOnHover")) 129 { 130 var selectedImageCategories = Model.Item.GetList("GetAlternativeImageFrom")?.GetRawValue().OfType<string>().ToList(); 131 List<MediaViewModel> allAssetsImages = product.AssetCategories.Where(x => selectedImageCategories.Contains(x.SystemName)).SelectMany(x => x.Assets).ToList(); 132 allAssetsImages.RemoveAll(x => x.Value == product.DefaultImage.Value); 133 alternativeImage = allAssetsImages.FirstOrDefault(); 134 } 135 136 string altImagePathXs = string.Empty; 137 string altImagePathS = string.Empty; 138 139 if (!string.IsNullOrEmpty(alternativeImage?.Value)) 140 { 141 altImagePathXs = "/Admin/Public/GetImage.ashx?width=" + smallImageSize + "&image=" + Dynamicweb.Context.Current.Server.UrlEncode(alternativeImage.Value) + "&format=webp"; 142 altImagePathS = "/Admin/Public/GetImage.ashx?width=" + largeImageSize + "&image=" + Dynamicweb.Context.Current.Server.UrlEncode(alternativeImage.Value) + "&format=webp"; 143 } 144 145 @* Theme settings *@ 146 string theme = !string.IsNullOrWhiteSpace(Model.Item.GetRawValueString("Theme")) ? " theme " + Model.Item.GetRawValueString("Theme").Replace(" ", "").Trim().ToLower() : ""; 147 string themeBorder = !string.IsNullOrWhiteSpace(theme) ? "border: 1px solid rgba(0,0,0,0)" : ""; 148 string themePadding = !string.IsNullOrWhiteSpace(theme) ? "p-2 p-lg-3" : ""; 149 150 string imageId = "ProductImage_" + product.Id; 151 152 153 154 string fullWidth = width == "auto" ? "w-100" : ""; 155 string customWidth = width != "auto" ? "style=\"width: " + width + "px\"" : "style=\"min-width: 60px\""; 156 157 string altImageZindex = Model.Item.GetBoolean("ShowAlternativeImageOnHover") && !string.IsNullOrEmpty(alternativeImage?.Value) ? " z-index: 1" : string.Empty; 158 string groupid = !string.IsNullOrEmpty(Dynamicweb.Context.Current.Request.QueryString.Get("GroupID")) ? Dynamicweb.Context.Current.Request.QueryString.Get("GroupID"):"" ; 159 string link = product.GetProductLink(GetPageIdByNavigationTag("Shop"), false); 160 var productVariantGroups = product.VariantGroups(); 161 string MainOutStock = "<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"25\" height=\"25\" fill=\"#CA0D0D\" class=\"bi bi-x-lg\" viewBox=\"0 0 16 16\"><path d=\"M4.646 4.646a.5.5 0 0 1 .708 0L8 7.293l2.646-2.647a.5.5 0 0 1 .708.708L8.707 8l2.647 2.646a.5.5 0 0 1-.708.708L8 8.707l-2.646 2.647a.5.5 0 0 1-.708-.708L7.293 8 4.646 5.354a.5.5 0 0 1 0-.708\"/></svg>"; 162 163 @if (!string.IsNullOrEmpty(imagePath)) 164 { 165 <div class="@fullWidth @theme position-relative item_@Model.Item.SystemName.ToLower() main-image-container" @customWidth> 166 <div class="" style="@(ratioVariable)@(altImageZindex)"> 167 <div class="d-flex justify-content-center align-items-center"> 168 <a class="main-link-link" href="@link"> 169 @if (imagePath.StartsWith("/Files/", StringComparison.OrdinalIgnoreCase)) 170 { 171 <img id="@imageId" 172 srcset=" 173 @imagePathXs @(smallImageSize)w, 174 @imagePathS @(largeImageSize)w" 175 sizes="(max-width: 992px) 50vw, 25vw" 176 src="@imagePathFallBack" 177 loading="lazy" 178 decoding="async" 179 class="h-100 w-100 @themePadding main-image" 180 style="object-fit: @ImageObjectFit; @themeBorder " 181 alt="@product.Name" 182 itemprop="image"> 183 } 184 else 185 { 186 <img src="@product.DefaultImage.Value" 187 loading="lazy" 188 class="h-100 w-100 @themePadding main-image" 189 style="object-fit: contain; @themeBorder" 190 alt="@product.Name" 191 itemprop="image"> 192 } 193 </a> 194 </div> 195 </div> 196 197 <div class="position-absolute top-0 left-0 p-2 pb-0 custom-badge-product-list @showNewSaleBadge"> 198 @{ 199 @RenderPartial("Components/Custom_EcommerceBadge.cshtml", product, badgeParms) 200 } 201 </div> 202 203 204 </div> 205 } 206 207 <div class="product-info h-100"> 208 <div class="fs-7 pt-1 opacity-85 start item_@Model.Item.SystemName.ToLower() product-number" itemprop="sku">@product.Id / @product.VariantId - @product.VariantName</div> 209 <div class="py-2" data-col-size="12"> 210 <h2 class="h6 start m-0 item_swift_productheader product-name" itemprop="name"><b>@product.Name</b></h2> 211 </div> 212 </div> 213 var sliderId = $"thumb-scroll-{product.Id}"; 214 if (productVariantGroups.Any() && product?.VariantInfo?.VariantInfo != null) 215 216 { 217 @using Dynamicweb.Ecommerce.Prices 218 @{ 219 string[] variantId = product.VariantId.Split('.'); 220 string showPricesWithVat = Pageview.Area.EcomPricesWithVat.ToLower(); 221 bool neverShowVat = string.IsNullOrEmpty(showPricesWithVat); 222 bool showInformativePrice = Model.Item.GetBoolean("ShowInformativePrice"); 223 string productInfoFeed = ""; 224 bool isLazyLoadingForProductInfoEnabled = Dynamicweb.Core.Converter.ToBoolean(Dynamicweb.Context.Current.Items["IsLazyLoadingForProductInfoEnabled"]); 225 if (isLazyLoadingForProductInfoEnabled) 226 { 227 if (Dynamicweb.Context.Current.Items.Contains("ProductInfoFeed")) 228 { 229 productInfoFeed = Dynamicweb.Context.Current.Items["ProductInfoFeed"]?.ToString(); 230 if (!string.IsNullOrEmpty(productInfoFeed)) 231 { 232 productInfoFeed =productInfoFeed; 233 } 234 } 235 236 } 237 string priceMin = ""; 238 string priceMax = ""; 239 int groupNumber = 1; 240 241 242 243 244 string baseUrl = $"Default.aspx?ID={GetPageIdByNavigationTag("Shop")}&GroupID={product.PrimaryOrDefaultGroup.Id}&ProductID={product.Id}"; 245 if (!string.IsNullOrEmpty(baseUrl)) 246 { 247 baseUrl = $"/{baseUrl.TrimStart('/')}"; 248 } 249 string variantUrl = string.Empty; 250 251 252 Dictionary<string, string> 253 variantImages = new Dictionary<string, string> 254 (); 255 <div class="last-row mt-auto"> 256 257 @foreach (var variantGroup in productVariantGroups) 258 { 259 <div class="thumbnail-wrapper"> 260 <button class="thumb-nav prev" onclick="scrollThumbs('@sliderId', -1)"> 261 <svg width="20px" height="20px" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" fill="#1D98A5"> 262 263 <g stroke="none" stroke-width="1" fill="none" fill-rule="evenodd"> 264 <g transform="translate(-336.000000, 0.000000)"> 265 <g id="left_line" transform="translate(336.000000, 0.000000)"> 266 <path d="M24,0 L24,24 L0,24 L0,0 L24,0 Z M12.5934901,23.257841 L12.5819402,23.2595131 L12.5108777,23.2950439 L12.4918791,23.2987469 L12.4918791,23.2987469 L12.4767152,23.2950439 L12.4056548,23.2595131 C12.3958229,23.2563662 12.3870493,23.2590235 12.3821421,23.2649074 L12.3780323,23.275831 L12.360941,23.7031097 L12.3658947,23.7234994 L12.3769048,23.7357139 L12.4804777,23.8096931 L12.4953491,23.8136134 L12.4953491,23.8136134 L12.5071152,23.8096931 L12.6106902,23.7357139 L12.6232938,23.7196733 L12.6232938,23.7196733 L12.6266527,23.7031097 L12.609561,23.275831 C12.6075724,23.2657013 12.6010112,23.2592993 12.5934901,23.257841 L12.5934901,23.257841 Z M12.8583906,23.1452862 L12.8445485,23.1473072 L12.6598443,23.2396597 L12.6498822,23.2499052 L12.6498822,23.2499052 L12.6471943,23.2611114 L12.6650943,23.6906389 L12.6699349,23.7034178 L12.6699349,23.7034178 L12.678386,23.7104931 L12.8793402,23.8032389 C12.8914285,23.8068999 12.9022333,23.8029875 12.9078286,23.7952264 L12.9118235,23.7811639 L12.8776777,23.1665331 C12.8752882,23.1545897 12.8674102,23.1470016 12.8583906,23.1452862 L12.8583906,23.1452862 Z M12.1430473,23.1473072 C12.1332178,23.1423925 12.1221763,23.1452606 12.1156365,23.1525954 L12.1099173,23.1665331 L12.0757714,23.7811639 C12.0751323,23.7926639 12.0828099,23.8018602 12.0926481,23.8045676 L12.108256,23.8032389 L12.3092106,23.7104931 L12.3186497,23.7024347 L12.3186497,23.7024347 L12.3225043,23.6906389 L12.340401,23.2611114 L12.337245,23.2485176 L12.337245,23.2485176 L12.3277531,23.2396597 L12.1430473,23.1473072 Z" id="MingCute" fill-rule="nonzero"> </path> 267 <path d="M8.29292,12.7071 C7.9024,12.3166 7.9024,11.6834 8.29292,11.2929 L13.9498,5.63604 C14.3403,5.24551 14.9735,5.24551 15.364,5.63604 C15.7545,6.02656 15.7545,6.65973 15.364,7.05025 L10.4142,12 L15.364,16.9497 C15.7545,17.3403 15.7545,17.9734 15.364,18.364 C14.9735,18.7545 14.3403,18.7545 13.9498,18.364 L8.29292,12.7071 Z" id="路径" fill="#1D98A5"> </path> 268 </g> 269 </g> 270 </g> 271 </svg> 272 273 </button> 274 <div class="thumbnail-scroll" id="@sliderId"> 275 @{ 276 VariantGroupViewModel group = variantGroup; 277 foreach (var option in group.Options.OrderBy(o => o.Id)) 278 { 279 var productVariant = productService.GetProductById(product.Id, option.Id, false); 280 281 var productSelection = new PriceProductSelection(productVariant, null, 0); 282 283 var currencyCode = string.IsNullOrWhiteSpace(Pageview.User.Currency) ? Pageview.Area.EcomCurrencyId : Pageview.User.Currency; 284 var countryCode = string.IsNullOrWhiteSpace(Pageview.User.CountryCode) ? Pageview.Area.EcomCountryCode : Pageview.User.CountryCode; 285 286 var userCurrency = Dynamicweb.Ecommerce.Services.Currencies.GetCurrency(currencyCode); 287 var userCountry = Dynamicweb.Ecommerce.Services.Countries.GetCountry(countryCode); 288 289 var priceContext = new PriceContext(userCurrency, userCountry, null, Pageview.User, false, null); 290 var productPrice = Dynamicweb.Ecommerce.Services.Prices.FindPrices(priceContext, productSelection, false); 291 292 //throw new Exception(System.Text.Json.JsonSerializer.Serialize(productPrice)); 293 294 var fieldValue = productVariant?.ProductFieldValues?.GetProductFieldValue("BlockedCustomerList")?.Value; 295 296 if ((fieldValue != null && !fieldValue.ToString().Contains(customerNumber)) || String.IsNullOrWhiteSpace(customerNumber)) 297 { 298 299 300 string active = variantId != null && variantId.Contains(option.Id) ? "active" : string.Empty; 301 string buttonId = $"{product.Id}_{option.Id}_{Pageview.CurrentParagraph.ID}"; 302 string contrastColor = string.Empty; 303 304 string searchKey = $"{product.Id}_{option.Id}_"; 305 /*Images*/ 306 var imagePathVariant = option.Image?.Value ?? ""; 307 308 309 var folderPath = Path.GetDirectoryName(imagePathVariant); 310 311 string physicalFolderPath = Dynamicweb.Context.Current.Server.MapPath(folderPath); 312 313 string lastImage = null; 314 315 if (Directory.Exists(physicalFolderPath)) 316 { 317 318 var fileWith15 = Directory.GetFiles(physicalFolderPath) 319 .FirstOrDefault(f => Path.GetFileName(f).Contains($"{product.Id}_{option.Id}_9")); 320 321 if (fileWith15 != null) 322 { 323 lastImage = fileWith15; 324 } 325 else 326 { 327 var files = Directory.GetFiles(physicalFolderPath) 328 .Where(f => Path.GetFileName(f).StartsWith($"{product.Id}_{option.Id}_")) 329 .OrderByDescending(f => 330 { 331 var filename = Path.GetFileNameWithoutExtension(f); 332 var match = System.Text.RegularExpressions.Regex.Match(filename, @"_(\d+)$"); 333 if (match.Success && int.TryParse(match.Groups[1].Value, out int index)) 334 { 335 return index; 336 } 337 return 0; 338 }) 339 .ToList(); 340 341 if (files.Any()) 342 { 343 lastImage = files.First(); 344 } 345 } 346 } 347 348 var lastImageUrl = lastImage != null ? lastImage : "/Files/Images/zijlstra/Afbeeldingen_overig/Coming_Soon.jpg"; 349 int index = lastImageUrl.IndexOf("Files"); 350 string relativePath = index >= 0 ? lastImageUrl.Substring(index).Replace("\\", "/") : lastImageUrl.Replace("\\", "/"); 351 lastImageUrl = "/" + relativePath; 352 lastImageUrl = Dynamicweb.Context.Current.Server.UrlEncode(lastImageUrl); 353 var variantImg = option.Image is object ? Dynamicweb.Context.Current.Server.UrlEncode(option.Image.Value) : null; 354 var variantLink = "/Default.aspx?ID=" + GetPageIdByNavigationTag("Shop") + "&GroupID=" + product.PrimaryOrDefaultGroup.Id + "&ProductID=" + product.Id + "&VariantID=" + option.Id; 355 356 string variantImage = string.Empty; 357 variantImages.TryGetValue(option.Id, out variantImage); 358 /*End Images*/ 359 360 /*stock state*/ 361 double variantStock = productVariant.Stock; 362 string svgInStock = "<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"16\" height=\"16\" fill=\"#44B11A\" class=\"bi bi-check-lg\" viewBox=\"0 0 16 16\"><path d=\"M12.736 3.97a.733.733 0 0 1 1.047 0c.286.289.29.756.01 1.05L7.88 12.01a.733.733 0 0 1-1.065.02L3.217 8.384a.757.757 0 0 1 0-1.06.733.733 0 0 1 1.047 0l3.052 3.093 5.4-6.425z\"/></svg>"; 363 string svgOutStock = "<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"25\" height=\"25\" fill=\"#CA0D0D\" class=\"bi bi-x-lg\" viewBox=\"0 0 16 16\"><path d=\"M4.646 4.646a.5.5 0 0 1 .708 0L8 7.293l2.646-2.647a.5.5 0 0 1 .708.708L8.707 8l2.647 2.646a.5.5 0 0 1-.708.708L8 8.707l-2.646 2.647a.5.5 0 0 1-.708-.708L7.293 8 4.646 5.354a.5.5 0 0 1 0-.708\"/></svg>"; 364 365 string infoStock = "<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"16\" height=\"16\" fill=\"currentColor\" class=\"bi bi-info-circle-fill\" viewBox=\"0 0 16 16\"><path d=\"M8 16A8 8 0 1 0 8 0a8 8 0 0 0 0 16m.93-9.412-1 4.705c-.07.34.029.533.304.533.194 0 .487-.07.686-.246l-.088.416c-.287.346-.92.598-1.465.598-.703 0-1.002-.422-.808-1.319l.738-3.468c.064-.293.006-.399-.287-.47l-.451-.081.082-.381 2.29-.287zM8 5.5a1 1 0 1 1 0-2 1 1 0 0 1 0 2\" /></svg>"; 366 string isNew = productVariant?.ProductFieldValues?.GetProductFieldValue("New")?.Value?.ToString().ToLower() ?? ""; 367 string isNewSvg = "<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"16\" height=\"16\" fill=\"#F2C400\" class=\"bi bi-star-fill\" viewBox=\"0 0 16 16\"><path d = \"M3.612 15.443c-.386.198-.824-.149-.746-.592l.83-4.73L.173 6.765c-.329-.314-.158-.888.283-.95l4.898-.696L7.538.792c.197-.39.73-.39.927 0l2.184 4.327 4.898.696c.441.062.612.636.282.95l-3.522 3.356.83 4.73c.078.443-.36.79-.746.592L8 13.187l-4.389 2.256z\" /></svg> "; 368 string stockState = ""; 369 370 string isSale = productVariant?.ProductFieldValues?.GetProductFieldValue("Sale")?.Value?.ToString().ToLower() ?? ""; 371 string isSaleSvg = "<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"16\" height=\"16\" fill=\"#F03232\" class=\"bi bi-star-fill\" viewBox=\"0 0 16 16\"><path d = \"M3.612 15.443c-.386.198-.824-.149-.746-.592l.83-4.73L.173 6.765c-.329-.314-.158-.888.283-.95l4.898-.696L7.538.792c.197-.39.73-.39.927 0l2.184 4.327 4.898.696c.441.062.612.636.282.95l-3.522 3.356.83 4.73c.078.443-.36.79-.746.592L8 13.187l-4.389 2.256z\" /></svg> "; 372 373 string expectedDeliveryDate = ""; 374 375 if (DateTime.Compare(productVariant.ExpectedDelivery, new DateTime(1900, 1, 1)) != 0) //In DW, if the Date is not set, it is defaulted 01-01-1900 and not null.. 376 { 377 expectedDeliveryDate = productVariant.ExpectedDelivery.ToShortDateString(); 378 } 379 380 string expectedDeliveryDateText = !String.IsNullOrWhiteSpace(expectedDeliveryDate) ? Translate("Verwacht:") + "&nbsp;" + expectedDeliveryDate : ""; 381 382 @if (!(bool?)productVariant.ProductFieldValues.Where(o => o.ProductField.SystemName == "ProductToBeDiscontinued").SingleOrDefault()?.Value ?? false) 383 { 384 if (variantStock > 0) 385 { 386 if (isNew == "true" || isSale == "true") 387 { 388 if (isSale == "true") 389 { 390 stockState += isSaleSvg + "&nbsp; &nbsp;" + Translate("Sale!") + "<br/>"; 391 } 392 393 if (isNew == "true") 394 { 395 stockState += isNewSvg + "&nbsp; &nbsp;" + Translate("New!") + "<br/>"; 396 } 397 398 stockState += "&nbsp;" + Translate("Nu leverbaar"); 399 } 400 else 401 { 402 stockState = svgInStock + "&nbsp; " + Translate("Op voorraad"); 403 404 } 405 } 406 else 407 { 408 stockState = svgOutStock + "&nbsp;" + Translate("Geen voorraad") + "<br/>" + expectedDeliveryDateText; 409 410 } 411 } 412 else 413 { 414 415 stockState = svgOutStock + "&nbsp;" + Translate("Discontinued:") + "<br/>" + variantStock + "&nbsp;" + @Translate("left in stock"); 416 417 } 418 /*End stock state*/ 419 /*Price variants*/ 420 double price = productVariant.DefaultPrice; 421 double cost = productVariant.Cost; 422 423 string priceFormated = Dynamicweb.Ecommerce.Services.Currencies.Format(Dynamicweb.Ecommerce.Services.Currencies.GetCurrency(currency), Convert.ToDouble(productPrice.ToList()[0].Amount, formatProvider)); 424 //string priceFormated = Dynamicweb.Ecommerce.Services.Currencies.Format(Dynamicweb.Ecommerce.Services.Currencies.GetCurrency(currency), Convert.ToDouble(price, formatProvider)); 425 426 427 428 /*End Price variants*/ 429 430 <img class="theme thumbnail" data-stockstate="@WebUtility.HtmlEncode(stockState)" src="/Admin/Public/GetImage.ashx?image=@(lastImageUrl)&width=64&format=webp" onclick="selectVariant('@(product.Id)','/Admin/Public/GetImage.ashx?image=@(variantImg)&format=webp','@variantLink','@product.Id','@option.Id','@option.Name',this.dataset.stockstate,'@isNew','@isSale','@priceFormated','@cost')" /> 431 432 433 } 434 } 435 436 } 437 </div> 438 <button class="thumb-nav next" onclick="scrollThumbs('@sliderId', 1)"> 439 <svg width="20px" height="20px" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" fill="#1D98A5"> 440 441 <g stroke="none" stroke-width="1" fill="none" fill-rule="evenodd"> 442 <g transform="translate(-384.000000, 0.000000)"> 443 <g id="right_line" transform="translate(384.000000, 0.000000)"> 444 <path d="M24,0 L24,24 L0,24 L0,0 L24,0 Z M12.5934901,23.257841 L12.5819402,23.2595131 L12.5108777,23.2950439 L12.4918791,23.2987469 L12.4918791,23.2987469 L12.4767152,23.2950439 L12.4056548,23.2595131 C12.3958229,23.2563662 12.3870493,23.2590235 12.3821421,23.2649074 L12.3780323,23.275831 L12.360941,23.7031097 L12.3658947,23.7234994 L12.3769048,23.7357139 L12.4804777,23.8096931 L12.4953491,23.8136134 L12.4953491,23.8136134 L12.5071152,23.8096931 L12.6106902,23.7357139 L12.6232938,23.7196733 L12.6232938,23.7196733 L12.6266527,23.7031097 L12.609561,23.275831 C12.6075724,23.2657013 12.6010112,23.2592993 12.5934901,23.257841 L12.5934901,23.257841 Z M12.8583906,23.1452862 L12.8445485,23.1473072 L12.6598443,23.2396597 L12.6498822,23.2499052 L12.6498822,23.2499052 L12.6471943,23.2611114 L12.6650943,23.6906389 L12.6699349,23.7034178 L12.6699349,23.7034178 L12.678386,23.7104931 L12.8793402,23.8032389 C12.8914285,23.8068999 12.9022333,23.8029875 12.9078286,23.7952264 L12.9118235,23.7811639 L12.8776777,23.1665331 C12.8752882,23.1545897 12.8674102,23.1470016 12.8583906,23.1452862 L12.8583906,23.1452862 Z M12.1430473,23.1473072 C12.1332178,23.1423925 12.1221763,23.1452606 12.1156365,23.1525954 L12.1099173,23.1665331 L12.0757714,23.7811639 C12.0751323,23.7926639 12.0828099,23.8018602 12.0926481,23.8045676 L12.108256,23.8032389 L12.3092106,23.7104931 L12.3186497,23.7024347 L12.3186497,23.7024347 L12.3225043,23.6906389 L12.340401,23.2611114 L12.337245,23.2485176 L12.337245,23.2485176 L12.3277531,23.2396597 L12.1430473,23.1473072 Z" id="MingCute" fill-rule="nonzero"> </path> 445 <path d="M15.7072,11.2929 C16.0977,11.6834 16.0977,12.3166 15.7072,12.7071 L10.0503,18.364 C9.65982,18.7545 9.02666,18.7545 8.63613,18.364 C8.24561,17.9734 8.24561,17.3403 8.63613,16.9497 L13.5859,12 L8.63613,7.05025 C8.24561,6.65973 8.24561,6.02656 8.63613,5.63604 C9.02666,5.24551 9.65982,5.24551 10.0503,5.63604 L15.7072,11.2929 Z" id="路径" fill="#1D98A5"> </path> 446 </g> 447 </g> 448 449 </svg> 450 451 </button> 452 </div> 453 } 454 455 456 </div> 457 458 } 459 if ((fieldValueBlocked != null && !fieldValueBlocked.ToString().Contains(customerNumber)) || String.IsNullOrWhiteSpace(customerNumber)) 460 { 461 <div class="stock-state pt-2 mt-auto"> 462 @{ 463 464 /*stock state*/ 465 double MainvariantStock = MainVariant.Stock; 466 string MainsvgInStock = "<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"16\" height=\"16\" fill=\"#44B11A\" class=\"bi bi-check-lg\" viewBox=\"0 0 16 16\"><path d=\"M12.736 3.97a.733.733 0 0 1 1.047 0c.286.289.29.756.01 1.05L7.88 12.01a.733.733 0 0 1-1.065.02L3.217 8.384a.757.757 0 0 1 0-1.06.733.733 0 0 1 1.047 0l3.052 3.093 5.4-6.425z\"/></svg>"; 467 string MainsvgOutStock = "<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"25\" height=\"25\" fill=\"#CA0D0D\" class=\"bi bi-x-lg\" viewBox=\"0 0 16 16\"><path d=\"M4.646 4.646a.5.5 0 0 1 .708 0L8 7.293l2.646-2.647a.5.5 0 0 1 .708.708L8.707 8l2.647 2.646a.5.5 0 0 1-.708.708L8 8.707l-2.646 2.647a.5.5 0 0 1-.708-.708L7.293 8 4.646 5.354a.5.5 0 0 1 0-.708\"/></svg>"; 468 469 string MaininfoStock = "<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"16\" height=\"16\" fill=\"currentColor\" class=\"bi bi-info-circle-fill\" viewBox=\"0 0 16 16\"><path d=\"M8 16A8 8 0 1 0 8 0a8 8 0 0 0 0 16m.93-9.412-1 4.705c-.07.34.029.533.304.533.194 0 .487-.07.686-.246l-.088.416c-.287.346-.92.598-1.465.598-.703 0-1.002-.422-.808-1.319l.738-3.468c.064-.293.006-.399-.287-.47l-.451-.081.082-.381 2.29-.287zM8 5.5a1 1 0 1 1 0-2 1 1 0 0 1 0 2\" /></svg>"; 470 string MainisNew = MainVariant?.ProductFieldValues?.GetProductFieldValue("New")?.Value?.ToString().ToLower() ?? ""; 471 string MainisNewSvg = "<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"16\" height=\"16\" fill=\"#F2C400\" class=\"bi bi-star-fill\" viewBox=\"0 0 16 16\"><path d = \"M3.612 15.443c-.386.198-.824-.149-.746-.592l.83-4.73L.173 6.765c-.329-.314-.158-.888.283-.95l4.898-.696L7.538.792c.197-.39.73-.39.927 0l2.184 4.327 4.898.696c.441.062.612.636.282.95l-3.522 3.356.83 4.73c.078.443-.36.79-.746.592L8 13.187l-4.389 2.256z\" /></svg> "; 472 string MainstockState = ""; 473 string MainIsSale = MainVariant?.ProductFieldValues?.GetProductFieldValue("Sale")?.Value?.ToString().ToLower() ?? ""; 474 string MainIsSaleSvg = "<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"16\" height=\"16\" fill=\"#F03232\" class=\"bi bi-star-fill\" viewBox=\"0 0 16 16\"><path d = \"M3.612 15.443c-.386.198-.824-.149-.746-.592l.83-4.73L.173 6.765c-.329-.314-.158-.888.283-.95l4.898-.696L7.538.792c.197-.39.73-.39.927 0l2.184 4.327 4.898.696c.441.062.612.636.282.95l-3.522 3.356.83 4.73c.078.443-.36.79-.746.592L8 13.187l-4.389 2.256z\" /></svg> "; 475 string MainexpectedDeliveryDate = ""; 476 477 if (DateTime.Compare(MainVariant.ExpectedDelivery, new DateTime(1900, 1, 1)) != 0) //In DW, if the Date is not set, it is defaulted 01-01-1900 and not null.. 478 { 479 MainexpectedDeliveryDate = MainVariant.ExpectedDelivery.ToShortDateString(); 480 } 481 482 string MainexpectedDeliveryDateText = !String.IsNullOrWhiteSpace(MainexpectedDeliveryDate) ? Translate("Verwacht:") + "&nbsp;" + MainexpectedDeliveryDate : ""; 483 484 @if (!(bool?)MainVariant.ProductFieldValues.Where(o => o.ProductField.SystemName == "ProductToBeDiscontinued").SingleOrDefault()?.Value ?? false) 485 { 486 if (MainvariantStock > 0) 487 { 488 if (MainisNew == "true" || MainIsSale == "true") 489 { 490 if (MainIsSale == "true") 491 { 492 MainstockState += MainIsSaleSvg + "&nbsp; &nbsp;" + Translate("Sale!") + "<br/>"; 493 } 494 495 if (MainisNew == "true") 496 { 497 MainstockState += MainisNewSvg + "&nbsp; &nbsp;" + Translate("New!") + "<br/>"; 498 } 499 500 MainstockState += "&nbsp;" + Translate("Nu leverbaar"); 501 } 502 else 503 { 504 MainstockState = MainsvgInStock + "&nbsp; " + Translate("Op voorraad"); 505 506 } 507 } 508 else 509 { 510 MainstockState = MainsvgOutStock + "&nbsp;" + Translate("Geen voorraad") + "<br/>" + MainexpectedDeliveryDateText; 511 512 } 513 } 514 else 515 { 516 517 MainstockState = MainsvgOutStock + "&nbsp;" + Translate("Discontinued:") + "<br/>" + MainvariantStock + "&nbsp;" + @Translate("left in stock"); 518 519 } 520 /*End stock state*/ 521 522 523 @MainstockState 524 525 526 } 527 </div> 528 } 529 else 530 { 531 <div class="stock-state pt-2 mt-auto"> 532 @MainOutStock @Translate("Discontinued") 533 </div> 534 } 535 <div class="custom-price mt-auto"> 536 @{ 537 538 539 540 541 bool isErpConnectionDown = !Dynamicweb.Core.Converter.ToBoolean(Dynamicweb.Context.Current.Items["IsWebServiceConnectionAvailable"]); 542 bool hidePrice = anonymousUsersLimitations.Contains("price") && anonymousUser || Pageview.AreaSettings.GetBoolean("ErpDownHidePrices") && isErpConnectionDown; 543 544 bool productIsDiscontinued = product is object && product.Discontinued; 545 bool doNotShowPriceIfProductIsDiscontinued = Model.Item.GetBoolean("DoNotShowPriceIfProductIsDiscontinued"); 546 var isDiscontinued = productIsDiscontinued && doNotShowPriceIfProductIsDiscontinued; 547 } 548 549 @if (product is object && !hidePrice && !isDiscontinued) 550 { 551 string unitId = !string.IsNullOrEmpty(Dynamicweb.Context.Current.Request.Form.Get("UnitId")) ? Dynamicweb.Context.Current.Request.Form.Get("UnitId") : string.Empty; 552 553 string priceFontSize = Model.Item.GetRawValueString("PriceSize", "fs-4"); 554 string horizontalAlign = Model.Item.GetRawValueString("HorizontalAlignment", ""); 555 string layout = Model.Item.GetRawValueString("Layout", "horizontal"); 556 string textAlign = horizontalAlign == "center" ? "text-center" : string.Empty; 557 textAlign = horizontalAlign == "end" ? "text-end" : textAlign; 558 559 horizontalAlign = horizontalAlign == "center" && layout == "horizontal" ? "justify-content-center" : horizontalAlign; 560 horizontalAlign = horizontalAlign == "end" && layout == "horizontal" ? "justify-content-end" : horizontalAlign; 561 horizontalAlign = horizontalAlign == "center" && layout == "vertical" ? "align-items-center" : horizontalAlign; 562 horizontalAlign = horizontalAlign == "end" && layout == "vertical" ? "align-items-end" : horizontalAlign; 563 564 string flexDirection = layout == "horizontal" ? string.Empty : "flex-column"; 565 string flexGap = layout == "horizontal" ? "gap-3" : string.Empty; 566 string order = layout == "horizontal" ? string.Empty : "order-2"; 567 568 569 string contentPadding = Model.Item.GetRawValueString("ContentPadding", ""); 570 contentPadding = contentPadding == "none" ? "p-0" : contentPadding; 571 contentPadding = contentPadding == "small" ? "p-1 px-md-2 py-md-1" : contentPadding; 572 contentPadding = contentPadding == "large" ? "p-2 px-md-3 py-md-2" : contentPadding; 573 string liveInfoClass = ""; 574 575 576 577 578 579 580 if (isLazyLoadingForProductInfoEnabled) 581 { 582 if (Dynamicweb.Context.Current.Items.Contains("ProductInfoFeed")) 583 { 584 productInfoFeed = Dynamicweb.Context.Current.Items["ProductInfoFeed"]?.ToString(); 585 if (!string.IsNullOrEmpty(productInfoFeed)) 586 { 587 productInfoFeed = $"data-product-info-feed=\"{productInfoFeed}\""; 588 } 589 } 590 liveInfoClass = "js-live-info"; 591 } 592 593 <div class="@textAlign @liveInfoClass item_@Model.Item.SystemName.ToLower()" data-product-id="@product.Id" data-variant-id="@product.VariantId" @productInfoFeed> 594 @if (showInformativePrice && product.PriceInformative.Price != 0) 595 { 596 <div class="opacity-50"> 597 <span>@Translate("RRP") </span> 598 <span class="text-decoration-line-through text-price">@product.PriceInformative.PriceFormatted</span> 599 </div> 600 } 601 <div class="@priceFontSize m-0 d-flex flex-wrap @flexDirection @flexGap @horizontalAlign" style="row-gap: 0 !important" itemprop="offers" itemscope itemtype="https://schema.org/Offer"> 602 <span itemprop="priceCurrency" content="@product.Price.CurrencyCode" class="d-none"></span> 603 604 605 @if (showPricesWithVat == "false" && !neverShowVat) 606 { 607 if (isLazyLoadingForProductInfoEnabled && !Pageview.IsVisualEditorMode) 608 { 609 <span itemprop="price" content="" class="d-none"></span> 610 <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> 611 } 612 else 613 { 614 string beforePrice = !string.IsNullOrEmpty(unitId) ? product.GetPrice(unitId).PriceBeforeDiscount.PriceWithoutVatFormatted : product.PriceBeforeDiscount.PriceWithoutVatFormatted; 615 616 <span itemprop="price" content="@product.Price.PriceWithoutVat.ToString("0.00", System.Globalization.CultureInfo.InvariantCulture)" class="d-none"></span> 617 if (product.Price.Price != product.PriceBeforeDiscount.Price) 618 { 619 <span class="text-decoration-line-through opacity-75 @order">@beforePrice</span> 620 } 621 } 622 } 623 else 624 { 625 if (isLazyLoadingForProductInfoEnabled && !Pageview.IsVisualEditorMode) 626 { 627 <span itemprop="price" content="" class="d-none"></span> 628 <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> 629 } 630 else 631 { 632 string beforePrice = !string.IsNullOrEmpty(unitId) ? product.GetPrice(unitId).PriceBeforeDiscount.PriceFormatted : product.PriceBeforeDiscount.PriceFormatted; 633 634 <span itemprop="price" content="@product.Price.Price.ToString("0.00", System.Globalization.CultureInfo.InvariantCulture)" class="d-none"></span> 635 636 if (product.Price.Price != product.PriceBeforeDiscount.Price) 637 { 638 <span class="text-decoration-line-through opacity-75 @order"> 639 <span class="text-price">@beforePrice</span> 640 </span> 641 } 642 } 643 } 644 645 @if (showPricesWithVat == "false" && !neverShowVat) 646 { 647 if (isLazyLoadingForProductInfoEnabled && !Pageview.IsVisualEditorMode) 648 { 649 <span class="text-price js-text-price"> 650 <span class="spinner-border" role="status"></span> 651 </span> 652 } 653 else 654 { 655 string price = !string.IsNullOrEmpty(unitId) ? product.GetPrice(unitId).Price.PriceWithoutVatFormatted : product.Price.PriceWithoutVatFormatted; 656 657 if (product?.VariantInfo?.VariantInfo != null) 658 { 659 priceMin = product?.VariantInfo?.PriceMin?.PriceWithoutVatFormatted != null ? product.VariantInfo.PriceMin.PriceWithoutVatFormatted : ""; 660 priceMax = product?.VariantInfo?.PriceMax?.PriceWithoutVatFormatted != null ? product.VariantInfo.PriceMax.PriceWithoutVatFormatted : ""; 661 } 662 if (priceMin != priceMax) 663 { 664 price = priceMin + " - " + priceMax; 665 } 666 <span class="@theme @contentPadding"> 667 <span class="text-price">@price</span> 668 </span> 669 } 670 } 671 else 672 { 673 if (isLazyLoadingForProductInfoEnabled && !Pageview.IsVisualEditorMode) 674 { 675 <span class="text-price js-text-price"> 676 <span class="spinner-border" role="status"></span> 677 </span> 678 } 679 else 680 { 681 string price = !string.IsNullOrEmpty(unitId) ? product.GetPrice(unitId).Price.PriceFormatted : product.Price.PriceFormatted; 682 683 if (product?.VariantInfo?.VariantInfo != null) 684 { 685 priceMin = product?.VariantInfo?.PriceMin?.PriceFormatted != null ? product.VariantInfo.PriceMin.PriceFormatted : ""; 686 priceMax = product?.VariantInfo?.PriceMax?.PriceFormatted != null ? product.VariantInfo.PriceMax.PriceFormatted : ""; 687 } 688 if (priceMin != priceMax) 689 { 690 price = priceMin + " - " + priceMax; 691 } 692 <span class="@theme @contentPadding"> 693 <span class="text-price">@price</span> 694 </span> 695 } 696 } 697 698 @* Stock state for Schema.org, start *@ 699 @{ 700 Uri url = Dynamicweb.Context.Current.Request.Url; 701 } 702 703 <link itemprop="url" href="@url"> 704 705 @{ 706 bool IsNeverOutOfStock = product.NeverOutOfstock; 707 } 708 709 @if (IsNeverOutOfStock) 710 { 711 <span itemprop="availability" class="d-none">@Translate("Available in stock")</span> 712 } 713 else 714 { 715 if (product.StockLevel > 0) 716 { 717 <span itemprop="availability" class="d-none">InStock</span> 718 } 719 else 720 { 721 <span itemprop="availability" class="d-none">OutOfStock</span> 722 } 723 } 724 @* Stock state for Schema.org, stop *@ 725 726 </div> 727 728 @if (showPricesWithVat == "false" && !neverShowVat) 729 { 730 if (isLazyLoadingForProductInfoEnabled && !Pageview.IsVisualEditorMode) 731 { 732 <small class="opacity-85 fst-normal js-text-price-with-vat d-none" data-suffix="@Translate("Incl. VAT")"></small> 733 } 734 else 735 { 736 string price = !string.IsNullOrEmpty(unitId) ? product.GetPrice(unitId).Price.PriceWithVatFormatted : product.Price.PriceWithVatFormatted; 737 738 if (product?.VariantInfo?.VariantInfo != null) 739 { 740 priceMin = product?.VariantInfo?.PriceMin?.PriceWithVatFormatted != null ? product.VariantInfo.PriceMin.PriceWithVatFormatted : ""; 741 priceMax = product?.VariantInfo?.PriceMax?.PriceWithVatFormatted != null ? product.VariantInfo.PriceMax.PriceWithVatFormatted : ""; 742 } 743 if (priceMin != priceMax) 744 { 745 price = priceMin + " - " + priceMax; 746 } 747 <!-- <small class="opacity-85 fst-normal">@price @Translate("Incl. VAT")</small> --> 748 } 749 } 750 </div> 751 } 752 else if (Pageview.IsVisualEditorMode) 753 { 754 <div class="alert alert-dark m-0" role="alert"> 755 <span>@Translate("No products available")</span> 756 </div> 757 } 758 759 </div> 760 } 761 } 762
Tischlampe 1L stellar
Error executing template "Designs/Swift/Paragraph/CustomProductSlider.cshtml"
System.NullReferenceException: Object reference not set to an instance of an object.
   at CompiledRazorTemplates.Dynamic.RazorEngine_3562354021b44d5c892fe73dc2806e4f.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 Dynamicweb.Ecommerce.ProductCatalog 3 @using Dynamicweb.Ecommerce.CustomerExperienceCenter.Favorites 4 @using Dynamicweb.Files 5 @using System.IO 6 @using System.Net 7 @using Dynamicweb.Security.UserManagement 8 9 10 @{ 11 ProductViewModel product = null; 12 if (Dynamicweb.Context.Current.Items.Contains("ProductDetails")) 13 { 14 product = (ProductViewModel)Dynamicweb.Context.Current.Items["ProductDetails"]; 15 } 16 else if (Pageview.Page.Item["DummyProduct"] != null && Pageview.IsVisualEditorMode) 17 { 18 var pageViewModel = Dynamicweb.Frontend.ContentViewModelFactory.CreatePageInfoViewModel(Pageview.Page); 19 ProductListViewModel productList = pageViewModel.Item.GetValue("DummyProduct") != null ? pageViewModel.Item.GetValue("DummyProduct") as ProductListViewModel : new ProductListViewModel(); 20 21 if (productList?.Products is object) 22 { 23 product = productList.Products[0]; 24 } 25 } 26 } 27 28 @{ 29 var currentUser = Pageview?.User; 30 var customerNumber = !string.IsNullOrEmpty(currentUser?.CustomerNumber) 31 ? currentUser.CustomerNumber 32 : ""; 33 } 34 @if (product is object) 35 { 36 string imagePath = product?.DefaultImage?.Value ?? ""; 37 string imagePathUrlEncoded = Dynamicweb.Context.Current.Server.UrlEncode(imagePath); 38 39 string ratio = Model.Item.GetRawValueString("ImageAspectRatio", ""); 40 ratio = ratio != "0" ? ratio : ""; 41 string ratioCssClass = ratio != "" ? " ratio" : ""; 42 string ratioVariable = ratio != "" ? "--bs-aspect-ratio: " + ratio + ";" : ""; 43 44 string width = Model.Item.GetRawValueString("Width", "auto"); 45 int smallImageSize = 640; 46 int largeImageSize = width == "auto" ? 1280 : Convert.ToInt32(width); 47 48 string ImageObjectFit = Model.Item.GetRawValueString("ImageObjectFit", "contain"); 49 50 string imagePathXs = "/Admin/Public/GetImage.ashx?width=" + smallImageSize + "&image=" + imagePathUrlEncoded + "&format=webp"; 51 string imagePathS = "/Admin/Public/GetImage.ashx?width=" + largeImageSize + "&image=" + imagePathUrlEncoded + "&format=webp"; 52 string imagePathFallBack = "/Admin/Public/GetImage.ashx?width=" + largeImageSize + "&image=" + imagePathUrlEncoded + "&format=webp"; 53 54 var badgeParms = new Dictionary<string, object>(); 55 badgeParms.Add("size", "h7"); 56 badgeParms.Add("saleBadgeType", Model.Item.GetRawValue("SaleBadgeType")); 57 badgeParms.Add("saleBadgeCssClassName", Model.Item.GetRawValue("SaleBadgeDesign")); 58 badgeParms.Add("newBadgeCssClassName", Model.Item.GetRawValue("NewBadgeDesign")); 59 badgeParms.Add("newPublicationDays", Model.Item.GetInt32("NewPublicationDays")); 60 badgeParms.Add("campaignBadgesValues", Model.Item.GetList("CampaignBadges")?.GetRawValue().OfType<string>().ToList()); 61 62 string badgeSize = Model.Item.GetRawValueString("BadgeSize", "fs-2"); 63 bool saleBadgeEnabled = !string.IsNullOrWhiteSpace(Model.Item.GetRawValueString("SaleBadgeDesign")) && Model.Item.GetRawValueString("SaleBadgeDesign") != "none" ? true : false; 64 bool newBadgeEnabled = !string.IsNullOrWhiteSpace(Model.Item.GetRawValueString("NewBadgeDesign")) && Model.Item.GetRawValueString("NewBadgeDesign") != "none" ? true : false; 65 66 /*Custom badge*/ 67 var productService = new Dynamicweb.Ecommerce.Products.ProductService(); 68 var currency = Dynamicweb.Ecommerce.Common.Context.Currency.Code; 69 var formatProvider = new System.Globalization.NumberFormatInfo(); 70 formatProvider.NumberDecimalSeparator = "."; 71 formatProvider.NumberGroupSeparator = ","; 72 var MainVariant = productService.GetProductById(product.Id, product.VariantId, false); 73 var fieldValueBlocked = MainVariant?.ProductFieldValues?.GetProductFieldValue("BlockedCustomerList")?.Value; 74 75 76 string isNewProduct = MainVariant?.ProductFieldValues?.GetProductFieldValue("New")?.Value?.ToString().ToLower() ?? ""; 77 string MainisSale = MainVariant?.ProductFieldValues?.GetProductFieldValue("Sale")?.Value?.ToString().ToLower() ?? ""; 78 bool showNewBadge = isNewProduct == "true" ? true : false; 79 bool showSaleBadge = MainisSale == "true" ? true : false; 80 string showNewSaleBadge = "d-none"; 81 if (showSaleBadge) 82 { 83 badgeParms.Add("isSale", "true"); 84 85 } 86 else 87 { 88 badgeParms.Add("isSale", "false"); 89 } 90 if (showNewBadge) 91 { 92 badgeParms.Add("isNew", "true"); 93 } 94 else 95 { 96 badgeParms.Add("isNew", "false"); 97 } 98 /*End Custom badge*/ 99 if (showSaleBadge || showNewBadge) 100 { 101 showNewSaleBadge = ""; 102 } 103 DateTime createdDate = product.Created.Value; 104 bool showBadges = saleBadgeEnabled && product.Discount.Price != 0 ? true : false; 105 106 bool showFavoritesSelector = !string.IsNullOrEmpty(Model.Item.GetString("ShowAddToFavorites")) ? Model.Item.GetBoolean("ShowAddToFavorites") : false; 107 string anonymousUsersLimitations = Pageview.AreaSettings.GetRawValueString("AnonymousUsers", ""); 108 bool anonymousUser = Pageview.User == null; 109 110 var favoriteParameters = new Dictionary<string, object>(); 111 if (!anonymousUser && showFavoritesSelector) 112 { 113 int defaultFavoriteListId = 0; 114 115 IEnumerable<FavoriteList> favoreiteLists = Pageview.User.GetFavoriteLists(); 116 if (favoreiteLists.Count() == 1) 117 { 118 foreach (FavoriteList list in favoreiteLists) 119 { 120 defaultFavoriteListId = list.ListId; 121 } 122 } 123 124 favoriteParameters.Add("ListId", defaultFavoriteListId); 125 } 126 127 MediaViewModel alternativeImage = new MediaViewModel(); 128 if (Model.Item.GetBoolean("ShowAlternativeImageOnHover")) 129 { 130 var selectedImageCategories = Model.Item.GetList("GetAlternativeImageFrom")?.GetRawValue().OfType<string>().ToList(); 131 List<MediaViewModel> allAssetsImages = product.AssetCategories.Where(x => selectedImageCategories.Contains(x.SystemName)).SelectMany(x => x.Assets).ToList(); 132 allAssetsImages.RemoveAll(x => x.Value == product.DefaultImage.Value); 133 alternativeImage = allAssetsImages.FirstOrDefault(); 134 } 135 136 string altImagePathXs = string.Empty; 137 string altImagePathS = string.Empty; 138 139 if (!string.IsNullOrEmpty(alternativeImage?.Value)) 140 { 141 altImagePathXs = "/Admin/Public/GetImage.ashx?width=" + smallImageSize + "&image=" + Dynamicweb.Context.Current.Server.UrlEncode(alternativeImage.Value) + "&format=webp"; 142 altImagePathS = "/Admin/Public/GetImage.ashx?width=" + largeImageSize + "&image=" + Dynamicweb.Context.Current.Server.UrlEncode(alternativeImage.Value) + "&format=webp"; 143 } 144 145 @* Theme settings *@ 146 string theme = !string.IsNullOrWhiteSpace(Model.Item.GetRawValueString("Theme")) ? " theme " + Model.Item.GetRawValueString("Theme").Replace(" ", "").Trim().ToLower() : ""; 147 string themeBorder = !string.IsNullOrWhiteSpace(theme) ? "border: 1px solid rgba(0,0,0,0)" : ""; 148 string themePadding = !string.IsNullOrWhiteSpace(theme) ? "p-2 p-lg-3" : ""; 149 150 string imageId = "ProductImage_" + product.Id; 151 152 153 154 string fullWidth = width == "auto" ? "w-100" : ""; 155 string customWidth = width != "auto" ? "style=\"width: " + width + "px\"" : "style=\"min-width: 60px\""; 156 157 string altImageZindex = Model.Item.GetBoolean("ShowAlternativeImageOnHover") && !string.IsNullOrEmpty(alternativeImage?.Value) ? " z-index: 1" : string.Empty; 158 string groupid = !string.IsNullOrEmpty(Dynamicweb.Context.Current.Request.QueryString.Get("GroupID")) ? Dynamicweb.Context.Current.Request.QueryString.Get("GroupID"):"" ; 159 string link = product.GetProductLink(GetPageIdByNavigationTag("Shop"), false); 160 var productVariantGroups = product.VariantGroups(); 161 string MainOutStock = "<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"25\" height=\"25\" fill=\"#CA0D0D\" class=\"bi bi-x-lg\" viewBox=\"0 0 16 16\"><path d=\"M4.646 4.646a.5.5 0 0 1 .708 0L8 7.293l2.646-2.647a.5.5 0 0 1 .708.708L8.707 8l2.647 2.646a.5.5 0 0 1-.708.708L8 8.707l-2.646 2.647a.5.5 0 0 1-.708-.708L7.293 8 4.646 5.354a.5.5 0 0 1 0-.708\"/></svg>"; 162 163 @if (!string.IsNullOrEmpty(imagePath)) 164 { 165 <div class="@fullWidth @theme position-relative item_@Model.Item.SystemName.ToLower() main-image-container" @customWidth> 166 <div class="" style="@(ratioVariable)@(altImageZindex)"> 167 <div class="d-flex justify-content-center align-items-center"> 168 <a class="main-link-link" href="@link"> 169 @if (imagePath.StartsWith("/Files/", StringComparison.OrdinalIgnoreCase)) 170 { 171 <img id="@imageId" 172 srcset=" 173 @imagePathXs @(smallImageSize)w, 174 @imagePathS @(largeImageSize)w" 175 sizes="(max-width: 992px) 50vw, 25vw" 176 src="@imagePathFallBack" 177 loading="lazy" 178 decoding="async" 179 class="h-100 w-100 @themePadding main-image" 180 style="object-fit: @ImageObjectFit; @themeBorder " 181 alt="@product.Name" 182 itemprop="image"> 183 } 184 else 185 { 186 <img src="@product.DefaultImage.Value" 187 loading="lazy" 188 class="h-100 w-100 @themePadding main-image" 189 style="object-fit: contain; @themeBorder" 190 alt="@product.Name" 191 itemprop="image"> 192 } 193 </a> 194 </div> 195 </div> 196 197 <div class="position-absolute top-0 left-0 p-2 pb-0 custom-badge-product-list @showNewSaleBadge"> 198 @{ 199 @RenderPartial("Components/Custom_EcommerceBadge.cshtml", product, badgeParms) 200 } 201 </div> 202 203 204 </div> 205 } 206 207 <div class="product-info h-100"> 208 <div class="fs-7 pt-1 opacity-85 start item_@Model.Item.SystemName.ToLower() product-number" itemprop="sku">@product.Id / @product.VariantId - @product.VariantName</div> 209 <div class="py-2" data-col-size="12"> 210 <h2 class="h6 start m-0 item_swift_productheader product-name" itemprop="name"><b>@product.Name</b></h2> 211 </div> 212 </div> 213 var sliderId = $"thumb-scroll-{product.Id}"; 214 if (productVariantGroups.Any() && product?.VariantInfo?.VariantInfo != null) 215 216 { 217 @using Dynamicweb.Ecommerce.Prices 218 @{ 219 string[] variantId = product.VariantId.Split('.'); 220 string showPricesWithVat = Pageview.Area.EcomPricesWithVat.ToLower(); 221 bool neverShowVat = string.IsNullOrEmpty(showPricesWithVat); 222 bool showInformativePrice = Model.Item.GetBoolean("ShowInformativePrice"); 223 string productInfoFeed = ""; 224 bool isLazyLoadingForProductInfoEnabled = Dynamicweb.Core.Converter.ToBoolean(Dynamicweb.Context.Current.Items["IsLazyLoadingForProductInfoEnabled"]); 225 if (isLazyLoadingForProductInfoEnabled) 226 { 227 if (Dynamicweb.Context.Current.Items.Contains("ProductInfoFeed")) 228 { 229 productInfoFeed = Dynamicweb.Context.Current.Items["ProductInfoFeed"]?.ToString(); 230 if (!string.IsNullOrEmpty(productInfoFeed)) 231 { 232 productInfoFeed =productInfoFeed; 233 } 234 } 235 236 } 237 string priceMin = ""; 238 string priceMax = ""; 239 int groupNumber = 1; 240 241 242 243 244 string baseUrl = $"Default.aspx?ID={GetPageIdByNavigationTag("Shop")}&GroupID={product.PrimaryOrDefaultGroup.Id}&ProductID={product.Id}"; 245 if (!string.IsNullOrEmpty(baseUrl)) 246 { 247 baseUrl = $"/{baseUrl.TrimStart('/')}"; 248 } 249 string variantUrl = string.Empty; 250 251 252 Dictionary<string, string> 253 variantImages = new Dictionary<string, string> 254 (); 255 <div class="last-row mt-auto"> 256 257 @foreach (var variantGroup in productVariantGroups) 258 { 259 <div class="thumbnail-wrapper"> 260 <button class="thumb-nav prev" onclick="scrollThumbs('@sliderId', -1)"> 261 <svg width="20px" height="20px" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" fill="#1D98A5"> 262 263 <g stroke="none" stroke-width="1" fill="none" fill-rule="evenodd"> 264 <g transform="translate(-336.000000, 0.000000)"> 265 <g id="left_line" transform="translate(336.000000, 0.000000)"> 266 <path d="M24,0 L24,24 L0,24 L0,0 L24,0 Z M12.5934901,23.257841 L12.5819402,23.2595131 L12.5108777,23.2950439 L12.4918791,23.2987469 L12.4918791,23.2987469 L12.4767152,23.2950439 L12.4056548,23.2595131 C12.3958229,23.2563662 12.3870493,23.2590235 12.3821421,23.2649074 L12.3780323,23.275831 L12.360941,23.7031097 L12.3658947,23.7234994 L12.3769048,23.7357139 L12.4804777,23.8096931 L12.4953491,23.8136134 L12.4953491,23.8136134 L12.5071152,23.8096931 L12.6106902,23.7357139 L12.6232938,23.7196733 L12.6232938,23.7196733 L12.6266527,23.7031097 L12.609561,23.275831 C12.6075724,23.2657013 12.6010112,23.2592993 12.5934901,23.257841 L12.5934901,23.257841 Z M12.8583906,23.1452862 L12.8445485,23.1473072 L12.6598443,23.2396597 L12.6498822,23.2499052 L12.6498822,23.2499052 L12.6471943,23.2611114 L12.6650943,23.6906389 L12.6699349,23.7034178 L12.6699349,23.7034178 L12.678386,23.7104931 L12.8793402,23.8032389 C12.8914285,23.8068999 12.9022333,23.8029875 12.9078286,23.7952264 L12.9118235,23.7811639 L12.8776777,23.1665331 C12.8752882,23.1545897 12.8674102,23.1470016 12.8583906,23.1452862 L12.8583906,23.1452862 Z M12.1430473,23.1473072 C12.1332178,23.1423925 12.1221763,23.1452606 12.1156365,23.1525954 L12.1099173,23.1665331 L12.0757714,23.7811639 C12.0751323,23.7926639 12.0828099,23.8018602 12.0926481,23.8045676 L12.108256,23.8032389 L12.3092106,23.7104931 L12.3186497,23.7024347 L12.3186497,23.7024347 L12.3225043,23.6906389 L12.340401,23.2611114 L12.337245,23.2485176 L12.337245,23.2485176 L12.3277531,23.2396597 L12.1430473,23.1473072 Z" id="MingCute" fill-rule="nonzero"> </path> 267 <path d="M8.29292,12.7071 C7.9024,12.3166 7.9024,11.6834 8.29292,11.2929 L13.9498,5.63604 C14.3403,5.24551 14.9735,5.24551 15.364,5.63604 C15.7545,6.02656 15.7545,6.65973 15.364,7.05025 L10.4142,12 L15.364,16.9497 C15.7545,17.3403 15.7545,17.9734 15.364,18.364 C14.9735,18.7545 14.3403,18.7545 13.9498,18.364 L8.29292,12.7071 Z" id="路径" fill="#1D98A5"> </path> 268 </g> 269 </g> 270 </g> 271 </svg> 272 273 </button> 274 <div class="thumbnail-scroll" id="@sliderId"> 275 @{ 276 VariantGroupViewModel group = variantGroup; 277 foreach (var option in group.Options.OrderBy(o => o.Id)) 278 { 279 var productVariant = productService.GetProductById(product.Id, option.Id, false); 280 281 var productSelection = new PriceProductSelection(productVariant, null, 0); 282 283 var currencyCode = string.IsNullOrWhiteSpace(Pageview.User.Currency) ? Pageview.Area.EcomCurrencyId : Pageview.User.Currency; 284 var countryCode = string.IsNullOrWhiteSpace(Pageview.User.CountryCode) ? Pageview.Area.EcomCountryCode : Pageview.User.CountryCode; 285 286 var userCurrency = Dynamicweb.Ecommerce.Services.Currencies.GetCurrency(currencyCode); 287 var userCountry = Dynamicweb.Ecommerce.Services.Countries.GetCountry(countryCode); 288 289 var priceContext = new PriceContext(userCurrency, userCountry, null, Pageview.User, false, null); 290 var productPrice = Dynamicweb.Ecommerce.Services.Prices.FindPrices(priceContext, productSelection, false); 291 292 //throw new Exception(System.Text.Json.JsonSerializer.Serialize(productPrice)); 293 294 var fieldValue = productVariant?.ProductFieldValues?.GetProductFieldValue("BlockedCustomerList")?.Value; 295 296 if ((fieldValue != null && !fieldValue.ToString().Contains(customerNumber)) || String.IsNullOrWhiteSpace(customerNumber)) 297 { 298 299 300 string active = variantId != null && variantId.Contains(option.Id) ? "active" : string.Empty; 301 string buttonId = $"{product.Id}_{option.Id}_{Pageview.CurrentParagraph.ID}"; 302 string contrastColor = string.Empty; 303 304 string searchKey = $"{product.Id}_{option.Id}_"; 305 /*Images*/ 306 var imagePathVariant = option.Image?.Value ?? ""; 307 308 309 var folderPath = Path.GetDirectoryName(imagePathVariant); 310 311 string physicalFolderPath = Dynamicweb.Context.Current.Server.MapPath(folderPath); 312 313 string lastImage = null; 314 315 if (Directory.Exists(physicalFolderPath)) 316 { 317 318 var fileWith15 = Directory.GetFiles(physicalFolderPath) 319 .FirstOrDefault(f => Path.GetFileName(f).Contains($"{product.Id}_{option.Id}_9")); 320 321 if (fileWith15 != null) 322 { 323 lastImage = fileWith15; 324 } 325 else 326 { 327 var files = Directory.GetFiles(physicalFolderPath) 328 .Where(f => Path.GetFileName(f).StartsWith($"{product.Id}_{option.Id}_")) 329 .OrderByDescending(f => 330 { 331 var filename = Path.GetFileNameWithoutExtension(f); 332 var match = System.Text.RegularExpressions.Regex.Match(filename, @"_(\d+)$"); 333 if (match.Success && int.TryParse(match.Groups[1].Value, out int index)) 334 { 335 return index; 336 } 337 return 0; 338 }) 339 .ToList(); 340 341 if (files.Any()) 342 { 343 lastImage = files.First(); 344 } 345 } 346 } 347 348 var lastImageUrl = lastImage != null ? lastImage : "/Files/Images/zijlstra/Afbeeldingen_overig/Coming_Soon.jpg"; 349 int index = lastImageUrl.IndexOf("Files"); 350 string relativePath = index >= 0 ? lastImageUrl.Substring(index).Replace("\\", "/") : lastImageUrl.Replace("\\", "/"); 351 lastImageUrl = "/" + relativePath; 352 lastImageUrl = Dynamicweb.Context.Current.Server.UrlEncode(lastImageUrl); 353 var variantImg = option.Image is object ? Dynamicweb.Context.Current.Server.UrlEncode(option.Image.Value) : null; 354 var variantLink = "/Default.aspx?ID=" + GetPageIdByNavigationTag("Shop") + "&GroupID=" + product.PrimaryOrDefaultGroup.Id + "&ProductID=" + product.Id + "&VariantID=" + option.Id; 355 356 string variantImage = string.Empty; 357 variantImages.TryGetValue(option.Id, out variantImage); 358 /*End Images*/ 359 360 /*stock state*/ 361 double variantStock = productVariant.Stock; 362 string svgInStock = "<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"16\" height=\"16\" fill=\"#44B11A\" class=\"bi bi-check-lg\" viewBox=\"0 0 16 16\"><path d=\"M12.736 3.97a.733.733 0 0 1 1.047 0c.286.289.29.756.01 1.05L7.88 12.01a.733.733 0 0 1-1.065.02L3.217 8.384a.757.757 0 0 1 0-1.06.733.733 0 0 1 1.047 0l3.052 3.093 5.4-6.425z\"/></svg>"; 363 string svgOutStock = "<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"25\" height=\"25\" fill=\"#CA0D0D\" class=\"bi bi-x-lg\" viewBox=\"0 0 16 16\"><path d=\"M4.646 4.646a.5.5 0 0 1 .708 0L8 7.293l2.646-2.647a.5.5 0 0 1 .708.708L8.707 8l2.647 2.646a.5.5 0 0 1-.708.708L8 8.707l-2.646 2.647a.5.5 0 0 1-.708-.708L7.293 8 4.646 5.354a.5.5 0 0 1 0-.708\"/></svg>"; 364 365 string infoStock = "<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"16\" height=\"16\" fill=\"currentColor\" class=\"bi bi-info-circle-fill\" viewBox=\"0 0 16 16\"><path d=\"M8 16A8 8 0 1 0 8 0a8 8 0 0 0 0 16m.93-9.412-1 4.705c-.07.34.029.533.304.533.194 0 .487-.07.686-.246l-.088.416c-.287.346-.92.598-1.465.598-.703 0-1.002-.422-.808-1.319l.738-3.468c.064-.293.006-.399-.287-.47l-.451-.081.082-.381 2.29-.287zM8 5.5a1 1 0 1 1 0-2 1 1 0 0 1 0 2\" /></svg>"; 366 string isNew = productVariant?.ProductFieldValues?.GetProductFieldValue("New")?.Value?.ToString().ToLower() ?? ""; 367 string isNewSvg = "<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"16\" height=\"16\" fill=\"#F2C400\" class=\"bi bi-star-fill\" viewBox=\"0 0 16 16\"><path d = \"M3.612 15.443c-.386.198-.824-.149-.746-.592l.83-4.73L.173 6.765c-.329-.314-.158-.888.283-.95l4.898-.696L7.538.792c.197-.39.73-.39.927 0l2.184 4.327 4.898.696c.441.062.612.636.282.95l-3.522 3.356.83 4.73c.078.443-.36.79-.746.592L8 13.187l-4.389 2.256z\" /></svg> "; 368 string stockState = ""; 369 370 string isSale = productVariant?.ProductFieldValues?.GetProductFieldValue("Sale")?.Value?.ToString().ToLower() ?? ""; 371 string isSaleSvg = "<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"16\" height=\"16\" fill=\"#F03232\" class=\"bi bi-star-fill\" viewBox=\"0 0 16 16\"><path d = \"M3.612 15.443c-.386.198-.824-.149-.746-.592l.83-4.73L.173 6.765c-.329-.314-.158-.888.283-.95l4.898-.696L7.538.792c.197-.39.73-.39.927 0l2.184 4.327 4.898.696c.441.062.612.636.282.95l-3.522 3.356.83 4.73c.078.443-.36.79-.746.592L8 13.187l-4.389 2.256z\" /></svg> "; 372 373 string expectedDeliveryDate = ""; 374 375 if (DateTime.Compare(productVariant.ExpectedDelivery, new DateTime(1900, 1, 1)) != 0) //In DW, if the Date is not set, it is defaulted 01-01-1900 and not null.. 376 { 377 expectedDeliveryDate = productVariant.ExpectedDelivery.ToShortDateString(); 378 } 379 380 string expectedDeliveryDateText = !String.IsNullOrWhiteSpace(expectedDeliveryDate) ? Translate("Verwacht:") + "&nbsp;" + expectedDeliveryDate : ""; 381 382 @if (!(bool?)productVariant.ProductFieldValues.Where(o => o.ProductField.SystemName == "ProductToBeDiscontinued").SingleOrDefault()?.Value ?? false) 383 { 384 if (variantStock > 0) 385 { 386 if (isNew == "true" || isSale == "true") 387 { 388 if (isSale == "true") 389 { 390 stockState += isSaleSvg + "&nbsp; &nbsp;" + Translate("Sale!") + "<br/>"; 391 } 392 393 if (isNew == "true") 394 { 395 stockState += isNewSvg + "&nbsp; &nbsp;" + Translate("New!") + "<br/>"; 396 } 397 398 stockState += "&nbsp;" + Translate("Nu leverbaar"); 399 } 400 else 401 { 402 stockState = svgInStock + "&nbsp; " + Translate("Op voorraad"); 403 404 } 405 } 406 else 407 { 408 stockState = svgOutStock + "&nbsp;" + Translate("Geen voorraad") + "<br/>" + expectedDeliveryDateText; 409 410 } 411 } 412 else 413 { 414 415 stockState = svgOutStock + "&nbsp;" + Translate("Discontinued:") + "<br/>" + variantStock + "&nbsp;" + @Translate("left in stock"); 416 417 } 418 /*End stock state*/ 419 /*Price variants*/ 420 double price = productVariant.DefaultPrice; 421 double cost = productVariant.Cost; 422 423 string priceFormated = Dynamicweb.Ecommerce.Services.Currencies.Format(Dynamicweb.Ecommerce.Services.Currencies.GetCurrency(currency), Convert.ToDouble(productPrice.ToList()[0].Amount, formatProvider)); 424 //string priceFormated = Dynamicweb.Ecommerce.Services.Currencies.Format(Dynamicweb.Ecommerce.Services.Currencies.GetCurrency(currency), Convert.ToDouble(price, formatProvider)); 425 426 427 428 /*End Price variants*/ 429 430 <img class="theme thumbnail" data-stockstate="@WebUtility.HtmlEncode(stockState)" src="/Admin/Public/GetImage.ashx?image=@(lastImageUrl)&width=64&format=webp" onclick="selectVariant('@(product.Id)','/Admin/Public/GetImage.ashx?image=@(variantImg)&format=webp','@variantLink','@product.Id','@option.Id','@option.Name',this.dataset.stockstate,'@isNew','@isSale','@priceFormated','@cost')" /> 431 432 433 } 434 } 435 436 } 437 </div> 438 <button class="thumb-nav next" onclick="scrollThumbs('@sliderId', 1)"> 439 <svg width="20px" height="20px" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" fill="#1D98A5"> 440 441 <g stroke="none" stroke-width="1" fill="none" fill-rule="evenodd"> 442 <g transform="translate(-384.000000, 0.000000)"> 443 <g id="right_line" transform="translate(384.000000, 0.000000)"> 444 <path d="M24,0 L24,24 L0,24 L0,0 L24,0 Z M12.5934901,23.257841 L12.5819402,23.2595131 L12.5108777,23.2950439 L12.4918791,23.2987469 L12.4918791,23.2987469 L12.4767152,23.2950439 L12.4056548,23.2595131 C12.3958229,23.2563662 12.3870493,23.2590235 12.3821421,23.2649074 L12.3780323,23.275831 L12.360941,23.7031097 L12.3658947,23.7234994 L12.3769048,23.7357139 L12.4804777,23.8096931 L12.4953491,23.8136134 L12.4953491,23.8136134 L12.5071152,23.8096931 L12.6106902,23.7357139 L12.6232938,23.7196733 L12.6232938,23.7196733 L12.6266527,23.7031097 L12.609561,23.275831 C12.6075724,23.2657013 12.6010112,23.2592993 12.5934901,23.257841 L12.5934901,23.257841 Z M12.8583906,23.1452862 L12.8445485,23.1473072 L12.6598443,23.2396597 L12.6498822,23.2499052 L12.6498822,23.2499052 L12.6471943,23.2611114 L12.6650943,23.6906389 L12.6699349,23.7034178 L12.6699349,23.7034178 L12.678386,23.7104931 L12.8793402,23.8032389 C12.8914285,23.8068999 12.9022333,23.8029875 12.9078286,23.7952264 L12.9118235,23.7811639 L12.8776777,23.1665331 C12.8752882,23.1545897 12.8674102,23.1470016 12.8583906,23.1452862 L12.8583906,23.1452862 Z M12.1430473,23.1473072 C12.1332178,23.1423925 12.1221763,23.1452606 12.1156365,23.1525954 L12.1099173,23.1665331 L12.0757714,23.7811639 C12.0751323,23.7926639 12.0828099,23.8018602 12.0926481,23.8045676 L12.108256,23.8032389 L12.3092106,23.7104931 L12.3186497,23.7024347 L12.3186497,23.7024347 L12.3225043,23.6906389 L12.340401,23.2611114 L12.337245,23.2485176 L12.337245,23.2485176 L12.3277531,23.2396597 L12.1430473,23.1473072 Z" id="MingCute" fill-rule="nonzero"> </path> 445 <path d="M15.7072,11.2929 C16.0977,11.6834 16.0977,12.3166 15.7072,12.7071 L10.0503,18.364 C9.65982,18.7545 9.02666,18.7545 8.63613,18.364 C8.24561,17.9734 8.24561,17.3403 8.63613,16.9497 L13.5859,12 L8.63613,7.05025 C8.24561,6.65973 8.24561,6.02656 8.63613,5.63604 C9.02666,5.24551 9.65982,5.24551 10.0503,5.63604 L15.7072,11.2929 Z" id="路径" fill="#1D98A5"> </path> 446 </g> 447 </g> 448 449 </svg> 450 451 </button> 452 </div> 453 } 454 455 456 </div> 457 458 } 459 if ((fieldValueBlocked != null && !fieldValueBlocked.ToString().Contains(customerNumber)) || String.IsNullOrWhiteSpace(customerNumber)) 460 { 461 <div class="stock-state pt-2 mt-auto"> 462 @{ 463 464 /*stock state*/ 465 double MainvariantStock = MainVariant.Stock; 466 string MainsvgInStock = "<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"16\" height=\"16\" fill=\"#44B11A\" class=\"bi bi-check-lg\" viewBox=\"0 0 16 16\"><path d=\"M12.736 3.97a.733.733 0 0 1 1.047 0c.286.289.29.756.01 1.05L7.88 12.01a.733.733 0 0 1-1.065.02L3.217 8.384a.757.757 0 0 1 0-1.06.733.733 0 0 1 1.047 0l3.052 3.093 5.4-6.425z\"/></svg>"; 467 string MainsvgOutStock = "<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"25\" height=\"25\" fill=\"#CA0D0D\" class=\"bi bi-x-lg\" viewBox=\"0 0 16 16\"><path d=\"M4.646 4.646a.5.5 0 0 1 .708 0L8 7.293l2.646-2.647a.5.5 0 0 1 .708.708L8.707 8l2.647 2.646a.5.5 0 0 1-.708.708L8 8.707l-2.646 2.647a.5.5 0 0 1-.708-.708L7.293 8 4.646 5.354a.5.5 0 0 1 0-.708\"/></svg>"; 468 469 string MaininfoStock = "<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"16\" height=\"16\" fill=\"currentColor\" class=\"bi bi-info-circle-fill\" viewBox=\"0 0 16 16\"><path d=\"M8 16A8 8 0 1 0 8 0a8 8 0 0 0 0 16m.93-9.412-1 4.705c-.07.34.029.533.304.533.194 0 .487-.07.686-.246l-.088.416c-.287.346-.92.598-1.465.598-.703 0-1.002-.422-.808-1.319l.738-3.468c.064-.293.006-.399-.287-.47l-.451-.081.082-.381 2.29-.287zM8 5.5a1 1 0 1 1 0-2 1 1 0 0 1 0 2\" /></svg>"; 470 string MainisNew = MainVariant?.ProductFieldValues?.GetProductFieldValue("New")?.Value?.ToString().ToLower() ?? ""; 471 string MainisNewSvg = "<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"16\" height=\"16\" fill=\"#F2C400\" class=\"bi bi-star-fill\" viewBox=\"0 0 16 16\"><path d = \"M3.612 15.443c-.386.198-.824-.149-.746-.592l.83-4.73L.173 6.765c-.329-.314-.158-.888.283-.95l4.898-.696L7.538.792c.197-.39.73-.39.927 0l2.184 4.327 4.898.696c.441.062.612.636.282.95l-3.522 3.356.83 4.73c.078.443-.36.79-.746.592L8 13.187l-4.389 2.256z\" /></svg> "; 472 string MainstockState = ""; 473 string MainIsSale = MainVariant?.ProductFieldValues?.GetProductFieldValue("Sale")?.Value?.ToString().ToLower() ?? ""; 474 string MainIsSaleSvg = "<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"16\" height=\"16\" fill=\"#F03232\" class=\"bi bi-star-fill\" viewBox=\"0 0 16 16\"><path d = \"M3.612 15.443c-.386.198-.824-.149-.746-.592l.83-4.73L.173 6.765c-.329-.314-.158-.888.283-.95l4.898-.696L7.538.792c.197-.39.73-.39.927 0l2.184 4.327 4.898.696c.441.062.612.636.282.95l-3.522 3.356.83 4.73c.078.443-.36.79-.746.592L8 13.187l-4.389 2.256z\" /></svg> "; 475 string MainexpectedDeliveryDate = ""; 476 477 if (DateTime.Compare(MainVariant.ExpectedDelivery, new DateTime(1900, 1, 1)) != 0) //In DW, if the Date is not set, it is defaulted 01-01-1900 and not null.. 478 { 479 MainexpectedDeliveryDate = MainVariant.ExpectedDelivery.ToShortDateString(); 480 } 481 482 string MainexpectedDeliveryDateText = !String.IsNullOrWhiteSpace(MainexpectedDeliveryDate) ? Translate("Verwacht:") + "&nbsp;" + MainexpectedDeliveryDate : ""; 483 484 @if (!(bool?)MainVariant.ProductFieldValues.Where(o => o.ProductField.SystemName == "ProductToBeDiscontinued").SingleOrDefault()?.Value ?? false) 485 { 486 if (MainvariantStock > 0) 487 { 488 if (MainisNew == "true" || MainIsSale == "true") 489 { 490 if (MainIsSale == "true") 491 { 492 MainstockState += MainIsSaleSvg + "&nbsp; &nbsp;" + Translate("Sale!") + "<br/>"; 493 } 494 495 if (MainisNew == "true") 496 { 497 MainstockState += MainisNewSvg + "&nbsp; &nbsp;" + Translate("New!") + "<br/>"; 498 } 499 500 MainstockState += "&nbsp;" + Translate("Nu leverbaar"); 501 } 502 else 503 { 504 MainstockState = MainsvgInStock + "&nbsp; " + Translate("Op voorraad"); 505 506 } 507 } 508 else 509 { 510 MainstockState = MainsvgOutStock + "&nbsp;" + Translate("Geen voorraad") + "<br/>" + MainexpectedDeliveryDateText; 511 512 } 513 } 514 else 515 { 516 517 MainstockState = MainsvgOutStock + "&nbsp;" + Translate("Discontinued:") + "<br/>" + MainvariantStock + "&nbsp;" + @Translate("left in stock"); 518 519 } 520 /*End stock state*/ 521 522 523 @MainstockState 524 525 526 } 527 </div> 528 } 529 else 530 { 531 <div class="stock-state pt-2 mt-auto"> 532 @MainOutStock @Translate("Discontinued") 533 </div> 534 } 535 <div class="custom-price mt-auto"> 536 @{ 537 538 539 540 541 bool isErpConnectionDown = !Dynamicweb.Core.Converter.ToBoolean(Dynamicweb.Context.Current.Items["IsWebServiceConnectionAvailable"]); 542 bool hidePrice = anonymousUsersLimitations.Contains("price") && anonymousUser || Pageview.AreaSettings.GetBoolean("ErpDownHidePrices") && isErpConnectionDown; 543 544 bool productIsDiscontinued = product is object && product.Discontinued; 545 bool doNotShowPriceIfProductIsDiscontinued = Model.Item.GetBoolean("DoNotShowPriceIfProductIsDiscontinued"); 546 var isDiscontinued = productIsDiscontinued && doNotShowPriceIfProductIsDiscontinued; 547 } 548 549 @if (product is object && !hidePrice && !isDiscontinued) 550 { 551 string unitId = !string.IsNullOrEmpty(Dynamicweb.Context.Current.Request.Form.Get("UnitId")) ? Dynamicweb.Context.Current.Request.Form.Get("UnitId") : string.Empty; 552 553 string priceFontSize = Model.Item.GetRawValueString("PriceSize", "fs-4"); 554 string horizontalAlign = Model.Item.GetRawValueString("HorizontalAlignment", ""); 555 string layout = Model.Item.GetRawValueString("Layout", "horizontal"); 556 string textAlign = horizontalAlign == "center" ? "text-center" : string.Empty; 557 textAlign = horizontalAlign == "end" ? "text-end" : textAlign; 558 559 horizontalAlign = horizontalAlign == "center" && layout == "horizontal" ? "justify-content-center" : horizontalAlign; 560 horizontalAlign = horizontalAlign == "end" && layout == "horizontal" ? "justify-content-end" : horizontalAlign; 561 horizontalAlign = horizontalAlign == "center" && layout == "vertical" ? "align-items-center" : horizontalAlign; 562 horizontalAlign = horizontalAlign == "end" && layout == "vertical" ? "align-items-end" : horizontalAlign; 563 564 string flexDirection = layout == "horizontal" ? string.Empty : "flex-column"; 565 string flexGap = layout == "horizontal" ? "gap-3" : string.Empty; 566 string order = layout == "horizontal" ? string.Empty : "order-2"; 567 568 569 string contentPadding = Model.Item.GetRawValueString("ContentPadding", ""); 570 contentPadding = contentPadding == "none" ? "p-0" : contentPadding; 571 contentPadding = contentPadding == "small" ? "p-1 px-md-2 py-md-1" : contentPadding; 572 contentPadding = contentPadding == "large" ? "p-2 px-md-3 py-md-2" : contentPadding; 573 string liveInfoClass = ""; 574 575 576 577 578 579 580 if (isLazyLoadingForProductInfoEnabled) 581 { 582 if (Dynamicweb.Context.Current.Items.Contains("ProductInfoFeed")) 583 { 584 productInfoFeed = Dynamicweb.Context.Current.Items["ProductInfoFeed"]?.ToString(); 585 if (!string.IsNullOrEmpty(productInfoFeed)) 586 { 587 productInfoFeed = $"data-product-info-feed=\"{productInfoFeed}\""; 588 } 589 } 590 liveInfoClass = "js-live-info"; 591 } 592 593 <div class="@textAlign @liveInfoClass item_@Model.Item.SystemName.ToLower()" data-product-id="@product.Id" data-variant-id="@product.VariantId" @productInfoFeed> 594 @if (showInformativePrice && product.PriceInformative.Price != 0) 595 { 596 <div class="opacity-50"> 597 <span>@Translate("RRP") </span> 598 <span class="text-decoration-line-through text-price">@product.PriceInformative.PriceFormatted</span> 599 </div> 600 } 601 <div class="@priceFontSize m-0 d-flex flex-wrap @flexDirection @flexGap @horizontalAlign" style="row-gap: 0 !important" itemprop="offers" itemscope itemtype="https://schema.org/Offer"> 602 <span itemprop="priceCurrency" content="@product.Price.CurrencyCode" class="d-none"></span> 603 604 605 @if (showPricesWithVat == "false" && !neverShowVat) 606 { 607 if (isLazyLoadingForProductInfoEnabled && !Pageview.IsVisualEditorMode) 608 { 609 <span itemprop="price" content="" class="d-none"></span> 610 <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> 611 } 612 else 613 { 614 string beforePrice = !string.IsNullOrEmpty(unitId) ? product.GetPrice(unitId).PriceBeforeDiscount.PriceWithoutVatFormatted : product.PriceBeforeDiscount.PriceWithoutVatFormatted; 615 616 <span itemprop="price" content="@product.Price.PriceWithoutVat.ToString("0.00", System.Globalization.CultureInfo.InvariantCulture)" class="d-none"></span> 617 if (product.Price.Price != product.PriceBeforeDiscount.Price) 618 { 619 <span class="text-decoration-line-through opacity-75 @order">@beforePrice</span> 620 } 621 } 622 } 623 else 624 { 625 if (isLazyLoadingForProductInfoEnabled && !Pageview.IsVisualEditorMode) 626 { 627 <span itemprop="price" content="" class="d-none"></span> 628 <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> 629 } 630 else 631 { 632 string beforePrice = !string.IsNullOrEmpty(unitId) ? product.GetPrice(unitId).PriceBeforeDiscount.PriceFormatted : product.PriceBeforeDiscount.PriceFormatted; 633 634 <span itemprop="price" content="@product.Price.Price.ToString("0.00", System.Globalization.CultureInfo.InvariantCulture)" class="d-none"></span> 635 636 if (product.Price.Price != product.PriceBeforeDiscount.Price) 637 { 638 <span class="text-decoration-line-through opacity-75 @order"> 639 <span class="text-price">@beforePrice</span> 640 </span> 641 } 642 } 643 } 644 645 @if (showPricesWithVat == "false" && !neverShowVat) 646 { 647 if (isLazyLoadingForProductInfoEnabled && !Pageview.IsVisualEditorMode) 648 { 649 <span class="text-price js-text-price"> 650 <span class="spinner-border" role="status"></span> 651 </span> 652 } 653 else 654 { 655 string price = !string.IsNullOrEmpty(unitId) ? product.GetPrice(unitId).Price.PriceWithoutVatFormatted : product.Price.PriceWithoutVatFormatted; 656 657 if (product?.VariantInfo?.VariantInfo != null) 658 { 659 priceMin = product?.VariantInfo?.PriceMin?.PriceWithoutVatFormatted != null ? product.VariantInfo.PriceMin.PriceWithoutVatFormatted : ""; 660 priceMax = product?.VariantInfo?.PriceMax?.PriceWithoutVatFormatted != null ? product.VariantInfo.PriceMax.PriceWithoutVatFormatted : ""; 661 } 662 if (priceMin != priceMax) 663 { 664 price = priceMin + " - " + priceMax; 665 } 666 <span class="@theme @contentPadding"> 667 <span class="text-price">@price</span> 668 </span> 669 } 670 } 671 else 672 { 673 if (isLazyLoadingForProductInfoEnabled && !Pageview.IsVisualEditorMode) 674 { 675 <span class="text-price js-text-price"> 676 <span class="spinner-border" role="status"></span> 677 </span> 678 } 679 else 680 { 681 string price = !string.IsNullOrEmpty(unitId) ? product.GetPrice(unitId).Price.PriceFormatted : product.Price.PriceFormatted; 682 683 if (product?.VariantInfo?.VariantInfo != null) 684 { 685 priceMin = product?.VariantInfo?.PriceMin?.PriceFormatted != null ? product.VariantInfo.PriceMin.PriceFormatted : ""; 686 priceMax = product?.VariantInfo?.PriceMax?.PriceFormatted != null ? product.VariantInfo.PriceMax.PriceFormatted : ""; 687 } 688 if (priceMin != priceMax) 689 { 690 price = priceMin + " - " + priceMax; 691 } 692 <span class="@theme @contentPadding"> 693 <span class="text-price">@price</span> 694 </span> 695 } 696 } 697 698 @* Stock state for Schema.org, start *@ 699 @{ 700 Uri url = Dynamicweb.Context.Current.Request.Url; 701 } 702 703 <link itemprop="url" href="@url"> 704 705 @{ 706 bool IsNeverOutOfStock = product.NeverOutOfstock; 707 } 708 709 @if (IsNeverOutOfStock) 710 { 711 <span itemprop="availability" class="d-none">@Translate("Available in stock")</span> 712 } 713 else 714 { 715 if (product.StockLevel > 0) 716 { 717 <span itemprop="availability" class="d-none">InStock</span> 718 } 719 else 720 { 721 <span itemprop="availability" class="d-none">OutOfStock</span> 722 } 723 } 724 @* Stock state for Schema.org, stop *@ 725 726 </div> 727 728 @if (showPricesWithVat == "false" && !neverShowVat) 729 { 730 if (isLazyLoadingForProductInfoEnabled && !Pageview.IsVisualEditorMode) 731 { 732 <small class="opacity-85 fst-normal js-text-price-with-vat d-none" data-suffix="@Translate("Incl. VAT")"></small> 733 } 734 else 735 { 736 string price = !string.IsNullOrEmpty(unitId) ? product.GetPrice(unitId).Price.PriceWithVatFormatted : product.Price.PriceWithVatFormatted; 737 738 if (product?.VariantInfo?.VariantInfo != null) 739 { 740 priceMin = product?.VariantInfo?.PriceMin?.PriceWithVatFormatted != null ? product.VariantInfo.PriceMin.PriceWithVatFormatted : ""; 741 priceMax = product?.VariantInfo?.PriceMax?.PriceWithVatFormatted != null ? product.VariantInfo.PriceMax.PriceWithVatFormatted : ""; 742 } 743 if (priceMin != priceMax) 744 { 745 price = priceMin + " - " + priceMax; 746 } 747 <!-- <small class="opacity-85 fst-normal">@price @Translate("Incl. VAT")</small> --> 748 } 749 } 750 </div> 751 } 752 else if (Pageview.IsVisualEditorMode) 753 { 754 <div class="alert alert-dark m-0" role="alert"> 755 <span>@Translate("No products available")</span> 756 </div> 757 } 758 759 </div> 760 } 761 } 762
Tischlampe 1L lantern
Error executing template "Designs/Swift/Paragraph/CustomProductSlider.cshtml"
System.NullReferenceException: Object reference not set to an instance of an object.
   at CompiledRazorTemplates.Dynamic.RazorEngine_3562354021b44d5c892fe73dc2806e4f.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 Dynamicweb.Ecommerce.ProductCatalog 3 @using Dynamicweb.Ecommerce.CustomerExperienceCenter.Favorites 4 @using Dynamicweb.Files 5 @using System.IO 6 @using System.Net 7 @using Dynamicweb.Security.UserManagement 8 9 10 @{ 11 ProductViewModel product = null; 12 if (Dynamicweb.Context.Current.Items.Contains("ProductDetails")) 13 { 14 product = (ProductViewModel)Dynamicweb.Context.Current.Items["ProductDetails"]; 15 } 16 else if (Pageview.Page.Item["DummyProduct"] != null && Pageview.IsVisualEditorMode) 17 { 18 var pageViewModel = Dynamicweb.Frontend.ContentViewModelFactory.CreatePageInfoViewModel(Pageview.Page); 19 ProductListViewModel productList = pageViewModel.Item.GetValue("DummyProduct") != null ? pageViewModel.Item.GetValue("DummyProduct") as ProductListViewModel : new ProductListViewModel(); 20 21 if (productList?.Products is object) 22 { 23 product = productList.Products[0]; 24 } 25 } 26 } 27 28 @{ 29 var currentUser = Pageview?.User; 30 var customerNumber = !string.IsNullOrEmpty(currentUser?.CustomerNumber) 31 ? currentUser.CustomerNumber 32 : ""; 33 } 34 @if (product is object) 35 { 36 string imagePath = product?.DefaultImage?.Value ?? ""; 37 string imagePathUrlEncoded = Dynamicweb.Context.Current.Server.UrlEncode(imagePath); 38 39 string ratio = Model.Item.GetRawValueString("ImageAspectRatio", ""); 40 ratio = ratio != "0" ? ratio : ""; 41 string ratioCssClass = ratio != "" ? " ratio" : ""; 42 string ratioVariable = ratio != "" ? "--bs-aspect-ratio: " + ratio + ";" : ""; 43 44 string width = Model.Item.GetRawValueString("Width", "auto"); 45 int smallImageSize = 640; 46 int largeImageSize = width == "auto" ? 1280 : Convert.ToInt32(width); 47 48 string ImageObjectFit = Model.Item.GetRawValueString("ImageObjectFit", "contain"); 49 50 string imagePathXs = "/Admin/Public/GetImage.ashx?width=" + smallImageSize + "&image=" + imagePathUrlEncoded + "&format=webp"; 51 string imagePathS = "/Admin/Public/GetImage.ashx?width=" + largeImageSize + "&image=" + imagePathUrlEncoded + "&format=webp"; 52 string imagePathFallBack = "/Admin/Public/GetImage.ashx?width=" + largeImageSize + "&image=" + imagePathUrlEncoded + "&format=webp"; 53 54 var badgeParms = new Dictionary<string, object>(); 55 badgeParms.Add("size", "h7"); 56 badgeParms.Add("saleBadgeType", Model.Item.GetRawValue("SaleBadgeType")); 57 badgeParms.Add("saleBadgeCssClassName", Model.Item.GetRawValue("SaleBadgeDesign")); 58 badgeParms.Add("newBadgeCssClassName", Model.Item.GetRawValue("NewBadgeDesign")); 59 badgeParms.Add("newPublicationDays", Model.Item.GetInt32("NewPublicationDays")); 60 badgeParms.Add("campaignBadgesValues", Model.Item.GetList("CampaignBadges")?.GetRawValue().OfType<string>().ToList()); 61 62 string badgeSize = Model.Item.GetRawValueString("BadgeSize", "fs-2"); 63 bool saleBadgeEnabled = !string.IsNullOrWhiteSpace(Model.Item.GetRawValueString("SaleBadgeDesign")) && Model.Item.GetRawValueString("SaleBadgeDesign") != "none" ? true : false; 64 bool newBadgeEnabled = !string.IsNullOrWhiteSpace(Model.Item.GetRawValueString("NewBadgeDesign")) && Model.Item.GetRawValueString("NewBadgeDesign") != "none" ? true : false; 65 66 /*Custom badge*/ 67 var productService = new Dynamicweb.Ecommerce.Products.ProductService(); 68 var currency = Dynamicweb.Ecommerce.Common.Context.Currency.Code; 69 var formatProvider = new System.Globalization.NumberFormatInfo(); 70 formatProvider.NumberDecimalSeparator = "."; 71 formatProvider.NumberGroupSeparator = ","; 72 var MainVariant = productService.GetProductById(product.Id, product.VariantId, false); 73 var fieldValueBlocked = MainVariant?.ProductFieldValues?.GetProductFieldValue("BlockedCustomerList")?.Value; 74 75 76 string isNewProduct = MainVariant?.ProductFieldValues?.GetProductFieldValue("New")?.Value?.ToString().ToLower() ?? ""; 77 string MainisSale = MainVariant?.ProductFieldValues?.GetProductFieldValue("Sale")?.Value?.ToString().ToLower() ?? ""; 78 bool showNewBadge = isNewProduct == "true" ? true : false; 79 bool showSaleBadge = MainisSale == "true" ? true : false; 80 string showNewSaleBadge = "d-none"; 81 if (showSaleBadge) 82 { 83 badgeParms.Add("isSale", "true"); 84 85 } 86 else 87 { 88 badgeParms.Add("isSale", "false"); 89 } 90 if (showNewBadge) 91 { 92 badgeParms.Add("isNew", "true"); 93 } 94 else 95 { 96 badgeParms.Add("isNew", "false"); 97 } 98 /*End Custom badge*/ 99 if (showSaleBadge || showNewBadge) 100 { 101 showNewSaleBadge = ""; 102 } 103 DateTime createdDate = product.Created.Value; 104 bool showBadges = saleBadgeEnabled && product.Discount.Price != 0 ? true : false; 105 106 bool showFavoritesSelector = !string.IsNullOrEmpty(Model.Item.GetString("ShowAddToFavorites")) ? Model.Item.GetBoolean("ShowAddToFavorites") : false; 107 string anonymousUsersLimitations = Pageview.AreaSettings.GetRawValueString("AnonymousUsers", ""); 108 bool anonymousUser = Pageview.User == null; 109 110 var favoriteParameters = new Dictionary<string, object>(); 111 if (!anonymousUser && showFavoritesSelector) 112 { 113 int defaultFavoriteListId = 0; 114 115 IEnumerable<FavoriteList> favoreiteLists = Pageview.User.GetFavoriteLists(); 116 if (favoreiteLists.Count() == 1) 117 { 118 foreach (FavoriteList list in favoreiteLists) 119 { 120 defaultFavoriteListId = list.ListId; 121 } 122 } 123 124 favoriteParameters.Add("ListId", defaultFavoriteListId); 125 } 126 127 MediaViewModel alternativeImage = new MediaViewModel(); 128 if (Model.Item.GetBoolean("ShowAlternativeImageOnHover")) 129 { 130 var selectedImageCategories = Model.Item.GetList("GetAlternativeImageFrom")?.GetRawValue().OfType<string>().ToList(); 131 List<MediaViewModel> allAssetsImages = product.AssetCategories.Where(x => selectedImageCategories.Contains(x.SystemName)).SelectMany(x => x.Assets).ToList(); 132 allAssetsImages.RemoveAll(x => x.Value == product.DefaultImage.Value); 133 alternativeImage = allAssetsImages.FirstOrDefault(); 134 } 135 136 string altImagePathXs = string.Empty; 137 string altImagePathS = string.Empty; 138 139 if (!string.IsNullOrEmpty(alternativeImage?.Value)) 140 { 141 altImagePathXs = "/Admin/Public/GetImage.ashx?width=" + smallImageSize + "&image=" + Dynamicweb.Context.Current.Server.UrlEncode(alternativeImage.Value) + "&format=webp"; 142 altImagePathS = "/Admin/Public/GetImage.ashx?width=" + largeImageSize + "&image=" + Dynamicweb.Context.Current.Server.UrlEncode(alternativeImage.Value) + "&format=webp"; 143 } 144 145 @* Theme settings *@ 146 string theme = !string.IsNullOrWhiteSpace(Model.Item.GetRawValueString("Theme")) ? " theme " + Model.Item.GetRawValueString("Theme").Replace(" ", "").Trim().ToLower() : ""; 147 string themeBorder = !string.IsNullOrWhiteSpace(theme) ? "border: 1px solid rgba(0,0,0,0)" : ""; 148 string themePadding = !string.IsNullOrWhiteSpace(theme) ? "p-2 p-lg-3" : ""; 149 150 string imageId = "ProductImage_" + product.Id; 151 152 153 154 string fullWidth = width == "auto" ? "w-100" : ""; 155 string customWidth = width != "auto" ? "style=\"width: " + width + "px\"" : "style=\"min-width: 60px\""; 156 157 string altImageZindex = Model.Item.GetBoolean("ShowAlternativeImageOnHover") && !string.IsNullOrEmpty(alternativeImage?.Value) ? " z-index: 1" : string.Empty; 158 string groupid = !string.IsNullOrEmpty(Dynamicweb.Context.Current.Request.QueryString.Get("GroupID")) ? Dynamicweb.Context.Current.Request.QueryString.Get("GroupID"):"" ; 159 string link = product.GetProductLink(GetPageIdByNavigationTag("Shop"), false); 160 var productVariantGroups = product.VariantGroups(); 161 string MainOutStock = "<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"25\" height=\"25\" fill=\"#CA0D0D\" class=\"bi bi-x-lg\" viewBox=\"0 0 16 16\"><path d=\"M4.646 4.646a.5.5 0 0 1 .708 0L8 7.293l2.646-2.647a.5.5 0 0 1 .708.708L8.707 8l2.647 2.646a.5.5 0 0 1-.708.708L8 8.707l-2.646 2.647a.5.5 0 0 1-.708-.708L7.293 8 4.646 5.354a.5.5 0 0 1 0-.708\"/></svg>"; 162 163 @if (!string.IsNullOrEmpty(imagePath)) 164 { 165 <div class="@fullWidth @theme position-relative item_@Model.Item.SystemName.ToLower() main-image-container" @customWidth> 166 <div class="" style="@(ratioVariable)@(altImageZindex)"> 167 <div class="d-flex justify-content-center align-items-center"> 168 <a class="main-link-link" href="@link"> 169 @if (imagePath.StartsWith("/Files/", StringComparison.OrdinalIgnoreCase)) 170 { 171 <img id="@imageId" 172 srcset=" 173 @imagePathXs @(smallImageSize)w, 174 @imagePathS @(largeImageSize)w" 175 sizes="(max-width: 992px) 50vw, 25vw" 176 src="@imagePathFallBack" 177 loading="lazy" 178 decoding="async" 179 class="h-100 w-100 @themePadding main-image" 180 style="object-fit: @ImageObjectFit; @themeBorder " 181 alt="@product.Name" 182 itemprop="image"> 183 } 184 else 185 { 186 <img src="@product.DefaultImage.Value" 187 loading="lazy" 188 class="h-100 w-100 @themePadding main-image" 189 style="object-fit: contain; @themeBorder" 190 alt="@product.Name" 191 itemprop="image"> 192 } 193 </a> 194 </div> 195 </div> 196 197 <div class="position-absolute top-0 left-0 p-2 pb-0 custom-badge-product-list @showNewSaleBadge"> 198 @{ 199 @RenderPartial("Components/Custom_EcommerceBadge.cshtml", product, badgeParms) 200 } 201 </div> 202 203 204 </div> 205 } 206 207 <div class="product-info h-100"> 208 <div class="fs-7 pt-1 opacity-85 start item_@Model.Item.SystemName.ToLower() product-number" itemprop="sku">@product.Id / @product.VariantId - @product.VariantName</div> 209 <div class="py-2" data-col-size="12"> 210 <h2 class="h6 start m-0 item_swift_productheader product-name" itemprop="name"><b>@product.Name</b></h2> 211 </div> 212 </div> 213 var sliderId = $"thumb-scroll-{product.Id}"; 214 if (productVariantGroups.Any() && product?.VariantInfo?.VariantInfo != null) 215 216 { 217 @using Dynamicweb.Ecommerce.Prices 218 @{ 219 string[] variantId = product.VariantId.Split('.'); 220 string showPricesWithVat = Pageview.Area.EcomPricesWithVat.ToLower(); 221 bool neverShowVat = string.IsNullOrEmpty(showPricesWithVat); 222 bool showInformativePrice = Model.Item.GetBoolean("ShowInformativePrice"); 223 string productInfoFeed = ""; 224 bool isLazyLoadingForProductInfoEnabled = Dynamicweb.Core.Converter.ToBoolean(Dynamicweb.Context.Current.Items["IsLazyLoadingForProductInfoEnabled"]); 225 if (isLazyLoadingForProductInfoEnabled) 226 { 227 if (Dynamicweb.Context.Current.Items.Contains("ProductInfoFeed")) 228 { 229 productInfoFeed = Dynamicweb.Context.Current.Items["ProductInfoFeed"]?.ToString(); 230 if (!string.IsNullOrEmpty(productInfoFeed)) 231 { 232 productInfoFeed =productInfoFeed; 233 } 234 } 235 236 } 237 string priceMin = ""; 238 string priceMax = ""; 239 int groupNumber = 1; 240 241 242 243 244 string baseUrl = $"Default.aspx?ID={GetPageIdByNavigationTag("Shop")}&GroupID={product.PrimaryOrDefaultGroup.Id}&ProductID={product.Id}"; 245 if (!string.IsNullOrEmpty(baseUrl)) 246 { 247 baseUrl = $"/{baseUrl.TrimStart('/')}"; 248 } 249 string variantUrl = string.Empty; 250 251 252 Dictionary<string, string> 253 variantImages = new Dictionary<string, string> 254 (); 255 <div class="last-row mt-auto"> 256 257 @foreach (var variantGroup in productVariantGroups) 258 { 259 <div class="thumbnail-wrapper"> 260 <button class="thumb-nav prev" onclick="scrollThumbs('@sliderId', -1)"> 261 <svg width="20px" height="20px" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" fill="#1D98A5"> 262 263 <g stroke="none" stroke-width="1" fill="none" fill-rule="evenodd"> 264 <g transform="translate(-336.000000, 0.000000)"> 265 <g id="left_line" transform="translate(336.000000, 0.000000)"> 266 <path d="M24,0 L24,24 L0,24 L0,0 L24,0 Z M12.5934901,23.257841 L12.5819402,23.2595131 L12.5108777,23.2950439 L12.4918791,23.2987469 L12.4918791,23.2987469 L12.4767152,23.2950439 L12.4056548,23.2595131 C12.3958229,23.2563662 12.3870493,23.2590235 12.3821421,23.2649074 L12.3780323,23.275831 L12.360941,23.7031097 L12.3658947,23.7234994 L12.3769048,23.7357139 L12.4804777,23.8096931 L12.4953491,23.8136134 L12.4953491,23.8136134 L12.5071152,23.8096931 L12.6106902,23.7357139 L12.6232938,23.7196733 L12.6232938,23.7196733 L12.6266527,23.7031097 L12.609561,23.275831 C12.6075724,23.2657013 12.6010112,23.2592993 12.5934901,23.257841 L12.5934901,23.257841 Z M12.8583906,23.1452862 L12.8445485,23.1473072 L12.6598443,23.2396597 L12.6498822,23.2499052 L12.6498822,23.2499052 L12.6471943,23.2611114 L12.6650943,23.6906389 L12.6699349,23.7034178 L12.6699349,23.7034178 L12.678386,23.7104931 L12.8793402,23.8032389 C12.8914285,23.8068999 12.9022333,23.8029875 12.9078286,23.7952264 L12.9118235,23.7811639 L12.8776777,23.1665331 C12.8752882,23.1545897 12.8674102,23.1470016 12.8583906,23.1452862 L12.8583906,23.1452862 Z M12.1430473,23.1473072 C12.1332178,23.1423925 12.1221763,23.1452606 12.1156365,23.1525954 L12.1099173,23.1665331 L12.0757714,23.7811639 C12.0751323,23.7926639 12.0828099,23.8018602 12.0926481,23.8045676 L12.108256,23.8032389 L12.3092106,23.7104931 L12.3186497,23.7024347 L12.3186497,23.7024347 L12.3225043,23.6906389 L12.340401,23.2611114 L12.337245,23.2485176 L12.337245,23.2485176 L12.3277531,23.2396597 L12.1430473,23.1473072 Z" id="MingCute" fill-rule="nonzero"> </path> 267 <path d="M8.29292,12.7071 C7.9024,12.3166 7.9024,11.6834 8.29292,11.2929 L13.9498,5.63604 C14.3403,5.24551 14.9735,5.24551 15.364,5.63604 C15.7545,6.02656 15.7545,6.65973 15.364,7.05025 L10.4142,12 L15.364,16.9497 C15.7545,17.3403 15.7545,17.9734 15.364,18.364 C14.9735,18.7545 14.3403,18.7545 13.9498,18.364 L8.29292,12.7071 Z" id="路径" fill="#1D98A5"> </path> 268 </g> 269 </g> 270 </g> 271 </svg> 272 273 </button> 274 <div class="thumbnail-scroll" id="@sliderId"> 275 @{ 276 VariantGroupViewModel group = variantGroup; 277 foreach (var option in group.Options.OrderBy(o => o.Id)) 278 { 279 var productVariant = productService.GetProductById(product.Id, option.Id, false); 280 281 var productSelection = new PriceProductSelection(productVariant, null, 0); 282 283 var currencyCode = string.IsNullOrWhiteSpace(Pageview.User.Currency) ? Pageview.Area.EcomCurrencyId : Pageview.User.Currency; 284 var countryCode = string.IsNullOrWhiteSpace(Pageview.User.CountryCode) ? Pageview.Area.EcomCountryCode : Pageview.User.CountryCode; 285 286 var userCurrency = Dynamicweb.Ecommerce.Services.Currencies.GetCurrency(currencyCode); 287 var userCountry = Dynamicweb.Ecommerce.Services.Countries.GetCountry(countryCode); 288 289 var priceContext = new PriceContext(userCurrency, userCountry, null, Pageview.User, false, null); 290 var productPrice = Dynamicweb.Ecommerce.Services.Prices.FindPrices(priceContext, productSelection, false); 291 292 //throw new Exception(System.Text.Json.JsonSerializer.Serialize(productPrice)); 293 294 var fieldValue = productVariant?.ProductFieldValues?.GetProductFieldValue("BlockedCustomerList")?.Value; 295 296 if ((fieldValue != null && !fieldValue.ToString().Contains(customerNumber)) || String.IsNullOrWhiteSpace(customerNumber)) 297 { 298 299 300 string active = variantId != null && variantId.Contains(option.Id) ? "active" : string.Empty; 301 string buttonId = $"{product.Id}_{option.Id}_{Pageview.CurrentParagraph.ID}"; 302 string contrastColor = string.Empty; 303 304 string searchKey = $"{product.Id}_{option.Id}_"; 305 /*Images*/ 306 var imagePathVariant = option.Image?.Value ?? ""; 307 308 309 var folderPath = Path.GetDirectoryName(imagePathVariant); 310 311 string physicalFolderPath = Dynamicweb.Context.Current.Server.MapPath(folderPath); 312 313 string lastImage = null; 314 315 if (Directory.Exists(physicalFolderPath)) 316 { 317 318 var fileWith15 = Directory.GetFiles(physicalFolderPath) 319 .FirstOrDefault(f => Path.GetFileName(f).Contains($"{product.Id}_{option.Id}_9")); 320 321 if (fileWith15 != null) 322 { 323 lastImage = fileWith15; 324 } 325 else 326 { 327 var files = Directory.GetFiles(physicalFolderPath) 328 .Where(f => Path.GetFileName(f).StartsWith($"{product.Id}_{option.Id}_")) 329 .OrderByDescending(f => 330 { 331 var filename = Path.GetFileNameWithoutExtension(f); 332 var match = System.Text.RegularExpressions.Regex.Match(filename, @"_(\d+)$"); 333 if (match.Success && int.TryParse(match.Groups[1].Value, out int index)) 334 { 335 return index; 336 } 337 return 0; 338 }) 339 .ToList(); 340 341 if (files.Any()) 342 { 343 lastImage = files.First(); 344 } 345 } 346 } 347 348 var lastImageUrl = lastImage != null ? lastImage : "/Files/Images/zijlstra/Afbeeldingen_overig/Coming_Soon.jpg"; 349 int index = lastImageUrl.IndexOf("Files"); 350 string relativePath = index >= 0 ? lastImageUrl.Substring(index).Replace("\\", "/") : lastImageUrl.Replace("\\", "/"); 351 lastImageUrl = "/" + relativePath; 352 lastImageUrl = Dynamicweb.Context.Current.Server.UrlEncode(lastImageUrl); 353 var variantImg = option.Image is object ? Dynamicweb.Context.Current.Server.UrlEncode(option.Image.Value) : null; 354 var variantLink = "/Default.aspx?ID=" + GetPageIdByNavigationTag("Shop") + "&GroupID=" + product.PrimaryOrDefaultGroup.Id + "&ProductID=" + product.Id + "&VariantID=" + option.Id; 355 356 string variantImage = string.Empty; 357 variantImages.TryGetValue(option.Id, out variantImage); 358 /*End Images*/ 359 360 /*stock state*/ 361 double variantStock = productVariant.Stock; 362 string svgInStock = "<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"16\" height=\"16\" fill=\"#44B11A\" class=\"bi bi-check-lg\" viewBox=\"0 0 16 16\"><path d=\"M12.736 3.97a.733.733 0 0 1 1.047 0c.286.289.29.756.01 1.05L7.88 12.01a.733.733 0 0 1-1.065.02L3.217 8.384a.757.757 0 0 1 0-1.06.733.733 0 0 1 1.047 0l3.052 3.093 5.4-6.425z\"/></svg>"; 363 string svgOutStock = "<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"25\" height=\"25\" fill=\"#CA0D0D\" class=\"bi bi-x-lg\" viewBox=\"0 0 16 16\"><path d=\"M4.646 4.646a.5.5 0 0 1 .708 0L8 7.293l2.646-2.647a.5.5 0 0 1 .708.708L8.707 8l2.647 2.646a.5.5 0 0 1-.708.708L8 8.707l-2.646 2.647a.5.5 0 0 1-.708-.708L7.293 8 4.646 5.354a.5.5 0 0 1 0-.708\"/></svg>"; 364 365 string infoStock = "<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"16\" height=\"16\" fill=\"currentColor\" class=\"bi bi-info-circle-fill\" viewBox=\"0 0 16 16\"><path d=\"M8 16A8 8 0 1 0 8 0a8 8 0 0 0 0 16m.93-9.412-1 4.705c-.07.34.029.533.304.533.194 0 .487-.07.686-.246l-.088.416c-.287.346-.92.598-1.465.598-.703 0-1.002-.422-.808-1.319l.738-3.468c.064-.293.006-.399-.287-.47l-.451-.081.082-.381 2.29-.287zM8 5.5a1 1 0 1 1 0-2 1 1 0 0 1 0 2\" /></svg>"; 366 string isNew = productVariant?.ProductFieldValues?.GetProductFieldValue("New")?.Value?.ToString().ToLower() ?? ""; 367 string isNewSvg = "<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"16\" height=\"16\" fill=\"#F2C400\" class=\"bi bi-star-fill\" viewBox=\"0 0 16 16\"><path d = \"M3.612 15.443c-.386.198-.824-.149-.746-.592l.83-4.73L.173 6.765c-.329-.314-.158-.888.283-.95l4.898-.696L7.538.792c.197-.39.73-.39.927 0l2.184 4.327 4.898.696c.441.062.612.636.282.95l-3.522 3.356.83 4.73c.078.443-.36.79-.746.592L8 13.187l-4.389 2.256z\" /></svg> "; 368 string stockState = ""; 369 370 string isSale = productVariant?.ProductFieldValues?.GetProductFieldValue("Sale")?.Value?.ToString().ToLower() ?? ""; 371 string isSaleSvg = "<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"16\" height=\"16\" fill=\"#F03232\" class=\"bi bi-star-fill\" viewBox=\"0 0 16 16\"><path d = \"M3.612 15.443c-.386.198-.824-.149-.746-.592l.83-4.73L.173 6.765c-.329-.314-.158-.888.283-.95l4.898-.696L7.538.792c.197-.39.73-.39.927 0l2.184 4.327 4.898.696c.441.062.612.636.282.95l-3.522 3.356.83 4.73c.078.443-.36.79-.746.592L8 13.187l-4.389 2.256z\" /></svg> "; 372 373 string expectedDeliveryDate = ""; 374 375 if (DateTime.Compare(productVariant.ExpectedDelivery, new DateTime(1900, 1, 1)) != 0) //In DW, if the Date is not set, it is defaulted 01-01-1900 and not null.. 376 { 377 expectedDeliveryDate = productVariant.ExpectedDelivery.ToShortDateString(); 378 } 379 380 string expectedDeliveryDateText = !String.IsNullOrWhiteSpace(expectedDeliveryDate) ? Translate("Verwacht:") + "&nbsp;" + expectedDeliveryDate : ""; 381 382 @if (!(bool?)productVariant.ProductFieldValues.Where(o => o.ProductField.SystemName == "ProductToBeDiscontinued").SingleOrDefault()?.Value ?? false) 383 { 384 if (variantStock > 0) 385 { 386 if (isNew == "true" || isSale == "true") 387 { 388 if (isSale == "true") 389 { 390 stockState += isSaleSvg + "&nbsp; &nbsp;" + Translate("Sale!") + "<br/>"; 391 } 392 393 if (isNew == "true") 394 { 395 stockState += isNewSvg + "&nbsp; &nbsp;" + Translate("New!") + "<br/>"; 396 } 397 398 stockState += "&nbsp;" + Translate("Nu leverbaar"); 399 } 400 else 401 { 402 stockState = svgInStock + "&nbsp; " + Translate("Op voorraad"); 403 404 } 405 } 406 else 407 { 408 stockState = svgOutStock + "&nbsp;" + Translate("Geen voorraad") + "<br/>" + expectedDeliveryDateText; 409 410 } 411 } 412 else 413 { 414 415 stockState = svgOutStock + "&nbsp;" + Translate("Discontinued:") + "<br/>" + variantStock + "&nbsp;" + @Translate("left in stock"); 416 417 } 418 /*End stock state*/ 419 /*Price variants*/ 420 double price = productVariant.DefaultPrice; 421 double cost = productVariant.Cost; 422 423 string priceFormated = Dynamicweb.Ecommerce.Services.Currencies.Format(Dynamicweb.Ecommerce.Services.Currencies.GetCurrency(currency), Convert.ToDouble(productPrice.ToList()[0].Amount, formatProvider)); 424 //string priceFormated = Dynamicweb.Ecommerce.Services.Currencies.Format(Dynamicweb.Ecommerce.Services.Currencies.GetCurrency(currency), Convert.ToDouble(price, formatProvider)); 425 426 427 428 /*End Price variants*/ 429 430 <img class="theme thumbnail" data-stockstate="@WebUtility.HtmlEncode(stockState)" src="/Admin/Public/GetImage.ashx?image=@(lastImageUrl)&width=64&format=webp" onclick="selectVariant('@(product.Id)','/Admin/Public/GetImage.ashx?image=@(variantImg)&format=webp','@variantLink','@product.Id','@option.Id','@option.Name',this.dataset.stockstate,'@isNew','@isSale','@priceFormated','@cost')" /> 431 432 433 } 434 } 435 436 } 437 </div> 438 <button class="thumb-nav next" onclick="scrollThumbs('@sliderId', 1)"> 439 <svg width="20px" height="20px" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" fill="#1D98A5"> 440 441 <g stroke="none" stroke-width="1" fill="none" fill-rule="evenodd"> 442 <g transform="translate(-384.000000, 0.000000)"> 443 <g id="right_line" transform="translate(384.000000, 0.000000)"> 444 <path d="M24,0 L24,24 L0,24 L0,0 L24,0 Z M12.5934901,23.257841 L12.5819402,23.2595131 L12.5108777,23.2950439 L12.4918791,23.2987469 L12.4918791,23.2987469 L12.4767152,23.2950439 L12.4056548,23.2595131 C12.3958229,23.2563662 12.3870493,23.2590235 12.3821421,23.2649074 L12.3780323,23.275831 L12.360941,23.7031097 L12.3658947,23.7234994 L12.3769048,23.7357139 L12.4804777,23.8096931 L12.4953491,23.8136134 L12.4953491,23.8136134 L12.5071152,23.8096931 L12.6106902,23.7357139 L12.6232938,23.7196733 L12.6232938,23.7196733 L12.6266527,23.7031097 L12.609561,23.275831 C12.6075724,23.2657013 12.6010112,23.2592993 12.5934901,23.257841 L12.5934901,23.257841 Z M12.8583906,23.1452862 L12.8445485,23.1473072 L12.6598443,23.2396597 L12.6498822,23.2499052 L12.6498822,23.2499052 L12.6471943,23.2611114 L12.6650943,23.6906389 L12.6699349,23.7034178 L12.6699349,23.7034178 L12.678386,23.7104931 L12.8793402,23.8032389 C12.8914285,23.8068999 12.9022333,23.8029875 12.9078286,23.7952264 L12.9118235,23.7811639 L12.8776777,23.1665331 C12.8752882,23.1545897 12.8674102,23.1470016 12.8583906,23.1452862 L12.8583906,23.1452862 Z M12.1430473,23.1473072 C12.1332178,23.1423925 12.1221763,23.1452606 12.1156365,23.1525954 L12.1099173,23.1665331 L12.0757714,23.7811639 C12.0751323,23.7926639 12.0828099,23.8018602 12.0926481,23.8045676 L12.108256,23.8032389 L12.3092106,23.7104931 L12.3186497,23.7024347 L12.3186497,23.7024347 L12.3225043,23.6906389 L12.340401,23.2611114 L12.337245,23.2485176 L12.337245,23.2485176 L12.3277531,23.2396597 L12.1430473,23.1473072 Z" id="MingCute" fill-rule="nonzero"> </path> 445 <path d="M15.7072,11.2929 C16.0977,11.6834 16.0977,12.3166 15.7072,12.7071 L10.0503,18.364 C9.65982,18.7545 9.02666,18.7545 8.63613,18.364 C8.24561,17.9734 8.24561,17.3403 8.63613,16.9497 L13.5859,12 L8.63613,7.05025 C8.24561,6.65973 8.24561,6.02656 8.63613,5.63604 C9.02666,5.24551 9.65982,5.24551 10.0503,5.63604 L15.7072,11.2929 Z" id="路径" fill="#1D98A5"> </path> 446 </g> 447 </g> 448 449 </svg> 450 451 </button> 452 </div> 453 } 454 455 456 </div> 457 458 } 459 if ((fieldValueBlocked != null && !fieldValueBlocked.ToString().Contains(customerNumber)) || String.IsNullOrWhiteSpace(customerNumber)) 460 { 461 <div class="stock-state pt-2 mt-auto"> 462 @{ 463 464 /*stock state*/ 465 double MainvariantStock = MainVariant.Stock; 466 string MainsvgInStock = "<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"16\" height=\"16\" fill=\"#44B11A\" class=\"bi bi-check-lg\" viewBox=\"0 0 16 16\"><path d=\"M12.736 3.97a.733.733 0 0 1 1.047 0c.286.289.29.756.01 1.05L7.88 12.01a.733.733 0 0 1-1.065.02L3.217 8.384a.757.757 0 0 1 0-1.06.733.733 0 0 1 1.047 0l3.052 3.093 5.4-6.425z\"/></svg>"; 467 string MainsvgOutStock = "<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"25\" height=\"25\" fill=\"#CA0D0D\" class=\"bi bi-x-lg\" viewBox=\"0 0 16 16\"><path d=\"M4.646 4.646a.5.5 0 0 1 .708 0L8 7.293l2.646-2.647a.5.5 0 0 1 .708.708L8.707 8l2.647 2.646a.5.5 0 0 1-.708.708L8 8.707l-2.646 2.647a.5.5 0 0 1-.708-.708L7.293 8 4.646 5.354a.5.5 0 0 1 0-.708\"/></svg>"; 468 469 string MaininfoStock = "<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"16\" height=\"16\" fill=\"currentColor\" class=\"bi bi-info-circle-fill\" viewBox=\"0 0 16 16\"><path d=\"M8 16A8 8 0 1 0 8 0a8 8 0 0 0 0 16m.93-9.412-1 4.705c-.07.34.029.533.304.533.194 0 .487-.07.686-.246l-.088.416c-.287.346-.92.598-1.465.598-.703 0-1.002-.422-.808-1.319l.738-3.468c.064-.293.006-.399-.287-.47l-.451-.081.082-.381 2.29-.287zM8 5.5a1 1 0 1 1 0-2 1 1 0 0 1 0 2\" /></svg>"; 470 string MainisNew = MainVariant?.ProductFieldValues?.GetProductFieldValue("New")?.Value?.ToString().ToLower() ?? ""; 471 string MainisNewSvg = "<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"16\" height=\"16\" fill=\"#F2C400\" class=\"bi bi-star-fill\" viewBox=\"0 0 16 16\"><path d = \"M3.612 15.443c-.386.198-.824-.149-.746-.592l.83-4.73L.173 6.765c-.329-.314-.158-.888.283-.95l4.898-.696L7.538.792c.197-.39.73-.39.927 0l2.184 4.327 4.898.696c.441.062.612.636.282.95l-3.522 3.356.83 4.73c.078.443-.36.79-.746.592L8 13.187l-4.389 2.256z\" /></svg> "; 472 string MainstockState = ""; 473 string MainIsSale = MainVariant?.ProductFieldValues?.GetProductFieldValue("Sale")?.Value?.ToString().ToLower() ?? ""; 474 string MainIsSaleSvg = "<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"16\" height=\"16\" fill=\"#F03232\" class=\"bi bi-star-fill\" viewBox=\"0 0 16 16\"><path d = \"M3.612 15.443c-.386.198-.824-.149-.746-.592l.83-4.73L.173 6.765c-.329-.314-.158-.888.283-.95l4.898-.696L7.538.792c.197-.39.73-.39.927 0l2.184 4.327 4.898.696c.441.062.612.636.282.95l-3.522 3.356.83 4.73c.078.443-.36.79-.746.592L8 13.187l-4.389 2.256z\" /></svg> "; 475 string MainexpectedDeliveryDate = ""; 476 477 if (DateTime.Compare(MainVariant.ExpectedDelivery, new DateTime(1900, 1, 1)) != 0) //In DW, if the Date is not set, it is defaulted 01-01-1900 and not null.. 478 { 479 MainexpectedDeliveryDate = MainVariant.ExpectedDelivery.ToShortDateString(); 480 } 481 482 string MainexpectedDeliveryDateText = !String.IsNullOrWhiteSpace(MainexpectedDeliveryDate) ? Translate("Verwacht:") + "&nbsp;" + MainexpectedDeliveryDate : ""; 483 484 @if (!(bool?)MainVariant.ProductFieldValues.Where(o => o.ProductField.SystemName == "ProductToBeDiscontinued").SingleOrDefault()?.Value ?? false) 485 { 486 if (MainvariantStock > 0) 487 { 488 if (MainisNew == "true" || MainIsSale == "true") 489 { 490 if (MainIsSale == "true") 491 { 492 MainstockState += MainIsSaleSvg + "&nbsp; &nbsp;" + Translate("Sale!") + "<br/>"; 493 } 494 495 if (MainisNew == "true") 496 { 497 MainstockState += MainisNewSvg + "&nbsp; &nbsp;" + Translate("New!") + "<br/>"; 498 } 499 500 MainstockState += "&nbsp;" + Translate("Nu leverbaar"); 501 } 502 else 503 { 504 MainstockState = MainsvgInStock + "&nbsp; " + Translate("Op voorraad"); 505 506 } 507 } 508 else 509 { 510 MainstockState = MainsvgOutStock + "&nbsp;" + Translate("Geen voorraad") + "<br/>" + MainexpectedDeliveryDateText; 511 512 } 513 } 514 else 515 { 516 517 MainstockState = MainsvgOutStock + "&nbsp;" + Translate("Discontinued:") + "<br/>" + MainvariantStock + "&nbsp;" + @Translate("left in stock"); 518 519 } 520 /*End stock state*/ 521 522 523 @MainstockState 524 525 526 } 527 </div> 528 } 529 else 530 { 531 <div class="stock-state pt-2 mt-auto"> 532 @MainOutStock @Translate("Discontinued") 533 </div> 534 } 535 <div class="custom-price mt-auto"> 536 @{ 537 538 539 540 541 bool isErpConnectionDown = !Dynamicweb.Core.Converter.ToBoolean(Dynamicweb.Context.Current.Items["IsWebServiceConnectionAvailable"]); 542 bool hidePrice = anonymousUsersLimitations.Contains("price") && anonymousUser || Pageview.AreaSettings.GetBoolean("ErpDownHidePrices") && isErpConnectionDown; 543 544 bool productIsDiscontinued = product is object && product.Discontinued; 545 bool doNotShowPriceIfProductIsDiscontinued = Model.Item.GetBoolean("DoNotShowPriceIfProductIsDiscontinued"); 546 var isDiscontinued = productIsDiscontinued && doNotShowPriceIfProductIsDiscontinued; 547 } 548 549 @if (product is object && !hidePrice && !isDiscontinued) 550 { 551 string unitId = !string.IsNullOrEmpty(Dynamicweb.Context.Current.Request.Form.Get("UnitId")) ? Dynamicweb.Context.Current.Request.Form.Get("UnitId") : string.Empty; 552 553 string priceFontSize = Model.Item.GetRawValueString("PriceSize", "fs-4"); 554 string horizontalAlign = Model.Item.GetRawValueString("HorizontalAlignment", ""); 555 string layout = Model.Item.GetRawValueString("Layout", "horizontal"); 556 string textAlign = horizontalAlign == "center" ? "text-center" : string.Empty; 557 textAlign = horizontalAlign == "end" ? "text-end" : textAlign; 558 559 horizontalAlign = horizontalAlign == "center" && layout == "horizontal" ? "justify-content-center" : horizontalAlign; 560 horizontalAlign = horizontalAlign == "end" && layout == "horizontal" ? "justify-content-end" : horizontalAlign; 561 horizontalAlign = horizontalAlign == "center" && layout == "vertical" ? "align-items-center" : horizontalAlign; 562 horizontalAlign = horizontalAlign == "end" && layout == "vertical" ? "align-items-end" : horizontalAlign; 563 564 string flexDirection = layout == "horizontal" ? string.Empty : "flex-column"; 565 string flexGap = layout == "horizontal" ? "gap-3" : string.Empty; 566 string order = layout == "horizontal" ? string.Empty : "order-2"; 567 568 569 string contentPadding = Model.Item.GetRawValueString("ContentPadding", ""); 570 contentPadding = contentPadding == "none" ? "p-0" : contentPadding; 571 contentPadding = contentPadding == "small" ? "p-1 px-md-2 py-md-1" : contentPadding; 572 contentPadding = contentPadding == "large" ? "p-2 px-md-3 py-md-2" : contentPadding; 573 string liveInfoClass = ""; 574 575 576 577 578 579 580 if (isLazyLoadingForProductInfoEnabled) 581 { 582 if (Dynamicweb.Context.Current.Items.Contains("ProductInfoFeed")) 583 { 584 productInfoFeed = Dynamicweb.Context.Current.Items["ProductInfoFeed"]?.ToString(); 585 if (!string.IsNullOrEmpty(productInfoFeed)) 586 { 587 productInfoFeed = $"data-product-info-feed=\"{productInfoFeed}\""; 588 } 589 } 590 liveInfoClass = "js-live-info"; 591 } 592 593 <div class="@textAlign @liveInfoClass item_@Model.Item.SystemName.ToLower()" data-product-id="@product.Id" data-variant-id="@product.VariantId" @productInfoFeed> 594 @if (showInformativePrice && product.PriceInformative.Price != 0) 595 { 596 <div class="opacity-50"> 597 <span>@Translate("RRP") </span> 598 <span class="text-decoration-line-through text-price">@product.PriceInformative.PriceFormatted</span> 599 </div> 600 } 601 <div class="@priceFontSize m-0 d-flex flex-wrap @flexDirection @flexGap @horizontalAlign" style="row-gap: 0 !important" itemprop="offers" itemscope itemtype="https://schema.org/Offer"> 602 <span itemprop="priceCurrency" content="@product.Price.CurrencyCode" class="d-none"></span> 603 604 605 @if (showPricesWithVat == "false" && !neverShowVat) 606 { 607 if (isLazyLoadingForProductInfoEnabled && !Pageview.IsVisualEditorMode) 608 { 609 <span itemprop="price" content="" class="d-none"></span> 610 <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> 611 } 612 else 613 { 614 string beforePrice = !string.IsNullOrEmpty(unitId) ? product.GetPrice(unitId).PriceBeforeDiscount.PriceWithoutVatFormatted : product.PriceBeforeDiscount.PriceWithoutVatFormatted; 615 616 <span itemprop="price" content="@product.Price.PriceWithoutVat.ToString("0.00", System.Globalization.CultureInfo.InvariantCulture)" class="d-none"></span> 617 if (product.Price.Price != product.PriceBeforeDiscount.Price) 618 { 619 <span class="text-decoration-line-through opacity-75 @order">@beforePrice</span> 620 } 621 } 622 } 623 else 624 { 625 if (isLazyLoadingForProductInfoEnabled && !Pageview.IsVisualEditorMode) 626 { 627 <span itemprop="price" content="" class="d-none"></span> 628 <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> 629 } 630 else 631 { 632 string beforePrice = !string.IsNullOrEmpty(unitId) ? product.GetPrice(unitId).PriceBeforeDiscount.PriceFormatted : product.PriceBeforeDiscount.PriceFormatted; 633 634 <span itemprop="price" content="@product.Price.Price.ToString("0.00", System.Globalization.CultureInfo.InvariantCulture)" class="d-none"></span> 635 636 if (product.Price.Price != product.PriceBeforeDiscount.Price) 637 { 638 <span class="text-decoration-line-through opacity-75 @order"> 639 <span class="text-price">@beforePrice</span> 640 </span> 641 } 642 } 643 } 644 645 @if (showPricesWithVat == "false" && !neverShowVat) 646 { 647 if (isLazyLoadingForProductInfoEnabled && !Pageview.IsVisualEditorMode) 648 { 649 <span class="text-price js-text-price"> 650 <span class="spinner-border" role="status"></span> 651 </span> 652 } 653 else 654 { 655 string price = !string.IsNullOrEmpty(unitId) ? product.GetPrice(unitId).Price.PriceWithoutVatFormatted : product.Price.PriceWithoutVatFormatted; 656 657 if (product?.VariantInfo?.VariantInfo != null) 658 { 659 priceMin = product?.VariantInfo?.PriceMin?.PriceWithoutVatFormatted != null ? product.VariantInfo.PriceMin.PriceWithoutVatFormatted : ""; 660 priceMax = product?.VariantInfo?.PriceMax?.PriceWithoutVatFormatted != null ? product.VariantInfo.PriceMax.PriceWithoutVatFormatted : ""; 661 } 662 if (priceMin != priceMax) 663 { 664 price = priceMin + " - " + priceMax; 665 } 666 <span class="@theme @contentPadding"> 667 <span class="text-price">@price</span> 668 </span> 669 } 670 } 671 else 672 { 673 if (isLazyLoadingForProductInfoEnabled && !Pageview.IsVisualEditorMode) 674 { 675 <span class="text-price js-text-price"> 676 <span class="spinner-border" role="status"></span> 677 </span> 678 } 679 else 680 { 681 string price = !string.IsNullOrEmpty(unitId) ? product.GetPrice(unitId).Price.PriceFormatted : product.Price.PriceFormatted; 682 683 if (product?.VariantInfo?.VariantInfo != null) 684 { 685 priceMin = product?.VariantInfo?.PriceMin?.PriceFormatted != null ? product.VariantInfo.PriceMin.PriceFormatted : ""; 686 priceMax = product?.VariantInfo?.PriceMax?.PriceFormatted != null ? product.VariantInfo.PriceMax.PriceFormatted : ""; 687 } 688 if (priceMin != priceMax) 689 { 690 price = priceMin + " - " + priceMax; 691 } 692 <span class="@theme @contentPadding"> 693 <span class="text-price">@price</span> 694 </span> 695 } 696 } 697 698 @* Stock state for Schema.org, start *@ 699 @{ 700 Uri url = Dynamicweb.Context.Current.Request.Url; 701 } 702 703 <link itemprop="url" href="@url"> 704 705 @{ 706 bool IsNeverOutOfStock = product.NeverOutOfstock; 707 } 708 709 @if (IsNeverOutOfStock) 710 { 711 <span itemprop="availability" class="d-none">@Translate("Available in stock")</span> 712 } 713 else 714 { 715 if (product.StockLevel > 0) 716 { 717 <span itemprop="availability" class="d-none">InStock</span> 718 } 719 else 720 { 721 <span itemprop="availability" class="d-none">OutOfStock</span> 722 } 723 } 724 @* Stock state for Schema.org, stop *@ 725 726 </div> 727 728 @if (showPricesWithVat == "false" && !neverShowVat) 729 { 730 if (isLazyLoadingForProductInfoEnabled && !Pageview.IsVisualEditorMode) 731 { 732 <small class="opacity-85 fst-normal js-text-price-with-vat d-none" data-suffix="@Translate("Incl. VAT")"></small> 733 } 734 else 735 { 736 string price = !string.IsNullOrEmpty(unitId) ? product.GetPrice(unitId).Price.PriceWithVatFormatted : product.Price.PriceWithVatFormatted; 737 738 if (product?.VariantInfo?.VariantInfo != null) 739 { 740 priceMin = product?.VariantInfo?.PriceMin?.PriceWithVatFormatted != null ? product.VariantInfo.PriceMin.PriceWithVatFormatted : ""; 741 priceMax = product?.VariantInfo?.PriceMax?.PriceWithVatFormatted != null ? product.VariantInfo.PriceMax.PriceWithVatFormatted : ""; 742 } 743 if (priceMin != priceMax) 744 { 745 price = priceMin + " - " + priceMax; 746 } 747 <!-- <small class="opacity-85 fst-normal">@price @Translate("Incl. VAT")</small> --> 748 } 749 } 750 </div> 751 } 752 else if (Pageview.IsVisualEditorMode) 753 { 754 <div class="alert alert-dark m-0" role="alert"> 755 <span>@Translate("No products available")</span> 756 </div> 757 } 758 759 </div> 760 } 761 } 762
Tischlampe 2L ring
Error executing template "Designs/Swift/Paragraph/CustomProductSlider.cshtml"
System.NullReferenceException: Object reference not set to an instance of an object.
   at CompiledRazorTemplates.Dynamic.RazorEngine_3562354021b44d5c892fe73dc2806e4f.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 Dynamicweb.Ecommerce.ProductCatalog 3 @using Dynamicweb.Ecommerce.CustomerExperienceCenter.Favorites 4 @using Dynamicweb.Files 5 @using System.IO 6 @using System.Net 7 @using Dynamicweb.Security.UserManagement 8 9 10 @{ 11 ProductViewModel product = null; 12 if (Dynamicweb.Context.Current.Items.Contains("ProductDetails")) 13 { 14 product = (ProductViewModel)Dynamicweb.Context.Current.Items["ProductDetails"]; 15 } 16 else if (Pageview.Page.Item["DummyProduct"] != null && Pageview.IsVisualEditorMode) 17 { 18 var pageViewModel = Dynamicweb.Frontend.ContentViewModelFactory.CreatePageInfoViewModel(Pageview.Page); 19 ProductListViewModel productList = pageViewModel.Item.GetValue("DummyProduct") != null ? pageViewModel.Item.GetValue("DummyProduct") as ProductListViewModel : new ProductListViewModel(); 20 21 if (productList?.Products is object) 22 { 23 product = productList.Products[0]; 24 } 25 } 26 } 27 28 @{ 29 var currentUser = Pageview?.User; 30 var customerNumber = !string.IsNullOrEmpty(currentUser?.CustomerNumber) 31 ? currentUser.CustomerNumber 32 : ""; 33 } 34 @if (product is object) 35 { 36 string imagePath = product?.DefaultImage?.Value ?? ""; 37 string imagePathUrlEncoded = Dynamicweb.Context.Current.Server.UrlEncode(imagePath); 38 39 string ratio = Model.Item.GetRawValueString("ImageAspectRatio", ""); 40 ratio = ratio != "0" ? ratio : ""; 41 string ratioCssClass = ratio != "" ? " ratio" : ""; 42 string ratioVariable = ratio != "" ? "--bs-aspect-ratio: " + ratio + ";" : ""; 43 44 string width = Model.Item.GetRawValueString("Width", "auto"); 45 int smallImageSize = 640; 46 int largeImageSize = width == "auto" ? 1280 : Convert.ToInt32(width); 47 48 string ImageObjectFit = Model.Item.GetRawValueString("ImageObjectFit", "contain"); 49 50 string imagePathXs = "/Admin/Public/GetImage.ashx?width=" + smallImageSize + "&image=" + imagePathUrlEncoded + "&format=webp"; 51 string imagePathS = "/Admin/Public/GetImage.ashx?width=" + largeImageSize + "&image=" + imagePathUrlEncoded + "&format=webp"; 52 string imagePathFallBack = "/Admin/Public/GetImage.ashx?width=" + largeImageSize + "&image=" + imagePathUrlEncoded + "&format=webp"; 53 54 var badgeParms = new Dictionary<string, object>(); 55 badgeParms.Add("size", "h7"); 56 badgeParms.Add("saleBadgeType", Model.Item.GetRawValue("SaleBadgeType")); 57 badgeParms.Add("saleBadgeCssClassName", Model.Item.GetRawValue("SaleBadgeDesign")); 58 badgeParms.Add("newBadgeCssClassName", Model.Item.GetRawValue("NewBadgeDesign")); 59 badgeParms.Add("newPublicationDays", Model.Item.GetInt32("NewPublicationDays")); 60 badgeParms.Add("campaignBadgesValues", Model.Item.GetList("CampaignBadges")?.GetRawValue().OfType<string>().ToList()); 61 62 string badgeSize = Model.Item.GetRawValueString("BadgeSize", "fs-2"); 63 bool saleBadgeEnabled = !string.IsNullOrWhiteSpace(Model.Item.GetRawValueString("SaleBadgeDesign")) && Model.Item.GetRawValueString("SaleBadgeDesign") != "none" ? true : false; 64 bool newBadgeEnabled = !string.IsNullOrWhiteSpace(Model.Item.GetRawValueString("NewBadgeDesign")) && Model.Item.GetRawValueString("NewBadgeDesign") != "none" ? true : false; 65 66 /*Custom badge*/ 67 var productService = new Dynamicweb.Ecommerce.Products.ProductService(); 68 var currency = Dynamicweb.Ecommerce.Common.Context.Currency.Code; 69 var formatProvider = new System.Globalization.NumberFormatInfo(); 70 formatProvider.NumberDecimalSeparator = "."; 71 formatProvider.NumberGroupSeparator = ","; 72 var MainVariant = productService.GetProductById(product.Id, product.VariantId, false); 73 var fieldValueBlocked = MainVariant?.ProductFieldValues?.GetProductFieldValue("BlockedCustomerList")?.Value; 74 75 76 string isNewProduct = MainVariant?.ProductFieldValues?.GetProductFieldValue("New")?.Value?.ToString().ToLower() ?? ""; 77 string MainisSale = MainVariant?.ProductFieldValues?.GetProductFieldValue("Sale")?.Value?.ToString().ToLower() ?? ""; 78 bool showNewBadge = isNewProduct == "true" ? true : false; 79 bool showSaleBadge = MainisSale == "true" ? true : false; 80 string showNewSaleBadge = "d-none"; 81 if (showSaleBadge) 82 { 83 badgeParms.Add("isSale", "true"); 84 85 } 86 else 87 { 88 badgeParms.Add("isSale", "false"); 89 } 90 if (showNewBadge) 91 { 92 badgeParms.Add("isNew", "true"); 93 } 94 else 95 { 96 badgeParms.Add("isNew", "false"); 97 } 98 /*End Custom badge*/ 99 if (showSaleBadge || showNewBadge) 100 { 101 showNewSaleBadge = ""; 102 } 103 DateTime createdDate = product.Created.Value; 104 bool showBadges = saleBadgeEnabled && product.Discount.Price != 0 ? true : false; 105 106 bool showFavoritesSelector = !string.IsNullOrEmpty(Model.Item.GetString("ShowAddToFavorites")) ? Model.Item.GetBoolean("ShowAddToFavorites") : false; 107 string anonymousUsersLimitations = Pageview.AreaSettings.GetRawValueString("AnonymousUsers", ""); 108 bool anonymousUser = Pageview.User == null; 109 110 var favoriteParameters = new Dictionary<string, object>(); 111 if (!anonymousUser && showFavoritesSelector) 112 { 113 int defaultFavoriteListId = 0; 114 115 IEnumerable<FavoriteList> favoreiteLists = Pageview.User.GetFavoriteLists(); 116 if (favoreiteLists.Count() == 1) 117 { 118 foreach (FavoriteList list in favoreiteLists) 119 { 120 defaultFavoriteListId = list.ListId; 121 } 122 } 123 124 favoriteParameters.Add("ListId", defaultFavoriteListId); 125 } 126 127 MediaViewModel alternativeImage = new MediaViewModel(); 128 if (Model.Item.GetBoolean("ShowAlternativeImageOnHover")) 129 { 130 var selectedImageCategories = Model.Item.GetList("GetAlternativeImageFrom")?.GetRawValue().OfType<string>().ToList(); 131 List<MediaViewModel> allAssetsImages = product.AssetCategories.Where(x => selectedImageCategories.Contains(x.SystemName)).SelectMany(x => x.Assets).ToList(); 132 allAssetsImages.RemoveAll(x => x.Value == product.DefaultImage.Value); 133 alternativeImage = allAssetsImages.FirstOrDefault(); 134 } 135 136 string altImagePathXs = string.Empty; 137 string altImagePathS = string.Empty; 138 139 if (!string.IsNullOrEmpty(alternativeImage?.Value)) 140 { 141 altImagePathXs = "/Admin/Public/GetImage.ashx?width=" + smallImageSize + "&image=" + Dynamicweb.Context.Current.Server.UrlEncode(alternativeImage.Value) + "&format=webp"; 142 altImagePathS = "/Admin/Public/GetImage.ashx?width=" + largeImageSize + "&image=" + Dynamicweb.Context.Current.Server.UrlEncode(alternativeImage.Value) + "&format=webp"; 143 } 144 145 @* Theme settings *@ 146 string theme = !string.IsNullOrWhiteSpace(Model.Item.GetRawValueString("Theme")) ? " theme " + Model.Item.GetRawValueString("Theme").Replace(" ", "").Trim().ToLower() : ""; 147 string themeBorder = !string.IsNullOrWhiteSpace(theme) ? "border: 1px solid rgba(0,0,0,0)" : ""; 148 string themePadding = !string.IsNullOrWhiteSpace(theme) ? "p-2 p-lg-3" : ""; 149 150 string imageId = "ProductImage_" + product.Id; 151 152 153 154 string fullWidth = width == "auto" ? "w-100" : ""; 155 string customWidth = width != "auto" ? "style=\"width: " + width + "px\"" : "style=\"min-width: 60px\""; 156 157 string altImageZindex = Model.Item.GetBoolean("ShowAlternativeImageOnHover") && !string.IsNullOrEmpty(alternativeImage?.Value) ? " z-index: 1" : string.Empty; 158 string groupid = !string.IsNullOrEmpty(Dynamicweb.Context.Current.Request.QueryString.Get("GroupID")) ? Dynamicweb.Context.Current.Request.QueryString.Get("GroupID"):"" ; 159 string link = product.GetProductLink(GetPageIdByNavigationTag("Shop"), false); 160 var productVariantGroups = product.VariantGroups(); 161 string MainOutStock = "<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"25\" height=\"25\" fill=\"#CA0D0D\" class=\"bi bi-x-lg\" viewBox=\"0 0 16 16\"><path d=\"M4.646 4.646a.5.5 0 0 1 .708 0L8 7.293l2.646-2.647a.5.5 0 0 1 .708.708L8.707 8l2.647 2.646a.5.5 0 0 1-.708.708L8 8.707l-2.646 2.647a.5.5 0 0 1-.708-.708L7.293 8 4.646 5.354a.5.5 0 0 1 0-.708\"/></svg>"; 162 163 @if (!string.IsNullOrEmpty(imagePath)) 164 { 165 <div class="@fullWidth @theme position-relative item_@Model.Item.SystemName.ToLower() main-image-container" @customWidth> 166 <div class="" style="@(ratioVariable)@(altImageZindex)"> 167 <div class="d-flex justify-content-center align-items-center"> 168 <a class="main-link-link" href="@link"> 169 @if (imagePath.StartsWith("/Files/", StringComparison.OrdinalIgnoreCase)) 170 { 171 <img id="@imageId" 172 srcset=" 173 @imagePathXs @(smallImageSize)w, 174 @imagePathS @(largeImageSize)w" 175 sizes="(max-width: 992px) 50vw, 25vw" 176 src="@imagePathFallBack" 177 loading="lazy" 178 decoding="async" 179 class="h-100 w-100 @themePadding main-image" 180 style="object-fit: @ImageObjectFit; @themeBorder " 181 alt="@product.Name" 182 itemprop="image"> 183 } 184 else 185 { 186 <img src="@product.DefaultImage.Value" 187 loading="lazy" 188 class="h-100 w-100 @themePadding main-image" 189 style="object-fit: contain; @themeBorder" 190 alt="@product.Name" 191 itemprop="image"> 192 } 193 </a> 194 </div> 195 </div> 196 197 <div class="position-absolute top-0 left-0 p-2 pb-0 custom-badge-product-list @showNewSaleBadge"> 198 @{ 199 @RenderPartial("Components/Custom_EcommerceBadge.cshtml", product, badgeParms) 200 } 201 </div> 202 203 204 </div> 205 } 206 207 <div class="product-info h-100"> 208 <div class="fs-7 pt-1 opacity-85 start item_@Model.Item.SystemName.ToLower() product-number" itemprop="sku">@product.Id / @product.VariantId - @product.VariantName</div> 209 <div class="py-2" data-col-size="12"> 210 <h2 class="h6 start m-0 item_swift_productheader product-name" itemprop="name"><b>@product.Name</b></h2> 211 </div> 212 </div> 213 var sliderId = $"thumb-scroll-{product.Id}"; 214 if (productVariantGroups.Any() && product?.VariantInfo?.VariantInfo != null) 215 216 { 217 @using Dynamicweb.Ecommerce.Prices 218 @{ 219 string[] variantId = product.VariantId.Split('.'); 220 string showPricesWithVat = Pageview.Area.EcomPricesWithVat.ToLower(); 221 bool neverShowVat = string.IsNullOrEmpty(showPricesWithVat); 222 bool showInformativePrice = Model.Item.GetBoolean("ShowInformativePrice"); 223 string productInfoFeed = ""; 224 bool isLazyLoadingForProductInfoEnabled = Dynamicweb.Core.Converter.ToBoolean(Dynamicweb.Context.Current.Items["IsLazyLoadingForProductInfoEnabled"]); 225 if (isLazyLoadingForProductInfoEnabled) 226 { 227 if (Dynamicweb.Context.Current.Items.Contains("ProductInfoFeed")) 228 { 229 productInfoFeed = Dynamicweb.Context.Current.Items["ProductInfoFeed"]?.ToString(); 230 if (!string.IsNullOrEmpty(productInfoFeed)) 231 { 232 productInfoFeed =productInfoFeed; 233 } 234 } 235 236 } 237 string priceMin = ""; 238 string priceMax = ""; 239 int groupNumber = 1; 240 241 242 243 244 string baseUrl = $"Default.aspx?ID={GetPageIdByNavigationTag("Shop")}&GroupID={product.PrimaryOrDefaultGroup.Id}&ProductID={product.Id}"; 245 if (!string.IsNullOrEmpty(baseUrl)) 246 { 247 baseUrl = $"/{baseUrl.TrimStart('/')}"; 248 } 249 string variantUrl = string.Empty; 250 251 252 Dictionary<string, string> 253 variantImages = new Dictionary<string, string> 254 (); 255 <div class="last-row mt-auto"> 256 257 @foreach (var variantGroup in productVariantGroups) 258 { 259 <div class="thumbnail-wrapper"> 260 <button class="thumb-nav prev" onclick="scrollThumbs('@sliderId', -1)"> 261 <svg width="20px" height="20px" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" fill="#1D98A5"> 262 263 <g stroke="none" stroke-width="1" fill="none" fill-rule="evenodd"> 264 <g transform="translate(-336.000000, 0.000000)"> 265 <g id="left_line" transform="translate(336.000000, 0.000000)"> 266 <path d="M24,0 L24,24 L0,24 L0,0 L24,0 Z M12.5934901,23.257841 L12.5819402,23.2595131 L12.5108777,23.2950439 L12.4918791,23.2987469 L12.4918791,23.2987469 L12.4767152,23.2950439 L12.4056548,23.2595131 C12.3958229,23.2563662 12.3870493,23.2590235 12.3821421,23.2649074 L12.3780323,23.275831 L12.360941,23.7031097 L12.3658947,23.7234994 L12.3769048,23.7357139 L12.4804777,23.8096931 L12.4953491,23.8136134 L12.4953491,23.8136134 L12.5071152,23.8096931 L12.6106902,23.7357139 L12.6232938,23.7196733 L12.6232938,23.7196733 L12.6266527,23.7031097 L12.609561,23.275831 C12.6075724,23.2657013 12.6010112,23.2592993 12.5934901,23.257841 L12.5934901,23.257841 Z M12.8583906,23.1452862 L12.8445485,23.1473072 L12.6598443,23.2396597 L12.6498822,23.2499052 L12.6498822,23.2499052 L12.6471943,23.2611114 L12.6650943,23.6906389 L12.6699349,23.7034178 L12.6699349,23.7034178 L12.678386,23.7104931 L12.8793402,23.8032389 C12.8914285,23.8068999 12.9022333,23.8029875 12.9078286,23.7952264 L12.9118235,23.7811639 L12.8776777,23.1665331 C12.8752882,23.1545897 12.8674102,23.1470016 12.8583906,23.1452862 L12.8583906,23.1452862 Z M12.1430473,23.1473072 C12.1332178,23.1423925 12.1221763,23.1452606 12.1156365,23.1525954 L12.1099173,23.1665331 L12.0757714,23.7811639 C12.0751323,23.7926639 12.0828099,23.8018602 12.0926481,23.8045676 L12.108256,23.8032389 L12.3092106,23.7104931 L12.3186497,23.7024347 L12.3186497,23.7024347 L12.3225043,23.6906389 L12.340401,23.2611114 L12.337245,23.2485176 L12.337245,23.2485176 L12.3277531,23.2396597 L12.1430473,23.1473072 Z" id="MingCute" fill-rule="nonzero"> </path> 267 <path d="M8.29292,12.7071 C7.9024,12.3166 7.9024,11.6834 8.29292,11.2929 L13.9498,5.63604 C14.3403,5.24551 14.9735,5.24551 15.364,5.63604 C15.7545,6.02656 15.7545,6.65973 15.364,7.05025 L10.4142,12 L15.364,16.9497 C15.7545,17.3403 15.7545,17.9734 15.364,18.364 C14.9735,18.7545 14.3403,18.7545 13.9498,18.364 L8.29292,12.7071 Z" id="路径" fill="#1D98A5"> </path> 268 </g> 269 </g> 270 </g> 271 </svg> 272 273 </button> 274 <div class="thumbnail-scroll" id="@sliderId"> 275 @{ 276 VariantGroupViewModel group = variantGroup; 277 foreach (var option in group.Options.OrderBy(o => o.Id)) 278 { 279 var productVariant = productService.GetProductById(product.Id, option.Id, false); 280 281 var productSelection = new PriceProductSelection(productVariant, null, 0); 282 283 var currencyCode = string.IsNullOrWhiteSpace(Pageview.User.Currency) ? Pageview.Area.EcomCurrencyId : Pageview.User.Currency; 284 var countryCode = string.IsNullOrWhiteSpace(Pageview.User.CountryCode) ? Pageview.Area.EcomCountryCode : Pageview.User.CountryCode; 285 286 var userCurrency = Dynamicweb.Ecommerce.Services.Currencies.GetCurrency(currencyCode); 287 var userCountry = Dynamicweb.Ecommerce.Services.Countries.GetCountry(countryCode); 288 289 var priceContext = new PriceContext(userCurrency, userCountry, null, Pageview.User, false, null); 290 var productPrice = Dynamicweb.Ecommerce.Services.Prices.FindPrices(priceContext, productSelection, false); 291 292 //throw new Exception(System.Text.Json.JsonSerializer.Serialize(productPrice)); 293 294 var fieldValue = productVariant?.ProductFieldValues?.GetProductFieldValue("BlockedCustomerList")?.Value; 295 296 if ((fieldValue != null && !fieldValue.ToString().Contains(customerNumber)) || String.IsNullOrWhiteSpace(customerNumber)) 297 { 298 299 300 string active = variantId != null && variantId.Contains(option.Id) ? "active" : string.Empty; 301 string buttonId = $"{product.Id}_{option.Id}_{Pageview.CurrentParagraph.ID}"; 302 string contrastColor = string.Empty; 303 304 string searchKey = $"{product.Id}_{option.Id}_"; 305 /*Images*/ 306 var imagePathVariant = option.Image?.Value ?? ""; 307 308 309 var folderPath = Path.GetDirectoryName(imagePathVariant); 310 311 string physicalFolderPath = Dynamicweb.Context.Current.Server.MapPath(folderPath); 312 313 string lastImage = null; 314 315 if (Directory.Exists(physicalFolderPath)) 316 { 317 318 var fileWith15 = Directory.GetFiles(physicalFolderPath) 319 .FirstOrDefault(f => Path.GetFileName(f).Contains($"{product.Id}_{option.Id}_9")); 320 321 if (fileWith15 != null) 322 { 323 lastImage = fileWith15; 324 } 325 else 326 { 327 var files = Directory.GetFiles(physicalFolderPath) 328 .Where(f => Path.GetFileName(f).StartsWith($"{product.Id}_{option.Id}_")) 329 .OrderByDescending(f => 330 { 331 var filename = Path.GetFileNameWithoutExtension(f); 332 var match = System.Text.RegularExpressions.Regex.Match(filename, @"_(\d+)$"); 333 if (match.Success && int.TryParse(match.Groups[1].Value, out int index)) 334 { 335 return index; 336 } 337 return 0; 338 }) 339 .ToList(); 340 341 if (files.Any()) 342 { 343 lastImage = files.First(); 344 } 345 } 346 } 347 348 var lastImageUrl = lastImage != null ? lastImage : "/Files/Images/zijlstra/Afbeeldingen_overig/Coming_Soon.jpg"; 349 int index = lastImageUrl.IndexOf("Files"); 350 string relativePath = index >= 0 ? lastImageUrl.Substring(index).Replace("\\", "/") : lastImageUrl.Replace("\\", "/"); 351 lastImageUrl = "/" + relativePath; 352 lastImageUrl = Dynamicweb.Context.Current.Server.UrlEncode(lastImageUrl); 353 var variantImg = option.Image is object ? Dynamicweb.Context.Current.Server.UrlEncode(option.Image.Value) : null; 354 var variantLink = "/Default.aspx?ID=" + GetPageIdByNavigationTag("Shop") + "&GroupID=" + product.PrimaryOrDefaultGroup.Id + "&ProductID=" + product.Id + "&VariantID=" + option.Id; 355 356 string variantImage = string.Empty; 357 variantImages.TryGetValue(option.Id, out variantImage); 358 /*End Images*/ 359 360 /*stock state*/ 361 double variantStock = productVariant.Stock; 362 string svgInStock = "<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"16\" height=\"16\" fill=\"#44B11A\" class=\"bi bi-check-lg\" viewBox=\"0 0 16 16\"><path d=\"M12.736 3.97a.733.733 0 0 1 1.047 0c.286.289.29.756.01 1.05L7.88 12.01a.733.733 0 0 1-1.065.02L3.217 8.384a.757.757 0 0 1 0-1.06.733.733 0 0 1 1.047 0l3.052 3.093 5.4-6.425z\"/></svg>"; 363 string svgOutStock = "<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"25\" height=\"25\" fill=\"#CA0D0D\" class=\"bi bi-x-lg\" viewBox=\"0 0 16 16\"><path d=\"M4.646 4.646a.5.5 0 0 1 .708 0L8 7.293l2.646-2.647a.5.5 0 0 1 .708.708L8.707 8l2.647 2.646a.5.5 0 0 1-.708.708L8 8.707l-2.646 2.647a.5.5 0 0 1-.708-.708L7.293 8 4.646 5.354a.5.5 0 0 1 0-.708\"/></svg>"; 364 365 string infoStock = "<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"16\" height=\"16\" fill=\"currentColor\" class=\"bi bi-info-circle-fill\" viewBox=\"0 0 16 16\"><path d=\"M8 16A8 8 0 1 0 8 0a8 8 0 0 0 0 16m.93-9.412-1 4.705c-.07.34.029.533.304.533.194 0 .487-.07.686-.246l-.088.416c-.287.346-.92.598-1.465.598-.703 0-1.002-.422-.808-1.319l.738-3.468c.064-.293.006-.399-.287-.47l-.451-.081.082-.381 2.29-.287zM8 5.5a1 1 0 1 1 0-2 1 1 0 0 1 0 2\" /></svg>"; 366 string isNew = productVariant?.ProductFieldValues?.GetProductFieldValue("New")?.Value?.ToString().ToLower() ?? ""; 367 string isNewSvg = "<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"16\" height=\"16\" fill=\"#F2C400\" class=\"bi bi-star-fill\" viewBox=\"0 0 16 16\"><path d = \"M3.612 15.443c-.386.198-.824-.149-.746-.592l.83-4.73L.173 6.765c-.329-.314-.158-.888.283-.95l4.898-.696L7.538.792c.197-.39.73-.39.927 0l2.184 4.327 4.898.696c.441.062.612.636.282.95l-3.522 3.356.83 4.73c.078.443-.36.79-.746.592L8 13.187l-4.389 2.256z\" /></svg> "; 368 string stockState = ""; 369 370 string isSale = productVariant?.ProductFieldValues?.GetProductFieldValue("Sale")?.Value?.ToString().ToLower() ?? ""; 371 string isSaleSvg = "<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"16\" height=\"16\" fill=\"#F03232\" class=\"bi bi-star-fill\" viewBox=\"0 0 16 16\"><path d = \"M3.612 15.443c-.386.198-.824-.149-.746-.592l.83-4.73L.173 6.765c-.329-.314-.158-.888.283-.95l4.898-.696L7.538.792c.197-.39.73-.39.927 0l2.184 4.327 4.898.696c.441.062.612.636.282.95l-3.522 3.356.83 4.73c.078.443-.36.79-.746.592L8 13.187l-4.389 2.256z\" /></svg> "; 372 373 string expectedDeliveryDate = ""; 374 375 if (DateTime.Compare(productVariant.ExpectedDelivery, new DateTime(1900, 1, 1)) != 0) //In DW, if the Date is not set, it is defaulted 01-01-1900 and not null.. 376 { 377 expectedDeliveryDate = productVariant.ExpectedDelivery.ToShortDateString(); 378 } 379 380 string expectedDeliveryDateText = !String.IsNullOrWhiteSpace(expectedDeliveryDate) ? Translate("Verwacht:") + "&nbsp;" + expectedDeliveryDate : ""; 381 382 @if (!(bool?)productVariant.ProductFieldValues.Where(o => o.ProductField.SystemName == "ProductToBeDiscontinued").SingleOrDefault()?.Value ?? false) 383 { 384 if (variantStock > 0) 385 { 386 if (isNew == "true" || isSale == "true") 387 { 388 if (isSale == "true") 389 { 390 stockState += isSaleSvg + "&nbsp; &nbsp;" + Translate("Sale!") + "<br/>"; 391 } 392 393 if (isNew == "true") 394 { 395 stockState += isNewSvg + "&nbsp; &nbsp;" + Translate("New!") + "<br/>"; 396 } 397 398 stockState += "&nbsp;" + Translate("Nu leverbaar"); 399 } 400 else 401 { 402 stockState = svgInStock + "&nbsp; " + Translate("Op voorraad"); 403 404 } 405 } 406 else 407 { 408 stockState = svgOutStock + "&nbsp;" + Translate("Geen voorraad") + "<br/>" + expectedDeliveryDateText; 409 410 } 411 } 412 else 413 { 414 415 stockState = svgOutStock + "&nbsp;" + Translate("Discontinued:") + "<br/>" + variantStock + "&nbsp;" + @Translate("left in stock"); 416 417 } 418 /*End stock state*/ 419 /*Price variants*/ 420 double price = productVariant.DefaultPrice; 421 double cost = productVariant.Cost; 422 423 string priceFormated = Dynamicweb.Ecommerce.Services.Currencies.Format(Dynamicweb.Ecommerce.Services.Currencies.GetCurrency(currency), Convert.ToDouble(productPrice.ToList()[0].Amount, formatProvider)); 424 //string priceFormated = Dynamicweb.Ecommerce.Services.Currencies.Format(Dynamicweb.Ecommerce.Services.Currencies.GetCurrency(currency), Convert.ToDouble(price, formatProvider)); 425 426 427 428 /*End Price variants*/ 429 430 <img class="theme thumbnail" data-stockstate="@WebUtility.HtmlEncode(stockState)" src="/Admin/Public/GetImage.ashx?image=@(lastImageUrl)&width=64&format=webp" onclick="selectVariant('@(product.Id)','/Admin/Public/GetImage.ashx?image=@(variantImg)&format=webp','@variantLink','@product.Id','@option.Id','@option.Name',this.dataset.stockstate,'@isNew','@isSale','@priceFormated','@cost')" /> 431 432 433 } 434 } 435 436 } 437 </div> 438 <button class="thumb-nav next" onclick="scrollThumbs('@sliderId', 1)"> 439 <svg width="20px" height="20px" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" fill="#1D98A5"> 440 441 <g stroke="none" stroke-width="1" fill="none" fill-rule="evenodd"> 442 <g transform="translate(-384.000000, 0.000000)"> 443 <g id="right_line" transform="translate(384.000000, 0.000000)"> 444 <path d="M24,0 L24,24 L0,24 L0,0 L24,0 Z M12.5934901,23.257841 L12.5819402,23.2595131 L12.5108777,23.2950439 L12.4918791,23.2987469 L12.4918791,23.2987469 L12.4767152,23.2950439 L12.4056548,23.2595131 C12.3958229,23.2563662 12.3870493,23.2590235 12.3821421,23.2649074 L12.3780323,23.275831 L12.360941,23.7031097 L12.3658947,23.7234994 L12.3769048,23.7357139 L12.4804777,23.8096931 L12.4953491,23.8136134 L12.4953491,23.8136134 L12.5071152,23.8096931 L12.6106902,23.7357139 L12.6232938,23.7196733 L12.6232938,23.7196733 L12.6266527,23.7031097 L12.609561,23.275831 C12.6075724,23.2657013 12.6010112,23.2592993 12.5934901,23.257841 L12.5934901,23.257841 Z M12.8583906,23.1452862 L12.8445485,23.1473072 L12.6598443,23.2396597 L12.6498822,23.2499052 L12.6498822,23.2499052 L12.6471943,23.2611114 L12.6650943,23.6906389 L12.6699349,23.7034178 L12.6699349,23.7034178 L12.678386,23.7104931 L12.8793402,23.8032389 C12.8914285,23.8068999 12.9022333,23.8029875 12.9078286,23.7952264 L12.9118235,23.7811639 L12.8776777,23.1665331 C12.8752882,23.1545897 12.8674102,23.1470016 12.8583906,23.1452862 L12.8583906,23.1452862 Z M12.1430473,23.1473072 C12.1332178,23.1423925 12.1221763,23.1452606 12.1156365,23.1525954 L12.1099173,23.1665331 L12.0757714,23.7811639 C12.0751323,23.7926639 12.0828099,23.8018602 12.0926481,23.8045676 L12.108256,23.8032389 L12.3092106,23.7104931 L12.3186497,23.7024347 L12.3186497,23.7024347 L12.3225043,23.6906389 L12.340401,23.2611114 L12.337245,23.2485176 L12.337245,23.2485176 L12.3277531,23.2396597 L12.1430473,23.1473072 Z" id="MingCute" fill-rule="nonzero"> </path> 445 <path d="M15.7072,11.2929 C16.0977,11.6834 16.0977,12.3166 15.7072,12.7071 L10.0503,18.364 C9.65982,18.7545 9.02666,18.7545 8.63613,18.364 C8.24561,17.9734 8.24561,17.3403 8.63613,16.9497 L13.5859,12 L8.63613,7.05025 C8.24561,6.65973 8.24561,6.02656 8.63613,5.63604 C9.02666,5.24551 9.65982,5.24551 10.0503,5.63604 L15.7072,11.2929 Z" id="路径" fill="#1D98A5"> </path> 446 </g> 447 </g> 448 449 </svg> 450 451 </button> 452 </div> 453 } 454 455 456 </div> 457 458 } 459 if ((fieldValueBlocked != null && !fieldValueBlocked.ToString().Contains(customerNumber)) || String.IsNullOrWhiteSpace(customerNumber)) 460 { 461 <div class="stock-state pt-2 mt-auto"> 462 @{ 463 464 /*stock state*/ 465 double MainvariantStock = MainVariant.Stock; 466 string MainsvgInStock = "<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"16\" height=\"16\" fill=\"#44B11A\" class=\"bi bi-check-lg\" viewBox=\"0 0 16 16\"><path d=\"M12.736 3.97a.733.733 0 0 1 1.047 0c.286.289.29.756.01 1.05L7.88 12.01a.733.733 0 0 1-1.065.02L3.217 8.384a.757.757 0 0 1 0-1.06.733.733 0 0 1 1.047 0l3.052 3.093 5.4-6.425z\"/></svg>"; 467 string MainsvgOutStock = "<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"25\" height=\"25\" fill=\"#CA0D0D\" class=\"bi bi-x-lg\" viewBox=\"0 0 16 16\"><path d=\"M4.646 4.646a.5.5 0 0 1 .708 0L8 7.293l2.646-2.647a.5.5 0 0 1 .708.708L8.707 8l2.647 2.646a.5.5 0 0 1-.708.708L8 8.707l-2.646 2.647a.5.5 0 0 1-.708-.708L7.293 8 4.646 5.354a.5.5 0 0 1 0-.708\"/></svg>"; 468 469 string MaininfoStock = "<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"16\" height=\"16\" fill=\"currentColor\" class=\"bi bi-info-circle-fill\" viewBox=\"0 0 16 16\"><path d=\"M8 16A8 8 0 1 0 8 0a8 8 0 0 0 0 16m.93-9.412-1 4.705c-.07.34.029.533.304.533.194 0 .487-.07.686-.246l-.088.416c-.287.346-.92.598-1.465.598-.703 0-1.002-.422-.808-1.319l.738-3.468c.064-.293.006-.399-.287-.47l-.451-.081.082-.381 2.29-.287zM8 5.5a1 1 0 1 1 0-2 1 1 0 0 1 0 2\" /></svg>"; 470 string MainisNew = MainVariant?.ProductFieldValues?.GetProductFieldValue("New")?.Value?.ToString().ToLower() ?? ""; 471 string MainisNewSvg = "<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"16\" height=\"16\" fill=\"#F2C400\" class=\"bi bi-star-fill\" viewBox=\"0 0 16 16\"><path d = \"M3.612 15.443c-.386.198-.824-.149-.746-.592l.83-4.73L.173 6.765c-.329-.314-.158-.888.283-.95l4.898-.696L7.538.792c.197-.39.73-.39.927 0l2.184 4.327 4.898.696c.441.062.612.636.282.95l-3.522 3.356.83 4.73c.078.443-.36.79-.746.592L8 13.187l-4.389 2.256z\" /></svg> "; 472 string MainstockState = ""; 473 string MainIsSale = MainVariant?.ProductFieldValues?.GetProductFieldValue("Sale")?.Value?.ToString().ToLower() ?? ""; 474 string MainIsSaleSvg = "<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"16\" height=\"16\" fill=\"#F03232\" class=\"bi bi-star-fill\" viewBox=\"0 0 16 16\"><path d = \"M3.612 15.443c-.386.198-.824-.149-.746-.592l.83-4.73L.173 6.765c-.329-.314-.158-.888.283-.95l4.898-.696L7.538.792c.197-.39.73-.39.927 0l2.184 4.327 4.898.696c.441.062.612.636.282.95l-3.522 3.356.83 4.73c.078.443-.36.79-.746.592L8 13.187l-4.389 2.256z\" /></svg> "; 475 string MainexpectedDeliveryDate = ""; 476 477 if (DateTime.Compare(MainVariant.ExpectedDelivery, new DateTime(1900, 1, 1)) != 0) //In DW, if the Date is not set, it is defaulted 01-01-1900 and not null.. 478 { 479 MainexpectedDeliveryDate = MainVariant.ExpectedDelivery.ToShortDateString(); 480 } 481 482 string MainexpectedDeliveryDateText = !String.IsNullOrWhiteSpace(MainexpectedDeliveryDate) ? Translate("Verwacht:") + "&nbsp;" + MainexpectedDeliveryDate : ""; 483 484 @if (!(bool?)MainVariant.ProductFieldValues.Where(o => o.ProductField.SystemName == "ProductToBeDiscontinued").SingleOrDefault()?.Value ?? false) 485 { 486 if (MainvariantStock > 0) 487 { 488 if (MainisNew == "true" || MainIsSale == "true") 489 { 490 if (MainIsSale == "true") 491 { 492 MainstockState += MainIsSaleSvg + "&nbsp; &nbsp;" + Translate("Sale!") + "<br/>"; 493 } 494 495 if (MainisNew == "true") 496 { 497 MainstockState += MainisNewSvg + "&nbsp; &nbsp;" + Translate("New!") + "<br/>"; 498 } 499 500 MainstockState += "&nbsp;" + Translate("Nu leverbaar"); 501 } 502 else 503 { 504 MainstockState = MainsvgInStock + "&nbsp; " + Translate("Op voorraad"); 505 506 } 507 } 508 else 509 { 510 MainstockState = MainsvgOutStock + "&nbsp;" + Translate("Geen voorraad") + "<br/>" + MainexpectedDeliveryDateText; 511 512 } 513 } 514 else 515 { 516 517 MainstockState = MainsvgOutStock + "&nbsp;" + Translate("Discontinued:") + "<br/>" + MainvariantStock + "&nbsp;" + @Translate("left in stock"); 518 519 } 520 /*End stock state*/ 521 522 523 @MainstockState 524 525 526 } 527 </div> 528 } 529 else 530 { 531 <div class="stock-state pt-2 mt-auto"> 532 @MainOutStock @Translate("Discontinued") 533 </div> 534 } 535 <div class="custom-price mt-auto"> 536 @{ 537 538 539 540 541 bool isErpConnectionDown = !Dynamicweb.Core.Converter.ToBoolean(Dynamicweb.Context.Current.Items["IsWebServiceConnectionAvailable"]); 542 bool hidePrice = anonymousUsersLimitations.Contains("price") && anonymousUser || Pageview.AreaSettings.GetBoolean("ErpDownHidePrices") && isErpConnectionDown; 543 544 bool productIsDiscontinued = product is object && product.Discontinued; 545 bool doNotShowPriceIfProductIsDiscontinued = Model.Item.GetBoolean("DoNotShowPriceIfProductIsDiscontinued"); 546 var isDiscontinued = productIsDiscontinued && doNotShowPriceIfProductIsDiscontinued; 547 } 548 549 @if (product is object && !hidePrice && !isDiscontinued) 550 { 551 string unitId = !string.IsNullOrEmpty(Dynamicweb.Context.Current.Request.Form.Get("UnitId")) ? Dynamicweb.Context.Current.Request.Form.Get("UnitId") : string.Empty; 552 553 string priceFontSize = Model.Item.GetRawValueString("PriceSize", "fs-4"); 554 string horizontalAlign = Model.Item.GetRawValueString("HorizontalAlignment", ""); 555 string layout = Model.Item.GetRawValueString("Layout", "horizontal"); 556 string textAlign = horizontalAlign == "center" ? "text-center" : string.Empty; 557 textAlign = horizontalAlign == "end" ? "text-end" : textAlign; 558 559 horizontalAlign = horizontalAlign == "center" && layout == "horizontal" ? "justify-content-center" : horizontalAlign; 560 horizontalAlign = horizontalAlign == "end" && layout == "horizontal" ? "justify-content-end" : horizontalAlign; 561 horizontalAlign = horizontalAlign == "center" && layout == "vertical" ? "align-items-center" : horizontalAlign; 562 horizontalAlign = horizontalAlign == "end" && layout == "vertical" ? "align-items-end" : horizontalAlign; 563 564 string flexDirection = layout == "horizontal" ? string.Empty : "flex-column"; 565 string flexGap = layout == "horizontal" ? "gap-3" : string.Empty; 566 string order = layout == "horizontal" ? string.Empty : "order-2"; 567 568 569 string contentPadding = Model.Item.GetRawValueString("ContentPadding", ""); 570 contentPadding = contentPadding == "none" ? "p-0" : contentPadding; 571 contentPadding = contentPadding == "small" ? "p-1 px-md-2 py-md-1" : contentPadding; 572 contentPadding = contentPadding == "large" ? "p-2 px-md-3 py-md-2" : contentPadding; 573 string liveInfoClass = ""; 574 575 576 577 578 579 580 if (isLazyLoadingForProductInfoEnabled) 581 { 582 if (Dynamicweb.Context.Current.Items.Contains("ProductInfoFeed")) 583 { 584 productInfoFeed = Dynamicweb.Context.Current.Items["ProductInfoFeed"]?.ToString(); 585 if (!string.IsNullOrEmpty(productInfoFeed)) 586 { 587 productInfoFeed = $"data-product-info-feed=\"{productInfoFeed}\""; 588 } 589 } 590 liveInfoClass = "js-live-info"; 591 } 592 593 <div class="@textAlign @liveInfoClass item_@Model.Item.SystemName.ToLower()" data-product-id="@product.Id" data-variant-id="@product.VariantId" @productInfoFeed> 594 @if (showInformativePrice && product.PriceInformative.Price != 0) 595 { 596 <div class="opacity-50"> 597 <span>@Translate("RRP") </span> 598 <span class="text-decoration-line-through text-price">@product.PriceInformative.PriceFormatted</span> 599 </div> 600 } 601 <div class="@priceFontSize m-0 d-flex flex-wrap @flexDirection @flexGap @horizontalAlign" style="row-gap: 0 !important" itemprop="offers" itemscope itemtype="https://schema.org/Offer"> 602 <span itemprop="priceCurrency" content="@product.Price.CurrencyCode" class="d-none"></span> 603 604 605 @if (showPricesWithVat == "false" && !neverShowVat) 606 { 607 if (isLazyLoadingForProductInfoEnabled && !Pageview.IsVisualEditorMode) 608 { 609 <span itemprop="price" content="" class="d-none"></span> 610 <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> 611 } 612 else 613 { 614 string beforePrice = !string.IsNullOrEmpty(unitId) ? product.GetPrice(unitId).PriceBeforeDiscount.PriceWithoutVatFormatted : product.PriceBeforeDiscount.PriceWithoutVatFormatted; 615 616 <span itemprop="price" content="@product.Price.PriceWithoutVat.ToString("0.00", System.Globalization.CultureInfo.InvariantCulture)" class="d-none"></span> 617 if (product.Price.Price != product.PriceBeforeDiscount.Price) 618 { 619 <span class="text-decoration-line-through opacity-75 @order">@beforePrice</span> 620 } 621 } 622 } 623 else 624 { 625 if (isLazyLoadingForProductInfoEnabled && !Pageview.IsVisualEditorMode) 626 { 627 <span itemprop="price" content="" class="d-none"></span> 628 <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> 629 } 630 else 631 { 632 string beforePrice = !string.IsNullOrEmpty(unitId) ? product.GetPrice(unitId).PriceBeforeDiscount.PriceFormatted : product.PriceBeforeDiscount.PriceFormatted; 633 634 <span itemprop="price" content="@product.Price.Price.ToString("0.00", System.Globalization.CultureInfo.InvariantCulture)" class="d-none"></span> 635 636 if (product.Price.Price != product.PriceBeforeDiscount.Price) 637 { 638 <span class="text-decoration-line-through opacity-75 @order"> 639 <span class="text-price">@beforePrice</span> 640 </span> 641 } 642 } 643 } 644 645 @if (showPricesWithVat == "false" && !neverShowVat) 646 { 647 if (isLazyLoadingForProductInfoEnabled && !Pageview.IsVisualEditorMode) 648 { 649 <span class="text-price js-text-price"> 650 <span class="spinner-border" role="status"></span> 651 </span> 652 } 653 else 654 { 655 string price = !string.IsNullOrEmpty(unitId) ? product.GetPrice(unitId).Price.PriceWithoutVatFormatted : product.Price.PriceWithoutVatFormatted; 656 657 if (product?.VariantInfo?.VariantInfo != null) 658 { 659 priceMin = product?.VariantInfo?.PriceMin?.PriceWithoutVatFormatted != null ? product.VariantInfo.PriceMin.PriceWithoutVatFormatted : ""; 660 priceMax = product?.VariantInfo?.PriceMax?.PriceWithoutVatFormatted != null ? product.VariantInfo.PriceMax.PriceWithoutVatFormatted : ""; 661 } 662 if (priceMin != priceMax) 663 { 664 price = priceMin + " - " + priceMax; 665 } 666 <span class="@theme @contentPadding"> 667 <span class="text-price">@price</span> 668 </span> 669 } 670 } 671 else 672 { 673 if (isLazyLoadingForProductInfoEnabled && !Pageview.IsVisualEditorMode) 674 { 675 <span class="text-price js-text-price"> 676 <span class="spinner-border" role="status"></span> 677 </span> 678 } 679 else 680 { 681 string price = !string.IsNullOrEmpty(unitId) ? product.GetPrice(unitId).Price.PriceFormatted : product.Price.PriceFormatted; 682 683 if (product?.VariantInfo?.VariantInfo != null) 684 { 685 priceMin = product?.VariantInfo?.PriceMin?.PriceFormatted != null ? product.VariantInfo.PriceMin.PriceFormatted : ""; 686 priceMax = product?.VariantInfo?.PriceMax?.PriceFormatted != null ? product.VariantInfo.PriceMax.PriceFormatted : ""; 687 } 688 if (priceMin != priceMax) 689 { 690 price = priceMin + " - " + priceMax; 691 } 692 <span class="@theme @contentPadding"> 693 <span class="text-price">@price</span> 694 </span> 695 } 696 } 697 698 @* Stock state for Schema.org, start *@ 699 @{ 700 Uri url = Dynamicweb.Context.Current.Request.Url; 701 } 702 703 <link itemprop="url" href="@url"> 704 705 @{ 706 bool IsNeverOutOfStock = product.NeverOutOfstock; 707 } 708 709 @if (IsNeverOutOfStock) 710 { 711 <span itemprop="availability" class="d-none">@Translate("Available in stock")</span> 712 } 713 else 714 { 715 if (product.StockLevel > 0) 716 { 717 <span itemprop="availability" class="d-none">InStock</span> 718 } 719 else 720 { 721 <span itemprop="availability" class="d-none">OutOfStock</span> 722 } 723 } 724 @* Stock state for Schema.org, stop *@ 725 726 </div> 727 728 @if (showPricesWithVat == "false" && !neverShowVat) 729 { 730 if (isLazyLoadingForProductInfoEnabled && !Pageview.IsVisualEditorMode) 731 { 732 <small class="opacity-85 fst-normal js-text-price-with-vat d-none" data-suffix="@Translate("Incl. VAT")"></small> 733 } 734 else 735 { 736 string price = !string.IsNullOrEmpty(unitId) ? product.GetPrice(unitId).Price.PriceWithVatFormatted : product.Price.PriceWithVatFormatted; 737 738 if (product?.VariantInfo?.VariantInfo != null) 739 { 740 priceMin = product?.VariantInfo?.PriceMin?.PriceWithVatFormatted != null ? product.VariantInfo.PriceMin.PriceWithVatFormatted : ""; 741 priceMax = product?.VariantInfo?.PriceMax?.PriceWithVatFormatted != null ? product.VariantInfo.PriceMax.PriceWithVatFormatted : ""; 742 } 743 if (priceMin != priceMax) 744 { 745 price = priceMin + " - " + priceMax; 746 } 747 <!-- <small class="opacity-85 fst-normal">@price @Translate("Incl. VAT")</small> --> 748 } 749 } 750 </div> 751 } 752 else if (Pageview.IsVisualEditorMode) 753 { 754 <div class="alert alert-dark m-0" role="alert"> 755 <span>@Translate("No products available")</span> 756 </div> 757 } 758 759 </div> 760 } 761 } 762
Tischlampe 1L ring perforiert
Error executing template "Designs/Swift/Paragraph/CustomProductSlider.cshtml"
System.NullReferenceException: Object reference not set to an instance of an object.
   at CompiledRazorTemplates.Dynamic.RazorEngine_3562354021b44d5c892fe73dc2806e4f.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 Dynamicweb.Ecommerce.ProductCatalog 3 @using Dynamicweb.Ecommerce.CustomerExperienceCenter.Favorites 4 @using Dynamicweb.Files 5 @using System.IO 6 @using System.Net 7 @using Dynamicweb.Security.UserManagement 8 9 10 @{ 11 ProductViewModel product = null; 12 if (Dynamicweb.Context.Current.Items.Contains("ProductDetails")) 13 { 14 product = (ProductViewModel)Dynamicweb.Context.Current.Items["ProductDetails"]; 15 } 16 else if (Pageview.Page.Item["DummyProduct"] != null && Pageview.IsVisualEditorMode) 17 { 18 var pageViewModel = Dynamicweb.Frontend.ContentViewModelFactory.CreatePageInfoViewModel(Pageview.Page); 19 ProductListViewModel productList = pageViewModel.Item.GetValue("DummyProduct") != null ? pageViewModel.Item.GetValue("DummyProduct") as ProductListViewModel : new ProductListViewModel(); 20 21 if (productList?.Products is object) 22 { 23 product = productList.Products[0]; 24 } 25 } 26 } 27 28 @{ 29 var currentUser = Pageview?.User; 30 var customerNumber = !string.IsNullOrEmpty(currentUser?.CustomerNumber) 31 ? currentUser.CustomerNumber 32 : ""; 33 } 34 @if (product is object) 35 { 36 string imagePath = product?.DefaultImage?.Value ?? ""; 37 string imagePathUrlEncoded = Dynamicweb.Context.Current.Server.UrlEncode(imagePath); 38 39 string ratio = Model.Item.GetRawValueString("ImageAspectRatio", ""); 40 ratio = ratio != "0" ? ratio : ""; 41 string ratioCssClass = ratio != "" ? " ratio" : ""; 42 string ratioVariable = ratio != "" ? "--bs-aspect-ratio: " + ratio + ";" : ""; 43 44 string width = Model.Item.GetRawValueString("Width", "auto"); 45 int smallImageSize = 640; 46 int largeImageSize = width == "auto" ? 1280 : Convert.ToInt32(width); 47 48 string ImageObjectFit = Model.Item.GetRawValueString("ImageObjectFit", "contain"); 49 50 string imagePathXs = "/Admin/Public/GetImage.ashx?width=" + smallImageSize + "&image=" + imagePathUrlEncoded + "&format=webp"; 51 string imagePathS = "/Admin/Public/GetImage.ashx?width=" + largeImageSize + "&image=" + imagePathUrlEncoded + "&format=webp"; 52 string imagePathFallBack = "/Admin/Public/GetImage.ashx?width=" + largeImageSize + "&image=" + imagePathUrlEncoded + "&format=webp"; 53 54 var badgeParms = new Dictionary<string, object>(); 55 badgeParms.Add("size", "h7"); 56 badgeParms.Add("saleBadgeType", Model.Item.GetRawValue("SaleBadgeType")); 57 badgeParms.Add("saleBadgeCssClassName", Model.Item.GetRawValue("SaleBadgeDesign")); 58 badgeParms.Add("newBadgeCssClassName", Model.Item.GetRawValue("NewBadgeDesign")); 59 badgeParms.Add("newPublicationDays", Model.Item.GetInt32("NewPublicationDays")); 60 badgeParms.Add("campaignBadgesValues", Model.Item.GetList("CampaignBadges")?.GetRawValue().OfType<string>().ToList()); 61 62 string badgeSize = Model.Item.GetRawValueString("BadgeSize", "fs-2"); 63 bool saleBadgeEnabled = !string.IsNullOrWhiteSpace(Model.Item.GetRawValueString("SaleBadgeDesign")) && Model.Item.GetRawValueString("SaleBadgeDesign") != "none" ? true : false; 64 bool newBadgeEnabled = !string.IsNullOrWhiteSpace(Model.Item.GetRawValueString("NewBadgeDesign")) && Model.Item.GetRawValueString("NewBadgeDesign") != "none" ? true : false; 65 66 /*Custom badge*/ 67 var productService = new Dynamicweb.Ecommerce.Products.ProductService(); 68 var currency = Dynamicweb.Ecommerce.Common.Context.Currency.Code; 69 var formatProvider = new System.Globalization.NumberFormatInfo(); 70 formatProvider.NumberDecimalSeparator = "."; 71 formatProvider.NumberGroupSeparator = ","; 72 var MainVariant = productService.GetProductById(product.Id, product.VariantId, false); 73 var fieldValueBlocked = MainVariant?.ProductFieldValues?.GetProductFieldValue("BlockedCustomerList")?.Value; 74 75 76 string isNewProduct = MainVariant?.ProductFieldValues?.GetProductFieldValue("New")?.Value?.ToString().ToLower() ?? ""; 77 string MainisSale = MainVariant?.ProductFieldValues?.GetProductFieldValue("Sale")?.Value?.ToString().ToLower() ?? ""; 78 bool showNewBadge = isNewProduct == "true" ? true : false; 79 bool showSaleBadge = MainisSale == "true" ? true : false; 80 string showNewSaleBadge = "d-none"; 81 if (showSaleBadge) 82 { 83 badgeParms.Add("isSale", "true"); 84 85 } 86 else 87 { 88 badgeParms.Add("isSale", "false"); 89 } 90 if (showNewBadge) 91 { 92 badgeParms.Add("isNew", "true"); 93 } 94 else 95 { 96 badgeParms.Add("isNew", "false"); 97 } 98 /*End Custom badge*/ 99 if (showSaleBadge || showNewBadge) 100 { 101 showNewSaleBadge = ""; 102 } 103 DateTime createdDate = product.Created.Value; 104 bool showBadges = saleBadgeEnabled && product.Discount.Price != 0 ? true : false; 105 106 bool showFavoritesSelector = !string.IsNullOrEmpty(Model.Item.GetString("ShowAddToFavorites")) ? Model.Item.GetBoolean("ShowAddToFavorites") : false; 107 string anonymousUsersLimitations = Pageview.AreaSettings.GetRawValueString("AnonymousUsers", ""); 108 bool anonymousUser = Pageview.User == null; 109 110 var favoriteParameters = new Dictionary<string, object>(); 111 if (!anonymousUser && showFavoritesSelector) 112 { 113 int defaultFavoriteListId = 0; 114 115 IEnumerable<FavoriteList> favoreiteLists = Pageview.User.GetFavoriteLists(); 116 if (favoreiteLists.Count() == 1) 117 { 118 foreach (FavoriteList list in favoreiteLists) 119 { 120 defaultFavoriteListId = list.ListId; 121 } 122 } 123 124 favoriteParameters.Add("ListId", defaultFavoriteListId); 125 } 126 127 MediaViewModel alternativeImage = new MediaViewModel(); 128 if (Model.Item.GetBoolean("ShowAlternativeImageOnHover")) 129 { 130 var selectedImageCategories = Model.Item.GetList("GetAlternativeImageFrom")?.GetRawValue().OfType<string>().ToList(); 131 List<MediaViewModel> allAssetsImages = product.AssetCategories.Where(x => selectedImageCategories.Contains(x.SystemName)).SelectMany(x => x.Assets).ToList(); 132 allAssetsImages.RemoveAll(x => x.Value == product.DefaultImage.Value); 133 alternativeImage = allAssetsImages.FirstOrDefault(); 134 } 135 136 string altImagePathXs = string.Empty; 137 string altImagePathS = string.Empty; 138 139 if (!string.IsNullOrEmpty(alternativeImage?.Value)) 140 { 141 altImagePathXs = "/Admin/Public/GetImage.ashx?width=" + smallImageSize + "&image=" + Dynamicweb.Context.Current.Server.UrlEncode(alternativeImage.Value) + "&format=webp"; 142 altImagePathS = "/Admin/Public/GetImage.ashx?width=" + largeImageSize + "&image=" + Dynamicweb.Context.Current.Server.UrlEncode(alternativeImage.Value) + "&format=webp"; 143 } 144 145 @* Theme settings *@ 146 string theme = !string.IsNullOrWhiteSpace(Model.Item.GetRawValueString("Theme")) ? " theme " + Model.Item.GetRawValueString("Theme").Replace(" ", "").Trim().ToLower() : ""; 147 string themeBorder = !string.IsNullOrWhiteSpace(theme) ? "border: 1px solid rgba(0,0,0,0)" : ""; 148 string themePadding = !string.IsNullOrWhiteSpace(theme) ? "p-2 p-lg-3" : ""; 149 150 string imageId = "ProductImage_" + product.Id; 151 152 153 154 string fullWidth = width == "auto" ? "w-100" : ""; 155 string customWidth = width != "auto" ? "style=\"width: " + width + "px\"" : "style=\"min-width: 60px\""; 156 157 string altImageZindex = Model.Item.GetBoolean("ShowAlternativeImageOnHover") && !string.IsNullOrEmpty(alternativeImage?.Value) ? " z-index: 1" : string.Empty; 158 string groupid = !string.IsNullOrEmpty(Dynamicweb.Context.Current.Request.QueryString.Get("GroupID")) ? Dynamicweb.Context.Current.Request.QueryString.Get("GroupID"):"" ; 159 string link = product.GetProductLink(GetPageIdByNavigationTag("Shop"), false); 160 var productVariantGroups = product.VariantGroups(); 161 string MainOutStock = "<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"25\" height=\"25\" fill=\"#CA0D0D\" class=\"bi bi-x-lg\" viewBox=\"0 0 16 16\"><path d=\"M4.646 4.646a.5.5 0 0 1 .708 0L8 7.293l2.646-2.647a.5.5 0 0 1 .708.708L8.707 8l2.647 2.646a.5.5 0 0 1-.708.708L8 8.707l-2.646 2.647a.5.5 0 0 1-.708-.708L7.293 8 4.646 5.354a.5.5 0 0 1 0-.708\"/></svg>"; 162 163 @if (!string.IsNullOrEmpty(imagePath)) 164 { 165 <div class="@fullWidth @theme position-relative item_@Model.Item.SystemName.ToLower() main-image-container" @customWidth> 166 <div class="" style="@(ratioVariable)@(altImageZindex)"> 167 <div class="d-flex justify-content-center align-items-center"> 168 <a class="main-link-link" href="@link"> 169 @if (imagePath.StartsWith("/Files/", StringComparison.OrdinalIgnoreCase)) 170 { 171 <img id="@imageId" 172 srcset=" 173 @imagePathXs @(smallImageSize)w, 174 @imagePathS @(largeImageSize)w" 175 sizes="(max-width: 992px) 50vw, 25vw" 176 src="@imagePathFallBack" 177 loading="lazy" 178 decoding="async" 179 class="h-100 w-100 @themePadding main-image" 180 style="object-fit: @ImageObjectFit; @themeBorder " 181 alt="@product.Name" 182 itemprop="image"> 183 } 184 else 185 { 186 <img src="@product.DefaultImage.Value" 187 loading="lazy" 188 class="h-100 w-100 @themePadding main-image" 189 style="object-fit: contain; @themeBorder" 190 alt="@product.Name" 191 itemprop="image"> 192 } 193 </a> 194 </div> 195 </div> 196 197 <div class="position-absolute top-0 left-0 p-2 pb-0 custom-badge-product-list @showNewSaleBadge"> 198 @{ 199 @RenderPartial("Components/Custom_EcommerceBadge.cshtml", product, badgeParms) 200 } 201 </div> 202 203 204 </div> 205 } 206 207 <div class="product-info h-100"> 208 <div class="fs-7 pt-1 opacity-85 start item_@Model.Item.SystemName.ToLower() product-number" itemprop="sku">@product.Id / @product.VariantId - @product.VariantName</div> 209 <div class="py-2" data-col-size="12"> 210 <h2 class="h6 start m-0 item_swift_productheader product-name" itemprop="name"><b>@product.Name</b></h2> 211 </div> 212 </div> 213 var sliderId = $"thumb-scroll-{product.Id}"; 214 if (productVariantGroups.Any() && product?.VariantInfo?.VariantInfo != null) 215 216 { 217 @using Dynamicweb.Ecommerce.Prices 218 @{ 219 string[] variantId = product.VariantId.Split('.'); 220 string showPricesWithVat = Pageview.Area.EcomPricesWithVat.ToLower(); 221 bool neverShowVat = string.IsNullOrEmpty(showPricesWithVat); 222 bool showInformativePrice = Model.Item.GetBoolean("ShowInformativePrice"); 223 string productInfoFeed = ""; 224 bool isLazyLoadingForProductInfoEnabled = Dynamicweb.Core.Converter.ToBoolean(Dynamicweb.Context.Current.Items["IsLazyLoadingForProductInfoEnabled"]); 225 if (isLazyLoadingForProductInfoEnabled) 226 { 227 if (Dynamicweb.Context.Current.Items.Contains("ProductInfoFeed")) 228 { 229 productInfoFeed = Dynamicweb.Context.Current.Items["ProductInfoFeed"]?.ToString(); 230 if (!string.IsNullOrEmpty(productInfoFeed)) 231 { 232 productInfoFeed =productInfoFeed; 233 } 234 } 235 236 } 237 string priceMin = ""; 238 string priceMax = ""; 239 int groupNumber = 1; 240 241 242 243 244 string baseUrl = $"Default.aspx?ID={GetPageIdByNavigationTag("Shop")}&GroupID={product.PrimaryOrDefaultGroup.Id}&ProductID={product.Id}"; 245 if (!string.IsNullOrEmpty(baseUrl)) 246 { 247 baseUrl = $"/{baseUrl.TrimStart('/')}"; 248 } 249 string variantUrl = string.Empty; 250 251 252 Dictionary<string, string> 253 variantImages = new Dictionary<string, string> 254 (); 255 <div class="last-row mt-auto"> 256 257 @foreach (var variantGroup in productVariantGroups) 258 { 259 <div class="thumbnail-wrapper"> 260 <button class="thumb-nav prev" onclick="scrollThumbs('@sliderId', -1)"> 261 <svg width="20px" height="20px" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" fill="#1D98A5"> 262 263 <g stroke="none" stroke-width="1" fill="none" fill-rule="evenodd"> 264 <g transform="translate(-336.000000, 0.000000)"> 265 <g id="left_line" transform="translate(336.000000, 0.000000)"> 266 <path d="M24,0 L24,24 L0,24 L0,0 L24,0 Z M12.5934901,23.257841 L12.5819402,23.2595131 L12.5108777,23.2950439 L12.4918791,23.2987469 L12.4918791,23.2987469 L12.4767152,23.2950439 L12.4056548,23.2595131 C12.3958229,23.2563662 12.3870493,23.2590235 12.3821421,23.2649074 L12.3780323,23.275831 L12.360941,23.7031097 L12.3658947,23.7234994 L12.3769048,23.7357139 L12.4804777,23.8096931 L12.4953491,23.8136134 L12.4953491,23.8136134 L12.5071152,23.8096931 L12.6106902,23.7357139 L12.6232938,23.7196733 L12.6232938,23.7196733 L12.6266527,23.7031097 L12.609561,23.275831 C12.6075724,23.2657013 12.6010112,23.2592993 12.5934901,23.257841 L12.5934901,23.257841 Z M12.8583906,23.1452862 L12.8445485,23.1473072 L12.6598443,23.2396597 L12.6498822,23.2499052 L12.6498822,23.2499052 L12.6471943,23.2611114 L12.6650943,23.6906389 L12.6699349,23.7034178 L12.6699349,23.7034178 L12.678386,23.7104931 L12.8793402,23.8032389 C12.8914285,23.8068999 12.9022333,23.8029875 12.9078286,23.7952264 L12.9118235,23.7811639 L12.8776777,23.1665331 C12.8752882,23.1545897 12.8674102,23.1470016 12.8583906,23.1452862 L12.8583906,23.1452862 Z M12.1430473,23.1473072 C12.1332178,23.1423925 12.1221763,23.1452606 12.1156365,23.1525954 L12.1099173,23.1665331 L12.0757714,23.7811639 C12.0751323,23.7926639 12.0828099,23.8018602 12.0926481,23.8045676 L12.108256,23.8032389 L12.3092106,23.7104931 L12.3186497,23.7024347 L12.3186497,23.7024347 L12.3225043,23.6906389 L12.340401,23.2611114 L12.337245,23.2485176 L12.337245,23.2485176 L12.3277531,23.2396597 L12.1430473,23.1473072 Z" id="MingCute" fill-rule="nonzero"> </path> 267 <path d="M8.29292,12.7071 C7.9024,12.3166 7.9024,11.6834 8.29292,11.2929 L13.9498,5.63604 C14.3403,5.24551 14.9735,5.24551 15.364,5.63604 C15.7545,6.02656 15.7545,6.65973 15.364,7.05025 L10.4142,12 L15.364,16.9497 C15.7545,17.3403 15.7545,17.9734 15.364,18.364 C14.9735,18.7545 14.3403,18.7545 13.9498,18.364 L8.29292,12.7071 Z" id="路径" fill="#1D98A5"> </path> 268 </g> 269 </g> 270 </g> 271 </svg> 272 273 </button> 274 <div class="thumbnail-scroll" id="@sliderId"> 275 @{ 276 VariantGroupViewModel group = variantGroup; 277 foreach (var option in group.Options.OrderBy(o => o.Id)) 278 { 279 var productVariant = productService.GetProductById(product.Id, option.Id, false); 280 281 var productSelection = new PriceProductSelection(productVariant, null, 0); 282 283 var currencyCode = string.IsNullOrWhiteSpace(Pageview.User.Currency) ? Pageview.Area.EcomCurrencyId : Pageview.User.Currency; 284 var countryCode = string.IsNullOrWhiteSpace(Pageview.User.CountryCode) ? Pageview.Area.EcomCountryCode : Pageview.User.CountryCode; 285 286 var userCurrency = Dynamicweb.Ecommerce.Services.Currencies.GetCurrency(currencyCode); 287 var userCountry = Dynamicweb.Ecommerce.Services.Countries.GetCountry(countryCode); 288 289 var priceContext = new PriceContext(userCurrency, userCountry, null, Pageview.User, false, null); 290 var productPrice = Dynamicweb.Ecommerce.Services.Prices.FindPrices(priceContext, productSelection, false); 291 292 //throw new Exception(System.Text.Json.JsonSerializer.Serialize(productPrice)); 293 294 var fieldValue = productVariant?.ProductFieldValues?.GetProductFieldValue("BlockedCustomerList")?.Value; 295 296 if ((fieldValue != null && !fieldValue.ToString().Contains(customerNumber)) || String.IsNullOrWhiteSpace(customerNumber)) 297 { 298 299 300 string active = variantId != null && variantId.Contains(option.Id) ? "active" : string.Empty; 301 string buttonId = $"{product.Id}_{option.Id}_{Pageview.CurrentParagraph.ID}"; 302 string contrastColor = string.Empty; 303 304 string searchKey = $"{product.Id}_{option.Id}_"; 305 /*Images*/ 306 var imagePathVariant = option.Image?.Value ?? ""; 307 308 309 var folderPath = Path.GetDirectoryName(imagePathVariant); 310 311 string physicalFolderPath = Dynamicweb.Context.Current.Server.MapPath(folderPath); 312 313 string lastImage = null; 314 315 if (Directory.Exists(physicalFolderPath)) 316 { 317 318 var fileWith15 = Directory.GetFiles(physicalFolderPath) 319 .FirstOrDefault(f => Path.GetFileName(f).Contains($"{product.Id}_{option.Id}_9")); 320 321 if (fileWith15 != null) 322 { 323 lastImage = fileWith15; 324 } 325 else 326 { 327 var files = Directory.GetFiles(physicalFolderPath) 328 .Where(f => Path.GetFileName(f).StartsWith($"{product.Id}_{option.Id}_")) 329 .OrderByDescending(f => 330 { 331 var filename = Path.GetFileNameWithoutExtension(f); 332 var match = System.Text.RegularExpressions.Regex.Match(filename, @"_(\d+)$"); 333 if (match.Success && int.TryParse(match.Groups[1].Value, out int index)) 334 { 335 return index; 336 } 337 return 0; 338 }) 339 .ToList(); 340 341 if (files.Any()) 342 { 343 lastImage = files.First(); 344 } 345 } 346 } 347 348 var lastImageUrl = lastImage != null ? lastImage : "/Files/Images/zijlstra/Afbeeldingen_overig/Coming_Soon.jpg"; 349 int index = lastImageUrl.IndexOf("Files"); 350 string relativePath = index >= 0 ? lastImageUrl.Substring(index).Replace("\\", "/") : lastImageUrl.Replace("\\", "/"); 351 lastImageUrl = "/" + relativePath; 352 lastImageUrl = Dynamicweb.Context.Current.Server.UrlEncode(lastImageUrl); 353 var variantImg = option.Image is object ? Dynamicweb.Context.Current.Server.UrlEncode(option.Image.Value) : null; 354 var variantLink = "/Default.aspx?ID=" + GetPageIdByNavigationTag("Shop") + "&GroupID=" + product.PrimaryOrDefaultGroup.Id + "&ProductID=" + product.Id + "&VariantID=" + option.Id; 355 356 string variantImage = string.Empty; 357 variantImages.TryGetValue(option.Id, out variantImage); 358 /*End Images*/ 359 360 /*stock state*/ 361 double variantStock = productVariant.Stock; 362 string svgInStock = "<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"16\" height=\"16\" fill=\"#44B11A\" class=\"bi bi-check-lg\" viewBox=\"0 0 16 16\"><path d=\"M12.736 3.97a.733.733 0 0 1 1.047 0c.286.289.29.756.01 1.05L7.88 12.01a.733.733 0 0 1-1.065.02L3.217 8.384a.757.757 0 0 1 0-1.06.733.733 0 0 1 1.047 0l3.052 3.093 5.4-6.425z\"/></svg>"; 363 string svgOutStock = "<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"25\" height=\"25\" fill=\"#CA0D0D\" class=\"bi bi-x-lg\" viewBox=\"0 0 16 16\"><path d=\"M4.646 4.646a.5.5 0 0 1 .708 0L8 7.293l2.646-2.647a.5.5 0 0 1 .708.708L8.707 8l2.647 2.646a.5.5 0 0 1-.708.708L8 8.707l-2.646 2.647a.5.5 0 0 1-.708-.708L7.293 8 4.646 5.354a.5.5 0 0 1 0-.708\"/></svg>"; 364 365 string infoStock = "<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"16\" height=\"16\" fill=\"currentColor\" class=\"bi bi-info-circle-fill\" viewBox=\"0 0 16 16\"><path d=\"M8 16A8 8 0 1 0 8 0a8 8 0 0 0 0 16m.93-9.412-1 4.705c-.07.34.029.533.304.533.194 0 .487-.07.686-.246l-.088.416c-.287.346-.92.598-1.465.598-.703 0-1.002-.422-.808-1.319l.738-3.468c.064-.293.006-.399-.287-.47l-.451-.081.082-.381 2.29-.287zM8 5.5a1 1 0 1 1 0-2 1 1 0 0 1 0 2\" /></svg>"; 366 string isNew = productVariant?.ProductFieldValues?.GetProductFieldValue("New")?.Value?.ToString().ToLower() ?? ""; 367 string isNewSvg = "<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"16\" height=\"16\" fill=\"#F2C400\" class=\"bi bi-star-fill\" viewBox=\"0 0 16 16\"><path d = \"M3.612 15.443c-.386.198-.824-.149-.746-.592l.83-4.73L.173 6.765c-.329-.314-.158-.888.283-.95l4.898-.696L7.538.792c.197-.39.73-.39.927 0l2.184 4.327 4.898.696c.441.062.612.636.282.95l-3.522 3.356.83 4.73c.078.443-.36.79-.746.592L8 13.187l-4.389 2.256z\" /></svg> "; 368 string stockState = ""; 369 370 string isSale = productVariant?.ProductFieldValues?.GetProductFieldValue("Sale")?.Value?.ToString().ToLower() ?? ""; 371 string isSaleSvg = "<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"16\" height=\"16\" fill=\"#F03232\" class=\"bi bi-star-fill\" viewBox=\"0 0 16 16\"><path d = \"M3.612 15.443c-.386.198-.824-.149-.746-.592l.83-4.73L.173 6.765c-.329-.314-.158-.888.283-.95l4.898-.696L7.538.792c.197-.39.73-.39.927 0l2.184 4.327 4.898.696c.441.062.612.636.282.95l-3.522 3.356.83 4.73c.078.443-.36.79-.746.592L8 13.187l-4.389 2.256z\" /></svg> "; 372 373 string expectedDeliveryDate = ""; 374 375 if (DateTime.Compare(productVariant.ExpectedDelivery, new DateTime(1900, 1, 1)) != 0) //In DW, if the Date is not set, it is defaulted 01-01-1900 and not null.. 376 { 377 expectedDeliveryDate = productVariant.ExpectedDelivery.ToShortDateString(); 378 } 379 380 string expectedDeliveryDateText = !String.IsNullOrWhiteSpace(expectedDeliveryDate) ? Translate("Verwacht:") + "&nbsp;" + expectedDeliveryDate : ""; 381 382 @if (!(bool?)productVariant.ProductFieldValues.Where(o => o.ProductField.SystemName == "ProductToBeDiscontinued").SingleOrDefault()?.Value ?? false) 383 { 384 if (variantStock > 0) 385 { 386 if (isNew == "true" || isSale == "true") 387 { 388 if (isSale == "true") 389 { 390 stockState += isSaleSvg + "&nbsp; &nbsp;" + Translate("Sale!") + "<br/>"; 391 } 392 393 if (isNew == "true") 394 { 395 stockState += isNewSvg + "&nbsp; &nbsp;" + Translate("New!") + "<br/>"; 396 } 397 398 stockState += "&nbsp;" + Translate("Nu leverbaar"); 399 } 400 else 401 { 402 stockState = svgInStock + "&nbsp; " + Translate("Op voorraad"); 403 404 } 405 } 406 else 407 { 408 stockState = svgOutStock + "&nbsp;" + Translate("Geen voorraad") + "<br/>" + expectedDeliveryDateText; 409 410 } 411 } 412 else 413 { 414 415 stockState = svgOutStock + "&nbsp;" + Translate("Discontinued:") + "<br/>" + variantStock + "&nbsp;" + @Translate("left in stock"); 416 417 } 418 /*End stock state*/ 419 /*Price variants*/ 420 double price = productVariant.DefaultPrice; 421 double cost = productVariant.Cost; 422 423 string priceFormated = Dynamicweb.Ecommerce.Services.Currencies.Format(Dynamicweb.Ecommerce.Services.Currencies.GetCurrency(currency), Convert.ToDouble(productPrice.ToList()[0].Amount, formatProvider)); 424 //string priceFormated = Dynamicweb.Ecommerce.Services.Currencies.Format(Dynamicweb.Ecommerce.Services.Currencies.GetCurrency(currency), Convert.ToDouble(price, formatProvider)); 425 426 427 428 /*End Price variants*/ 429 430 <img class="theme thumbnail" data-stockstate="@WebUtility.HtmlEncode(stockState)" src="/Admin/Public/GetImage.ashx?image=@(lastImageUrl)&width=64&format=webp" onclick="selectVariant('@(product.Id)','/Admin/Public/GetImage.ashx?image=@(variantImg)&format=webp','@variantLink','@product.Id','@option.Id','@option.Name',this.dataset.stockstate,'@isNew','@isSale','@priceFormated','@cost')" /> 431 432 433 } 434 } 435 436 } 437 </div> 438 <button class="thumb-nav next" onclick="scrollThumbs('@sliderId', 1)"> 439 <svg width="20px" height="20px" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" fill="#1D98A5"> 440 441 <g stroke="none" stroke-width="1" fill="none" fill-rule="evenodd"> 442 <g transform="translate(-384.000000, 0.000000)"> 443 <g id="right_line" transform="translate(384.000000, 0.000000)"> 444 <path d="M24,0 L24,24 L0,24 L0,0 L24,0 Z M12.5934901,23.257841 L12.5819402,23.2595131 L12.5108777,23.2950439 L12.4918791,23.2987469 L12.4918791,23.2987469 L12.4767152,23.2950439 L12.4056548,23.2595131 C12.3958229,23.2563662 12.3870493,23.2590235 12.3821421,23.2649074 L12.3780323,23.275831 L12.360941,23.7031097 L12.3658947,23.7234994 L12.3769048,23.7357139 L12.4804777,23.8096931 L12.4953491,23.8136134 L12.4953491,23.8136134 L12.5071152,23.8096931 L12.6106902,23.7357139 L12.6232938,23.7196733 L12.6232938,23.7196733 L12.6266527,23.7031097 L12.609561,23.275831 C12.6075724,23.2657013 12.6010112,23.2592993 12.5934901,23.257841 L12.5934901,23.257841 Z M12.8583906,23.1452862 L12.8445485,23.1473072 L12.6598443,23.2396597 L12.6498822,23.2499052 L12.6498822,23.2499052 L12.6471943,23.2611114 L12.6650943,23.6906389 L12.6699349,23.7034178 L12.6699349,23.7034178 L12.678386,23.7104931 L12.8793402,23.8032389 C12.8914285,23.8068999 12.9022333,23.8029875 12.9078286,23.7952264 L12.9118235,23.7811639 L12.8776777,23.1665331 C12.8752882,23.1545897 12.8674102,23.1470016 12.8583906,23.1452862 L12.8583906,23.1452862 Z M12.1430473,23.1473072 C12.1332178,23.1423925 12.1221763,23.1452606 12.1156365,23.1525954 L12.1099173,23.1665331 L12.0757714,23.7811639 C12.0751323,23.7926639 12.0828099,23.8018602 12.0926481,23.8045676 L12.108256,23.8032389 L12.3092106,23.7104931 L12.3186497,23.7024347 L12.3186497,23.7024347 L12.3225043,23.6906389 L12.340401,23.2611114 L12.337245,23.2485176 L12.337245,23.2485176 L12.3277531,23.2396597 L12.1430473,23.1473072 Z" id="MingCute" fill-rule="nonzero"> </path> 445 <path d="M15.7072,11.2929 C16.0977,11.6834 16.0977,12.3166 15.7072,12.7071 L10.0503,18.364 C9.65982,18.7545 9.02666,18.7545 8.63613,18.364 C8.24561,17.9734 8.24561,17.3403 8.63613,16.9497 L13.5859,12 L8.63613,7.05025 C8.24561,6.65973 8.24561,6.02656 8.63613,5.63604 C9.02666,5.24551 9.65982,5.24551 10.0503,5.63604 L15.7072,11.2929 Z" id="路径" fill="#1D98A5"> </path> 446 </g> 447 </g> 448 449 </svg> 450 451 </button> 452 </div> 453 } 454 455 456 </div> 457 458 } 459 if ((fieldValueBlocked != null && !fieldValueBlocked.ToString().Contains(customerNumber)) || String.IsNullOrWhiteSpace(customerNumber)) 460 { 461 <div class="stock-state pt-2 mt-auto"> 462 @{ 463 464 /*stock state*/ 465 double MainvariantStock = MainVariant.Stock; 466 string MainsvgInStock = "<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"16\" height=\"16\" fill=\"#44B11A\" class=\"bi bi-check-lg\" viewBox=\"0 0 16 16\"><path d=\"M12.736 3.97a.733.733 0 0 1 1.047 0c.286.289.29.756.01 1.05L7.88 12.01a.733.733 0 0 1-1.065.02L3.217 8.384a.757.757 0 0 1 0-1.06.733.733 0 0 1 1.047 0l3.052 3.093 5.4-6.425z\"/></svg>"; 467 string MainsvgOutStock = "<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"25\" height=\"25\" fill=\"#CA0D0D\" class=\"bi bi-x-lg\" viewBox=\"0 0 16 16\"><path d=\"M4.646 4.646a.5.5 0 0 1 .708 0L8 7.293l2.646-2.647a.5.5 0 0 1 .708.708L8.707 8l2.647 2.646a.5.5 0 0 1-.708.708L8 8.707l-2.646 2.647a.5.5 0 0 1-.708-.708L7.293 8 4.646 5.354a.5.5 0 0 1 0-.708\"/></svg>"; 468 469 string MaininfoStock = "<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"16\" height=\"16\" fill=\"currentColor\" class=\"bi bi-info-circle-fill\" viewBox=\"0 0 16 16\"><path d=\"M8 16A8 8 0 1 0 8 0a8 8 0 0 0 0 16m.93-9.412-1 4.705c-.07.34.029.533.304.533.194 0 .487-.07.686-.246l-.088.416c-.287.346-.92.598-1.465.598-.703 0-1.002-.422-.808-1.319l.738-3.468c.064-.293.006-.399-.287-.47l-.451-.081.082-.381 2.29-.287zM8 5.5a1 1 0 1 1 0-2 1 1 0 0 1 0 2\" /></svg>"; 470 string MainisNew = MainVariant?.ProductFieldValues?.GetProductFieldValue("New")?.Value?.ToString().ToLower() ?? ""; 471 string MainisNewSvg = "<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"16\" height=\"16\" fill=\"#F2C400\" class=\"bi bi-star-fill\" viewBox=\"0 0 16 16\"><path d = \"M3.612 15.443c-.386.198-.824-.149-.746-.592l.83-4.73L.173 6.765c-.329-.314-.158-.888.283-.95l4.898-.696L7.538.792c.197-.39.73-.39.927 0l2.184 4.327 4.898.696c.441.062.612.636.282.95l-3.522 3.356.83 4.73c.078.443-.36.79-.746.592L8 13.187l-4.389 2.256z\" /></svg> "; 472 string MainstockState = ""; 473 string MainIsSale = MainVariant?.ProductFieldValues?.GetProductFieldValue("Sale")?.Value?.ToString().ToLower() ?? ""; 474 string MainIsSaleSvg = "<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"16\" height=\"16\" fill=\"#F03232\" class=\"bi bi-star-fill\" viewBox=\"0 0 16 16\"><path d = \"M3.612 15.443c-.386.198-.824-.149-.746-.592l.83-4.73L.173 6.765c-.329-.314-.158-.888.283-.95l4.898-.696L7.538.792c.197-.39.73-.39.927 0l2.184 4.327 4.898.696c.441.062.612.636.282.95l-3.522 3.356.83 4.73c.078.443-.36.79-.746.592L8 13.187l-4.389 2.256z\" /></svg> "; 475 string MainexpectedDeliveryDate = ""; 476 477 if (DateTime.Compare(MainVariant.ExpectedDelivery, new DateTime(1900, 1, 1)) != 0) //In DW, if the Date is not set, it is defaulted 01-01-1900 and not null.. 478 { 479 MainexpectedDeliveryDate = MainVariant.ExpectedDelivery.ToShortDateString(); 480 } 481 482 string MainexpectedDeliveryDateText = !String.IsNullOrWhiteSpace(MainexpectedDeliveryDate) ? Translate("Verwacht:") + "&nbsp;" + MainexpectedDeliveryDate : ""; 483 484 @if (!(bool?)MainVariant.ProductFieldValues.Where(o => o.ProductField.SystemName == "ProductToBeDiscontinued").SingleOrDefault()?.Value ?? false) 485 { 486 if (MainvariantStock > 0) 487 { 488 if (MainisNew == "true" || MainIsSale == "true") 489 { 490 if (MainIsSale == "true") 491 { 492 MainstockState += MainIsSaleSvg + "&nbsp; &nbsp;" + Translate("Sale!") + "<br/>"; 493 } 494 495 if (MainisNew == "true") 496 { 497 MainstockState += MainisNewSvg + "&nbsp; &nbsp;" + Translate("New!") + "<br/>"; 498 } 499 500 MainstockState += "&nbsp;" + Translate("Nu leverbaar"); 501 } 502 else 503 { 504 MainstockState = MainsvgInStock + "&nbsp; " + Translate("Op voorraad"); 505 506 } 507 } 508 else 509 { 510 MainstockState = MainsvgOutStock + "&nbsp;" + Translate("Geen voorraad") + "<br/>" + MainexpectedDeliveryDateText; 511 512 } 513 } 514 else 515 { 516 517 MainstockState = MainsvgOutStock + "&nbsp;" + Translate("Discontinued:") + "<br/>" + MainvariantStock + "&nbsp;" + @Translate("left in stock"); 518 519 } 520 /*End stock state*/ 521 522 523 @MainstockState 524 525 526 } 527 </div> 528 } 529 else 530 { 531 <div class="stock-state pt-2 mt-auto"> 532 @MainOutStock @Translate("Discontinued") 533 </div> 534 } 535 <div class="custom-price mt-auto"> 536 @{ 537 538 539 540 541 bool isErpConnectionDown = !Dynamicweb.Core.Converter.ToBoolean(Dynamicweb.Context.Current.Items["IsWebServiceConnectionAvailable"]); 542 bool hidePrice = anonymousUsersLimitations.Contains("price") && anonymousUser || Pageview.AreaSettings.GetBoolean("ErpDownHidePrices") && isErpConnectionDown; 543 544 bool productIsDiscontinued = product is object && product.Discontinued; 545 bool doNotShowPriceIfProductIsDiscontinued = Model.Item.GetBoolean("DoNotShowPriceIfProductIsDiscontinued"); 546 var isDiscontinued = productIsDiscontinued && doNotShowPriceIfProductIsDiscontinued; 547 } 548 549 @if (product is object && !hidePrice && !isDiscontinued) 550 { 551 string unitId = !string.IsNullOrEmpty(Dynamicweb.Context.Current.Request.Form.Get("UnitId")) ? Dynamicweb.Context.Current.Request.Form.Get("UnitId") : string.Empty; 552 553 string priceFontSize = Model.Item.GetRawValueString("PriceSize", "fs-4"); 554 string horizontalAlign = Model.Item.GetRawValueString("HorizontalAlignment", ""); 555 string layout = Model.Item.GetRawValueString("Layout", "horizontal"); 556 string textAlign = horizontalAlign == "center" ? "text-center" : string.Empty; 557 textAlign = horizontalAlign == "end" ? "text-end" : textAlign; 558 559 horizontalAlign = horizontalAlign == "center" && layout == "horizontal" ? "justify-content-center" : horizontalAlign; 560 horizontalAlign = horizontalAlign == "end" && layout == "horizontal" ? "justify-content-end" : horizontalAlign; 561 horizontalAlign = horizontalAlign == "center" && layout == "vertical" ? "align-items-center" : horizontalAlign; 562 horizontalAlign = horizontalAlign == "end" && layout == "vertical" ? "align-items-end" : horizontalAlign; 563 564 string flexDirection = layout == "horizontal" ? string.Empty : "flex-column"; 565 string flexGap = layout == "horizontal" ? "gap-3" : string.Empty; 566 string order = layout == "horizontal" ? string.Empty : "order-2"; 567 568 569 string contentPadding = Model.Item.GetRawValueString("ContentPadding", ""); 570 contentPadding = contentPadding == "none" ? "p-0" : contentPadding; 571 contentPadding = contentPadding == "small" ? "p-1 px-md-2 py-md-1" : contentPadding; 572 contentPadding = contentPadding == "large" ? "p-2 px-md-3 py-md-2" : contentPadding; 573 string liveInfoClass = ""; 574 575 576 577 578 579 580 if (isLazyLoadingForProductInfoEnabled) 581 { 582 if (Dynamicweb.Context.Current.Items.Contains("ProductInfoFeed")) 583 { 584 productInfoFeed = Dynamicweb.Context.Current.Items["ProductInfoFeed"]?.ToString(); 585 if (!string.IsNullOrEmpty(productInfoFeed)) 586 { 587 productInfoFeed = $"data-product-info-feed=\"{productInfoFeed}\""; 588 } 589 } 590 liveInfoClass = "js-live-info"; 591 } 592 593 <div class="@textAlign @liveInfoClass item_@Model.Item.SystemName.ToLower()" data-product-id="@product.Id" data-variant-id="@product.VariantId" @productInfoFeed> 594 @if (showInformativePrice && product.PriceInformative.Price != 0) 595 { 596 <div class="opacity-50"> 597 <span>@Translate("RRP") </span> 598 <span class="text-decoration-line-through text-price">@product.PriceInformative.PriceFormatted</span> 599 </div> 600 } 601 <div class="@priceFontSize m-0 d-flex flex-wrap @flexDirection @flexGap @horizontalAlign" style="row-gap: 0 !important" itemprop="offers" itemscope itemtype="https://schema.org/Offer"> 602 <span itemprop="priceCurrency" content="@product.Price.CurrencyCode" class="d-none"></span> 603 604 605 @if (showPricesWithVat == "false" && !neverShowVat) 606 { 607 if (isLazyLoadingForProductInfoEnabled && !Pageview.IsVisualEditorMode) 608 { 609 <span itemprop="price" content="" class="d-none"></span> 610 <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> 611 } 612 else 613 { 614 string beforePrice = !string.IsNullOrEmpty(unitId) ? product.GetPrice(unitId).PriceBeforeDiscount.PriceWithoutVatFormatted : product.PriceBeforeDiscount.PriceWithoutVatFormatted; 615 616 <span itemprop="price" content="@product.Price.PriceWithoutVat.ToString("0.00", System.Globalization.CultureInfo.InvariantCulture)" class="d-none"></span> 617 if (product.Price.Price != product.PriceBeforeDiscount.Price) 618 { 619 <span class="text-decoration-line-through opacity-75 @order">@beforePrice</span> 620 } 621 } 622 } 623 else 624 { 625 if (isLazyLoadingForProductInfoEnabled && !Pageview.IsVisualEditorMode) 626 { 627 <span itemprop="price" content="" class="d-none"></span> 628 <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> 629 } 630 else 631 { 632 string beforePrice = !string.IsNullOrEmpty(unitId) ? product.GetPrice(unitId).PriceBeforeDiscount.PriceFormatted : product.PriceBeforeDiscount.PriceFormatted; 633 634 <span itemprop="price" content="@product.Price.Price.ToString("0.00", System.Globalization.CultureInfo.InvariantCulture)" class="d-none"></span> 635 636 if (product.Price.Price != product.PriceBeforeDiscount.Price) 637 { 638 <span class="text-decoration-line-through opacity-75 @order"> 639 <span class="text-price">@beforePrice</span> 640 </span> 641 } 642 } 643 } 644 645 @if (showPricesWithVat == "false" && !neverShowVat) 646 { 647 if (isLazyLoadingForProductInfoEnabled && !Pageview.IsVisualEditorMode) 648 { 649 <span class="text-price js-text-price"> 650 <span class="spinner-border" role="status"></span> 651 </span> 652 } 653 else 654 { 655 string price = !string.IsNullOrEmpty(unitId) ? product.GetPrice(unitId).Price.PriceWithoutVatFormatted : product.Price.PriceWithoutVatFormatted; 656 657 if (product?.VariantInfo?.VariantInfo != null) 658 { 659 priceMin = product?.VariantInfo?.PriceMin?.PriceWithoutVatFormatted != null ? product.VariantInfo.PriceMin.PriceWithoutVatFormatted : ""; 660 priceMax = product?.VariantInfo?.PriceMax?.PriceWithoutVatFormatted != null ? product.VariantInfo.PriceMax.PriceWithoutVatFormatted : ""; 661 } 662 if (priceMin != priceMax) 663 { 664 price = priceMin + " - " + priceMax; 665 } 666 <span class="@theme @contentPadding"> 667 <span class="text-price">@price</span> 668 </span> 669 } 670 } 671 else 672 { 673 if (isLazyLoadingForProductInfoEnabled && !Pageview.IsVisualEditorMode) 674 { 675 <span class="text-price js-text-price"> 676 <span class="spinner-border" role="status"></span> 677 </span> 678 } 679 else 680 { 681 string price = !string.IsNullOrEmpty(unitId) ? product.GetPrice(unitId).Price.PriceFormatted : product.Price.PriceFormatted; 682 683 if (product?.VariantInfo?.VariantInfo != null) 684 { 685 priceMin = product?.VariantInfo?.PriceMin?.PriceFormatted != null ? product.VariantInfo.PriceMin.PriceFormatted : ""; 686 priceMax = product?.VariantInfo?.PriceMax?.PriceFormatted != null ? product.VariantInfo.PriceMax.PriceFormatted : ""; 687 } 688 if (priceMin != priceMax) 689 { 690 price = priceMin + " - " + priceMax; 691 } 692 <span class="@theme @contentPadding"> 693 <span class="text-price">@price</span> 694 </span> 695 } 696 } 697 698 @* Stock state for Schema.org, start *@ 699 @{ 700 Uri url = Dynamicweb.Context.Current.Request.Url; 701 } 702 703 <link itemprop="url" href="@url"> 704 705 @{ 706 bool IsNeverOutOfStock = product.NeverOutOfstock; 707 } 708 709 @if (IsNeverOutOfStock) 710 { 711 <span itemprop="availability" class="d-none">@Translate("Available in stock")</span> 712 } 713 else 714 { 715 if (product.StockLevel > 0) 716 { 717 <span itemprop="availability" class="d-none">InStock</span> 718 } 719 else 720 { 721 <span itemprop="availability" class="d-none">OutOfStock</span> 722 } 723 } 724 @* Stock state for Schema.org, stop *@ 725 726 </div> 727 728 @if (showPricesWithVat == "false" && !neverShowVat) 729 { 730 if (isLazyLoadingForProductInfoEnabled && !Pageview.IsVisualEditorMode) 731 { 732 <small class="opacity-85 fst-normal js-text-price-with-vat d-none" data-suffix="@Translate("Incl. VAT")"></small> 733 } 734 else 735 { 736 string price = !string.IsNullOrEmpty(unitId) ? product.GetPrice(unitId).Price.PriceWithVatFormatted : product.Price.PriceWithVatFormatted; 737 738 if (product?.VariantInfo?.VariantInfo != null) 739 { 740 priceMin = product?.VariantInfo?.PriceMin?.PriceWithVatFormatted != null ? product.VariantInfo.PriceMin.PriceWithVatFormatted : ""; 741 priceMax = product?.VariantInfo?.PriceMax?.PriceWithVatFormatted != null ? product.VariantInfo.PriceMax.PriceWithVatFormatted : ""; 742 } 743 if (priceMin != priceMax) 744 { 745 price = priceMin + " - " + priceMax; 746 } 747 <!-- <small class="opacity-85 fst-normal">@price @Translate("Incl. VAT")</small> --> 748 } 749 } 750 </div> 751 } 752 else if (Pageview.IsVisualEditorMode) 753 { 754 <div class="alert alert-dark m-0" role="alert"> 755 <span>@Translate("No products available")</span> 756 </div> 757 } 758 759 </div> 760 } 761 } 762
Tischlampe beam
Error executing template "Designs/Swift/Paragraph/CustomProductSlider.cshtml"
System.NullReferenceException: Object reference not set to an instance of an object.
   at CompiledRazorTemplates.Dynamic.RazorEngine_3562354021b44d5c892fe73dc2806e4f.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 Dynamicweb.Ecommerce.ProductCatalog 3 @using Dynamicweb.Ecommerce.CustomerExperienceCenter.Favorites 4 @using Dynamicweb.Files 5 @using System.IO 6 @using System.Net 7 @using Dynamicweb.Security.UserManagement 8 9 10 @{ 11 ProductViewModel product = null; 12 if (Dynamicweb.Context.Current.Items.Contains("ProductDetails")) 13 { 14 product = (ProductViewModel)Dynamicweb.Context.Current.Items["ProductDetails"]; 15 } 16 else if (Pageview.Page.Item["DummyProduct"] != null && Pageview.IsVisualEditorMode) 17 { 18 var pageViewModel = Dynamicweb.Frontend.ContentViewModelFactory.CreatePageInfoViewModel(Pageview.Page); 19 ProductListViewModel productList = pageViewModel.Item.GetValue("DummyProduct") != null ? pageViewModel.Item.GetValue("DummyProduct") as ProductListViewModel : new ProductListViewModel(); 20 21 if (productList?.Products is object) 22 { 23 product = productList.Products[0]; 24 } 25 } 26 } 27 28 @{ 29 var currentUser = Pageview?.User; 30 var customerNumber = !string.IsNullOrEmpty(currentUser?.CustomerNumber) 31 ? currentUser.CustomerNumber 32 : ""; 33 } 34 @if (product is object) 35 { 36 string imagePath = product?.DefaultImage?.Value ?? ""; 37 string imagePathUrlEncoded = Dynamicweb.Context.Current.Server.UrlEncode(imagePath); 38 39 string ratio = Model.Item.GetRawValueString("ImageAspectRatio", ""); 40 ratio = ratio != "0" ? ratio : ""; 41 string ratioCssClass = ratio != "" ? " ratio" : ""; 42 string ratioVariable = ratio != "" ? "--bs-aspect-ratio: " + ratio + ";" : ""; 43 44 string width = Model.Item.GetRawValueString("Width", "auto"); 45 int smallImageSize = 640; 46 int largeImageSize = width == "auto" ? 1280 : Convert.ToInt32(width); 47 48 string ImageObjectFit = Model.Item.GetRawValueString("ImageObjectFit", "contain"); 49 50 string imagePathXs = "/Admin/Public/GetImage.ashx?width=" + smallImageSize + "&image=" + imagePathUrlEncoded + "&format=webp"; 51 string imagePathS = "/Admin/Public/GetImage.ashx?width=" + largeImageSize + "&image=" + imagePathUrlEncoded + "&format=webp"; 52 string imagePathFallBack = "/Admin/Public/GetImage.ashx?width=" + largeImageSize + "&image=" + imagePathUrlEncoded + "&format=webp"; 53 54 var badgeParms = new Dictionary<string, object>(); 55 badgeParms.Add("size", "h7"); 56 badgeParms.Add("saleBadgeType", Model.Item.GetRawValue("SaleBadgeType")); 57 badgeParms.Add("saleBadgeCssClassName", Model.Item.GetRawValue("SaleBadgeDesign")); 58 badgeParms.Add("newBadgeCssClassName", Model.Item.GetRawValue("NewBadgeDesign")); 59 badgeParms.Add("newPublicationDays", Model.Item.GetInt32("NewPublicationDays")); 60 badgeParms.Add("campaignBadgesValues", Model.Item.GetList("CampaignBadges")?.GetRawValue().OfType<string>().ToList()); 61 62 string badgeSize = Model.Item.GetRawValueString("BadgeSize", "fs-2"); 63 bool saleBadgeEnabled = !string.IsNullOrWhiteSpace(Model.Item.GetRawValueString("SaleBadgeDesign")) && Model.Item.GetRawValueString("SaleBadgeDesign") != "none" ? true : false; 64 bool newBadgeEnabled = !string.IsNullOrWhiteSpace(Model.Item.GetRawValueString("NewBadgeDesign")) && Model.Item.GetRawValueString("NewBadgeDesign") != "none" ? true : false; 65 66 /*Custom badge*/ 67 var productService = new Dynamicweb.Ecommerce.Products.ProductService(); 68 var currency = Dynamicweb.Ecommerce.Common.Context.Currency.Code; 69 var formatProvider = new System.Globalization.NumberFormatInfo(); 70 formatProvider.NumberDecimalSeparator = "."; 71 formatProvider.NumberGroupSeparator = ","; 72 var MainVariant = productService.GetProductById(product.Id, product.VariantId, false); 73 var fieldValueBlocked = MainVariant?.ProductFieldValues?.GetProductFieldValue("BlockedCustomerList")?.Value; 74 75 76 string isNewProduct = MainVariant?.ProductFieldValues?.GetProductFieldValue("New")?.Value?.ToString().ToLower() ?? ""; 77 string MainisSale = MainVariant?.ProductFieldValues?.GetProductFieldValue("Sale")?.Value?.ToString().ToLower() ?? ""; 78 bool showNewBadge = isNewProduct == "true" ? true : false; 79 bool showSaleBadge = MainisSale == "true" ? true : false; 80 string showNewSaleBadge = "d-none"; 81 if (showSaleBadge) 82 { 83 badgeParms.Add("isSale", "true"); 84 85 } 86 else 87 { 88 badgeParms.Add("isSale", "false"); 89 } 90 if (showNewBadge) 91 { 92 badgeParms.Add("isNew", "true"); 93 } 94 else 95 { 96 badgeParms.Add("isNew", "false"); 97 } 98 /*End Custom badge*/ 99 if (showSaleBadge || showNewBadge) 100 { 101 showNewSaleBadge = ""; 102 } 103 DateTime createdDate = product.Created.Value; 104 bool showBadges = saleBadgeEnabled && product.Discount.Price != 0 ? true : false; 105 106 bool showFavoritesSelector = !string.IsNullOrEmpty(Model.Item.GetString("ShowAddToFavorites")) ? Model.Item.GetBoolean("ShowAddToFavorites") : false; 107 string anonymousUsersLimitations = Pageview.AreaSettings.GetRawValueString("AnonymousUsers", ""); 108 bool anonymousUser = Pageview.User == null; 109 110 var favoriteParameters = new Dictionary<string, object>(); 111 if (!anonymousUser && showFavoritesSelector) 112 { 113 int defaultFavoriteListId = 0; 114 115 IEnumerable<FavoriteList> favoreiteLists = Pageview.User.GetFavoriteLists(); 116 if (favoreiteLists.Count() == 1) 117 { 118 foreach (FavoriteList list in favoreiteLists) 119 { 120 defaultFavoriteListId = list.ListId; 121 } 122 } 123 124 favoriteParameters.Add("ListId", defaultFavoriteListId); 125 } 126 127 MediaViewModel alternativeImage = new MediaViewModel(); 128 if (Model.Item.GetBoolean("ShowAlternativeImageOnHover")) 129 { 130 var selectedImageCategories = Model.Item.GetList("GetAlternativeImageFrom")?.GetRawValue().OfType<string>().ToList(); 131 List<MediaViewModel> allAssetsImages = product.AssetCategories.Where(x => selectedImageCategories.Contains(x.SystemName)).SelectMany(x => x.Assets).ToList(); 132 allAssetsImages.RemoveAll(x => x.Value == product.DefaultImage.Value); 133 alternativeImage = allAssetsImages.FirstOrDefault(); 134 } 135 136 string altImagePathXs = string.Empty; 137 string altImagePathS = string.Empty; 138 139 if (!string.IsNullOrEmpty(alternativeImage?.Value)) 140 { 141 altImagePathXs = "/Admin/Public/GetImage.ashx?width=" + smallImageSize + "&image=" + Dynamicweb.Context.Current.Server.UrlEncode(alternativeImage.Value) + "&format=webp"; 142 altImagePathS = "/Admin/Public/GetImage.ashx?width=" + largeImageSize + "&image=" + Dynamicweb.Context.Current.Server.UrlEncode(alternativeImage.Value) + "&format=webp"; 143 } 144 145 @* Theme settings *@ 146 string theme = !string.IsNullOrWhiteSpace(Model.Item.GetRawValueString("Theme")) ? " theme " + Model.Item.GetRawValueString("Theme").Replace(" ", "").Trim().ToLower() : ""; 147 string themeBorder = !string.IsNullOrWhiteSpace(theme) ? "border: 1px solid rgba(0,0,0,0)" : ""; 148 string themePadding = !string.IsNullOrWhiteSpace(theme) ? "p-2 p-lg-3" : ""; 149 150 string imageId = "ProductImage_" + product.Id; 151 152 153 154 string fullWidth = width == "auto" ? "w-100" : ""; 155 string customWidth = width != "auto" ? "style=\"width: " + width + "px\"" : "style=\"min-width: 60px\""; 156 157 string altImageZindex = Model.Item.GetBoolean("ShowAlternativeImageOnHover") && !string.IsNullOrEmpty(alternativeImage?.Value) ? " z-index: 1" : string.Empty; 158 string groupid = !string.IsNullOrEmpty(Dynamicweb.Context.Current.Request.QueryString.Get("GroupID")) ? Dynamicweb.Context.Current.Request.QueryString.Get("GroupID"):"" ; 159 string link = product.GetProductLink(GetPageIdByNavigationTag("Shop"), false); 160 var productVariantGroups = product.VariantGroups(); 161 string MainOutStock = "<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"25\" height=\"25\" fill=\"#CA0D0D\" class=\"bi bi-x-lg\" viewBox=\"0 0 16 16\"><path d=\"M4.646 4.646a.5.5 0 0 1 .708 0L8 7.293l2.646-2.647a.5.5 0 0 1 .708.708L8.707 8l2.647 2.646a.5.5 0 0 1-.708.708L8 8.707l-2.646 2.647a.5.5 0 0 1-.708-.708L7.293 8 4.646 5.354a.5.5 0 0 1 0-.708\"/></svg>"; 162 163 @if (!string.IsNullOrEmpty(imagePath)) 164 { 165 <div class="@fullWidth @theme position-relative item_@Model.Item.SystemName.ToLower() main-image-container" @customWidth> 166 <div class="" style="@(ratioVariable)@(altImageZindex)"> 167 <div class="d-flex justify-content-center align-items-center"> 168 <a class="main-link-link" href="@link"> 169 @if (imagePath.StartsWith("/Files/", StringComparison.OrdinalIgnoreCase)) 170 { 171 <img id="@imageId" 172 srcset=" 173 @imagePathXs @(smallImageSize)w, 174 @imagePathS @(largeImageSize)w" 175 sizes="(max-width: 992px) 50vw, 25vw" 176 src="@imagePathFallBack" 177 loading="lazy" 178 decoding="async" 179 class="h-100 w-100 @themePadding main-image" 180 style="object-fit: @ImageObjectFit; @themeBorder " 181 alt="@product.Name" 182 itemprop="image"> 183 } 184 else 185 { 186 <img src="@product.DefaultImage.Value" 187 loading="lazy" 188 class="h-100 w-100 @themePadding main-image" 189 style="object-fit: contain; @themeBorder" 190 alt="@product.Name" 191 itemprop="image"> 192 } 193 </a> 194 </div> 195 </div> 196 197 <div class="position-absolute top-0 left-0 p-2 pb-0 custom-badge-product-list @showNewSaleBadge"> 198 @{ 199 @RenderPartial("Components/Custom_EcommerceBadge.cshtml", product, badgeParms) 200 } 201 </div> 202 203 204 </div> 205 } 206 207 <div class="product-info h-100"> 208 <div class="fs-7 pt-1 opacity-85 start item_@Model.Item.SystemName.ToLower() product-number" itemprop="sku">@product.Id / @product.VariantId - @product.VariantName</div> 209 <div class="py-2" data-col-size="12"> 210 <h2 class="h6 start m-0 item_swift_productheader product-name" itemprop="name"><b>@product.Name</b></h2> 211 </div> 212 </div> 213 var sliderId = $"thumb-scroll-{product.Id}"; 214 if (productVariantGroups.Any() && product?.VariantInfo?.VariantInfo != null) 215 216 { 217 @using Dynamicweb.Ecommerce.Prices 218 @{ 219 string[] variantId = product.VariantId.Split('.'); 220 string showPricesWithVat = Pageview.Area.EcomPricesWithVat.ToLower(); 221 bool neverShowVat = string.IsNullOrEmpty(showPricesWithVat); 222 bool showInformativePrice = Model.Item.GetBoolean("ShowInformativePrice"); 223 string productInfoFeed = ""; 224 bool isLazyLoadingForProductInfoEnabled = Dynamicweb.Core.Converter.ToBoolean(Dynamicweb.Context.Current.Items["IsLazyLoadingForProductInfoEnabled"]); 225 if (isLazyLoadingForProductInfoEnabled) 226 { 227 if (Dynamicweb.Context.Current.Items.Contains("ProductInfoFeed")) 228 { 229 productInfoFeed = Dynamicweb.Context.Current.Items["ProductInfoFeed"]?.ToString(); 230 if (!string.IsNullOrEmpty(productInfoFeed)) 231 { 232 productInfoFeed =productInfoFeed; 233 } 234 } 235 236 } 237 string priceMin = ""; 238 string priceMax = ""; 239 int groupNumber = 1; 240 241 242 243 244 string baseUrl = $"Default.aspx?ID={GetPageIdByNavigationTag("Shop")}&GroupID={product.PrimaryOrDefaultGroup.Id}&ProductID={product.Id}"; 245 if (!string.IsNullOrEmpty(baseUrl)) 246 { 247 baseUrl = $"/{baseUrl.TrimStart('/')}"; 248 } 249 string variantUrl = string.Empty; 250 251 252 Dictionary<string, string> 253 variantImages = new Dictionary<string, string> 254 (); 255 <div class="last-row mt-auto"> 256 257 @foreach (var variantGroup in productVariantGroups) 258 { 259 <div class="thumbnail-wrapper"> 260 <button class="thumb-nav prev" onclick="scrollThumbs('@sliderId', -1)"> 261 <svg width="20px" height="20px" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" fill="#1D98A5"> 262 263 <g stroke="none" stroke-width="1" fill="none" fill-rule="evenodd"> 264 <g transform="translate(-336.000000, 0.000000)"> 265 <g id="left_line" transform="translate(336.000000, 0.000000)"> 266 <path d="M24,0 L24,24 L0,24 L0,0 L24,0 Z M12.5934901,23.257841 L12.5819402,23.2595131 L12.5108777,23.2950439 L12.4918791,23.2987469 L12.4918791,23.2987469 L12.4767152,23.2950439 L12.4056548,23.2595131 C12.3958229,23.2563662 12.3870493,23.2590235 12.3821421,23.2649074 L12.3780323,23.275831 L12.360941,23.7031097 L12.3658947,23.7234994 L12.3769048,23.7357139 L12.4804777,23.8096931 L12.4953491,23.8136134 L12.4953491,23.8136134 L12.5071152,23.8096931 L12.6106902,23.7357139 L12.6232938,23.7196733 L12.6232938,23.7196733 L12.6266527,23.7031097 L12.609561,23.275831 C12.6075724,23.2657013 12.6010112,23.2592993 12.5934901,23.257841 L12.5934901,23.257841 Z M12.8583906,23.1452862 L12.8445485,23.1473072 L12.6598443,23.2396597 L12.6498822,23.2499052 L12.6498822,23.2499052 L12.6471943,23.2611114 L12.6650943,23.6906389 L12.6699349,23.7034178 L12.6699349,23.7034178 L12.678386,23.7104931 L12.8793402,23.8032389 C12.8914285,23.8068999 12.9022333,23.8029875 12.9078286,23.7952264 L12.9118235,23.7811639 L12.8776777,23.1665331 C12.8752882,23.1545897 12.8674102,23.1470016 12.8583906,23.1452862 L12.8583906,23.1452862 Z M12.1430473,23.1473072 C12.1332178,23.1423925 12.1221763,23.1452606 12.1156365,23.1525954 L12.1099173,23.1665331 L12.0757714,23.7811639 C12.0751323,23.7926639 12.0828099,23.8018602 12.0926481,23.8045676 L12.108256,23.8032389 L12.3092106,23.7104931 L12.3186497,23.7024347 L12.3186497,23.7024347 L12.3225043,23.6906389 L12.340401,23.2611114 L12.337245,23.2485176 L12.337245,23.2485176 L12.3277531,23.2396597 L12.1430473,23.1473072 Z" id="MingCute" fill-rule="nonzero"> </path> 267 <path d="M8.29292,12.7071 C7.9024,12.3166 7.9024,11.6834 8.29292,11.2929 L13.9498,5.63604 C14.3403,5.24551 14.9735,5.24551 15.364,5.63604 C15.7545,6.02656 15.7545,6.65973 15.364,7.05025 L10.4142,12 L15.364,16.9497 C15.7545,17.3403 15.7545,17.9734 15.364,18.364 C14.9735,18.7545 14.3403,18.7545 13.9498,18.364 L8.29292,12.7071 Z" id="路径" fill="#1D98A5"> </path> 268 </g> 269 </g> 270 </g> 271 </svg> 272 273 </button> 274 <div class="thumbnail-scroll" id="@sliderId"> 275 @{ 276 VariantGroupViewModel group = variantGroup; 277 foreach (var option in group.Options.OrderBy(o => o.Id)) 278 { 279 var productVariant = productService.GetProductById(product.Id, option.Id, false); 280 281 var productSelection = new PriceProductSelection(productVariant, null, 0); 282 283 var currencyCode = string.IsNullOrWhiteSpace(Pageview.User.Currency) ? Pageview.Area.EcomCurrencyId : Pageview.User.Currency; 284 var countryCode = string.IsNullOrWhiteSpace(Pageview.User.CountryCode) ? Pageview.Area.EcomCountryCode : Pageview.User.CountryCode; 285 286 var userCurrency = Dynamicweb.Ecommerce.Services.Currencies.GetCurrency(currencyCode); 287 var userCountry = Dynamicweb.Ecommerce.Services.Countries.GetCountry(countryCode); 288 289 var priceContext = new PriceContext(userCurrency, userCountry, null, Pageview.User, false, null); 290 var productPrice = Dynamicweb.Ecommerce.Services.Prices.FindPrices(priceContext, productSelection, false); 291 292 //throw new Exception(System.Text.Json.JsonSerializer.Serialize(productPrice)); 293 294 var fieldValue = productVariant?.ProductFieldValues?.GetProductFieldValue("BlockedCustomerList")?.Value; 295 296 if ((fieldValue != null && !fieldValue.ToString().Contains(customerNumber)) || String.IsNullOrWhiteSpace(customerNumber)) 297 { 298 299 300 string active = variantId != null && variantId.Contains(option.Id) ? "active" : string.Empty; 301 string buttonId = $"{product.Id}_{option.Id}_{Pageview.CurrentParagraph.ID}"; 302 string contrastColor = string.Empty; 303 304 string searchKey = $"{product.Id}_{option.Id}_"; 305 /*Images*/ 306 var imagePathVariant = option.Image?.Value ?? ""; 307 308 309 var folderPath = Path.GetDirectoryName(imagePathVariant); 310 311 string physicalFolderPath = Dynamicweb.Context.Current.Server.MapPath(folderPath); 312 313 string lastImage = null; 314 315 if (Directory.Exists(physicalFolderPath)) 316 { 317 318 var fileWith15 = Directory.GetFiles(physicalFolderPath) 319 .FirstOrDefault(f => Path.GetFileName(f).Contains($"{product.Id}_{option.Id}_9")); 320 321 if (fileWith15 != null) 322 { 323 lastImage = fileWith15; 324 } 325 else 326 { 327 var files = Directory.GetFiles(physicalFolderPath) 328 .Where(f => Path.GetFileName(f).StartsWith($"{product.Id}_{option.Id}_")) 329 .OrderByDescending(f => 330 { 331 var filename = Path.GetFileNameWithoutExtension(f); 332 var match = System.Text.RegularExpressions.Regex.Match(filename, @"_(\d+)$"); 333 if (match.Success && int.TryParse(match.Groups[1].Value, out int index)) 334 { 335 return index; 336 } 337 return 0; 338 }) 339 .ToList(); 340 341 if (files.Any()) 342 { 343 lastImage = files.First(); 344 } 345 } 346 } 347 348 var lastImageUrl = lastImage != null ? lastImage : "/Files/Images/zijlstra/Afbeeldingen_overig/Coming_Soon.jpg"; 349 int index = lastImageUrl.IndexOf("Files"); 350 string relativePath = index >= 0 ? lastImageUrl.Substring(index).Replace("\\", "/") : lastImageUrl.Replace("\\", "/"); 351 lastImageUrl = "/" + relativePath; 352 lastImageUrl = Dynamicweb.Context.Current.Server.UrlEncode(lastImageUrl); 353 var variantImg = option.Image is object ? Dynamicweb.Context.Current.Server.UrlEncode(option.Image.Value) : null; 354 var variantLink = "/Default.aspx?ID=" + GetPageIdByNavigationTag("Shop") + "&GroupID=" + product.PrimaryOrDefaultGroup.Id + "&ProductID=" + product.Id + "&VariantID=" + option.Id; 355 356 string variantImage = string.Empty; 357 variantImages.TryGetValue(option.Id, out variantImage); 358 /*End Images*/ 359 360 /*stock state*/ 361 double variantStock = productVariant.Stock; 362 string svgInStock = "<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"16\" height=\"16\" fill=\"#44B11A\" class=\"bi bi-check-lg\" viewBox=\"0 0 16 16\"><path d=\"M12.736 3.97a.733.733 0 0 1 1.047 0c.286.289.29.756.01 1.05L7.88 12.01a.733.733 0 0 1-1.065.02L3.217 8.384a.757.757 0 0 1 0-1.06.733.733 0 0 1 1.047 0l3.052 3.093 5.4-6.425z\"/></svg>"; 363 string svgOutStock = "<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"25\" height=\"25\" fill=\"#CA0D0D\" class=\"bi bi-x-lg\" viewBox=\"0 0 16 16\"><path d=\"M4.646 4.646a.5.5 0 0 1 .708 0L8 7.293l2.646-2.647a.5.5 0 0 1 .708.708L8.707 8l2.647 2.646a.5.5 0 0 1-.708.708L8 8.707l-2.646 2.647a.5.5 0 0 1-.708-.708L7.293 8 4.646 5.354a.5.5 0 0 1 0-.708\"/></svg>"; 364 365 string infoStock = "<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"16\" height=\"16\" fill=\"currentColor\" class=\"bi bi-info-circle-fill\" viewBox=\"0 0 16 16\"><path d=\"M8 16A8 8 0 1 0 8 0a8 8 0 0 0 0 16m.93-9.412-1 4.705c-.07.34.029.533.304.533.194 0 .487-.07.686-.246l-.088.416c-.287.346-.92.598-1.465.598-.703 0-1.002-.422-.808-1.319l.738-3.468c.064-.293.006-.399-.287-.47l-.451-.081.082-.381 2.29-.287zM8 5.5a1 1 0 1 1 0-2 1 1 0 0 1 0 2\" /></svg>"; 366 string isNew = productVariant?.ProductFieldValues?.GetProductFieldValue("New")?.Value?.ToString().ToLower() ?? ""; 367 string isNewSvg = "<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"16\" height=\"16\" fill=\"#F2C400\" class=\"bi bi-star-fill\" viewBox=\"0 0 16 16\"><path d = \"M3.612 15.443c-.386.198-.824-.149-.746-.592l.83-4.73L.173 6.765c-.329-.314-.158-.888.283-.95l4.898-.696L7.538.792c.197-.39.73-.39.927 0l2.184 4.327 4.898.696c.441.062.612.636.282.95l-3.522 3.356.83 4.73c.078.443-.36.79-.746.592L8 13.187l-4.389 2.256z\" /></svg> "; 368 string stockState = ""; 369 370 string isSale = productVariant?.ProductFieldValues?.GetProductFieldValue("Sale")?.Value?.ToString().ToLower() ?? ""; 371 string isSaleSvg = "<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"16\" height=\"16\" fill=\"#F03232\" class=\"bi bi-star-fill\" viewBox=\"0 0 16 16\"><path d = \"M3.612 15.443c-.386.198-.824-.149-.746-.592l.83-4.73L.173 6.765c-.329-.314-.158-.888.283-.95l4.898-.696L7.538.792c.197-.39.73-.39.927 0l2.184 4.327 4.898.696c.441.062.612.636.282.95l-3.522 3.356.83 4.73c.078.443-.36.79-.746.592L8 13.187l-4.389 2.256z\" /></svg> "; 372 373 string expectedDeliveryDate = ""; 374 375 if (DateTime.Compare(productVariant.ExpectedDelivery, new DateTime(1900, 1, 1)) != 0) //In DW, if the Date is not set, it is defaulted 01-01-1900 and not null.. 376 { 377 expectedDeliveryDate = productVariant.ExpectedDelivery.ToShortDateString(); 378 } 379 380 string expectedDeliveryDateText = !String.IsNullOrWhiteSpace(expectedDeliveryDate) ? Translate("Verwacht:") + "&nbsp;" + expectedDeliveryDate : ""; 381 382 @if (!(bool?)productVariant.ProductFieldValues.Where(o => o.ProductField.SystemName == "ProductToBeDiscontinued").SingleOrDefault()?.Value ?? false) 383 { 384 if (variantStock > 0) 385 { 386 if (isNew == "true" || isSale == "true") 387 { 388 if (isSale == "true") 389 { 390 stockState += isSaleSvg + "&nbsp; &nbsp;" + Translate("Sale!") + "<br/>"; 391 } 392 393 if (isNew == "true") 394 { 395 stockState += isNewSvg + "&nbsp; &nbsp;" + Translate("New!") + "<br/>"; 396 } 397 398 stockState += "&nbsp;" + Translate("Nu leverbaar"); 399 } 400 else 401 { 402 stockState = svgInStock + "&nbsp; " + Translate("Op voorraad"); 403 404 } 405 } 406 else 407 { 408 stockState = svgOutStock + "&nbsp;" + Translate("Geen voorraad") + "<br/>" + expectedDeliveryDateText; 409 410 } 411 } 412 else 413 { 414 415 stockState = svgOutStock + "&nbsp;" + Translate("Discontinued:") + "<br/>" + variantStock + "&nbsp;" + @Translate("left in stock"); 416 417 } 418 /*End stock state*/ 419 /*Price variants*/ 420 double price = productVariant.DefaultPrice; 421 double cost = productVariant.Cost; 422 423 string priceFormated = Dynamicweb.Ecommerce.Services.Currencies.Format(Dynamicweb.Ecommerce.Services.Currencies.GetCurrency(currency), Convert.ToDouble(productPrice.ToList()[0].Amount, formatProvider)); 424 //string priceFormated = Dynamicweb.Ecommerce.Services.Currencies.Format(Dynamicweb.Ecommerce.Services.Currencies.GetCurrency(currency), Convert.ToDouble(price, formatProvider)); 425 426 427 428 /*End Price variants*/ 429 430 <img class="theme thumbnail" data-stockstate="@WebUtility.HtmlEncode(stockState)" src="/Admin/Public/GetImage.ashx?image=@(lastImageUrl)&width=64&format=webp" onclick="selectVariant('@(product.Id)','/Admin/Public/GetImage.ashx?image=@(variantImg)&format=webp','@variantLink','@product.Id','@option.Id','@option.Name',this.dataset.stockstate,'@isNew','@isSale','@priceFormated','@cost')" /> 431 432 433 } 434 } 435 436 } 437 </div> 438 <button class="thumb-nav next" onclick="scrollThumbs('@sliderId', 1)"> 439 <svg width="20px" height="20px" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" fill="#1D98A5"> 440 441 <g stroke="none" stroke-width="1" fill="none" fill-rule="evenodd"> 442 <g transform="translate(-384.000000, 0.000000)"> 443 <g id="right_line" transform="translate(384.000000, 0.000000)"> 444 <path d="M24,0 L24,24 L0,24 L0,0 L24,0 Z M12.5934901,23.257841 L12.5819402,23.2595131 L12.5108777,23.2950439 L12.4918791,23.2987469 L12.4918791,23.2987469 L12.4767152,23.2950439 L12.4056548,23.2595131 C12.3958229,23.2563662 12.3870493,23.2590235 12.3821421,23.2649074 L12.3780323,23.275831 L12.360941,23.7031097 L12.3658947,23.7234994 L12.3769048,23.7357139 L12.4804777,23.8096931 L12.4953491,23.8136134 L12.4953491,23.8136134 L12.5071152,23.8096931 L12.6106902,23.7357139 L12.6232938,23.7196733 L12.6232938,23.7196733 L12.6266527,23.7031097 L12.609561,23.275831 C12.6075724,23.2657013 12.6010112,23.2592993 12.5934901,23.257841 L12.5934901,23.257841 Z M12.8583906,23.1452862 L12.8445485,23.1473072 L12.6598443,23.2396597 L12.6498822,23.2499052 L12.6498822,23.2499052 L12.6471943,23.2611114 L12.6650943,23.6906389 L12.6699349,23.7034178 L12.6699349,23.7034178 L12.678386,23.7104931 L12.8793402,23.8032389 C12.8914285,23.8068999 12.9022333,23.8029875 12.9078286,23.7952264 L12.9118235,23.7811639 L12.8776777,23.1665331 C12.8752882,23.1545897 12.8674102,23.1470016 12.8583906,23.1452862 L12.8583906,23.1452862 Z M12.1430473,23.1473072 C12.1332178,23.1423925 12.1221763,23.1452606 12.1156365,23.1525954 L12.1099173,23.1665331 L12.0757714,23.7811639 C12.0751323,23.7926639 12.0828099,23.8018602 12.0926481,23.8045676 L12.108256,23.8032389 L12.3092106,23.7104931 L12.3186497,23.7024347 L12.3186497,23.7024347 L12.3225043,23.6906389 L12.340401,23.2611114 L12.337245,23.2485176 L12.337245,23.2485176 L12.3277531,23.2396597 L12.1430473,23.1473072 Z" id="MingCute" fill-rule="nonzero"> </path> 445 <path d="M15.7072,11.2929 C16.0977,11.6834 16.0977,12.3166 15.7072,12.7071 L10.0503,18.364 C9.65982,18.7545 9.02666,18.7545 8.63613,18.364 C8.24561,17.9734 8.24561,17.3403 8.63613,16.9497 L13.5859,12 L8.63613,7.05025 C8.24561,6.65973 8.24561,6.02656 8.63613,5.63604 C9.02666,5.24551 9.65982,5.24551 10.0503,5.63604 L15.7072,11.2929 Z" id="路径" fill="#1D98A5"> </path> 446 </g> 447 </g> 448 449 </svg> 450 451 </button> 452 </div> 453 } 454 455 456 </div> 457 458 } 459 if ((fieldValueBlocked != null && !fieldValueBlocked.ToString().Contains(customerNumber)) || String.IsNullOrWhiteSpace(customerNumber)) 460 { 461 <div class="stock-state pt-2 mt-auto"> 462 @{ 463 464 /*stock state*/ 465 double MainvariantStock = MainVariant.Stock; 466 string MainsvgInStock = "<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"16\" height=\"16\" fill=\"#44B11A\" class=\"bi bi-check-lg\" viewBox=\"0 0 16 16\"><path d=\"M12.736 3.97a.733.733 0 0 1 1.047 0c.286.289.29.756.01 1.05L7.88 12.01a.733.733 0 0 1-1.065.02L3.217 8.384a.757.757 0 0 1 0-1.06.733.733 0 0 1 1.047 0l3.052 3.093 5.4-6.425z\"/></svg>"; 467 string MainsvgOutStock = "<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"25\" height=\"25\" fill=\"#CA0D0D\" class=\"bi bi-x-lg\" viewBox=\"0 0 16 16\"><path d=\"M4.646 4.646a.5.5 0 0 1 .708 0L8 7.293l2.646-2.647a.5.5 0 0 1 .708.708L8.707 8l2.647 2.646a.5.5 0 0 1-.708.708L8 8.707l-2.646 2.647a.5.5 0 0 1-.708-.708L7.293 8 4.646 5.354a.5.5 0 0 1 0-.708\"/></svg>"; 468 469 string MaininfoStock = "<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"16\" height=\"16\" fill=\"currentColor\" class=\"bi bi-info-circle-fill\" viewBox=\"0 0 16 16\"><path d=\"M8 16A8 8 0 1 0 8 0a8 8 0 0 0 0 16m.93-9.412-1 4.705c-.07.34.029.533.304.533.194 0 .487-.07.686-.246l-.088.416c-.287.346-.92.598-1.465.598-.703 0-1.002-.422-.808-1.319l.738-3.468c.064-.293.006-.399-.287-.47l-.451-.081.082-.381 2.29-.287zM8 5.5a1 1 0 1 1 0-2 1 1 0 0 1 0 2\" /></svg>"; 470 string MainisNew = MainVariant?.ProductFieldValues?.GetProductFieldValue("New")?.Value?.ToString().ToLower() ?? ""; 471 string MainisNewSvg = "<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"16\" height=\"16\" fill=\"#F2C400\" class=\"bi bi-star-fill\" viewBox=\"0 0 16 16\"><path d = \"M3.612 15.443c-.386.198-.824-.149-.746-.592l.83-4.73L.173 6.765c-.329-.314-.158-.888.283-.95l4.898-.696L7.538.792c.197-.39.73-.39.927 0l2.184 4.327 4.898.696c.441.062.612.636.282.95l-3.522 3.356.83 4.73c.078.443-.36.79-.746.592L8 13.187l-4.389 2.256z\" /></svg> "; 472 string MainstockState = ""; 473 string MainIsSale = MainVariant?.ProductFieldValues?.GetProductFieldValue("Sale")?.Value?.ToString().ToLower() ?? ""; 474 string MainIsSaleSvg = "<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"16\" height=\"16\" fill=\"#F03232\" class=\"bi bi-star-fill\" viewBox=\"0 0 16 16\"><path d = \"M3.612 15.443c-.386.198-.824-.149-.746-.592l.83-4.73L.173 6.765c-.329-.314-.158-.888.283-.95l4.898-.696L7.538.792c.197-.39.73-.39.927 0l2.184 4.327 4.898.696c.441.062.612.636.282.95l-3.522 3.356.83 4.73c.078.443-.36.79-.746.592L8 13.187l-4.389 2.256z\" /></svg> "; 475 string MainexpectedDeliveryDate = ""; 476 477 if (DateTime.Compare(MainVariant.ExpectedDelivery, new DateTime(1900, 1, 1)) != 0) //In DW, if the Date is not set, it is defaulted 01-01-1900 and not null.. 478 { 479 MainexpectedDeliveryDate = MainVariant.ExpectedDelivery.ToShortDateString(); 480 } 481 482 string MainexpectedDeliveryDateText = !String.IsNullOrWhiteSpace(MainexpectedDeliveryDate) ? Translate("Verwacht:") + "&nbsp;" + MainexpectedDeliveryDate : ""; 483 484 @if (!(bool?)MainVariant.ProductFieldValues.Where(o => o.ProductField.SystemName == "ProductToBeDiscontinued").SingleOrDefault()?.Value ?? false) 485 { 486 if (MainvariantStock > 0) 487 { 488 if (MainisNew == "true" || MainIsSale == "true") 489 { 490 if (MainIsSale == "true") 491 { 492 MainstockState += MainIsSaleSvg + "&nbsp; &nbsp;" + Translate("Sale!") + "<br/>"; 493 } 494 495 if (MainisNew == "true") 496 { 497 MainstockState += MainisNewSvg + "&nbsp; &nbsp;" + Translate("New!") + "<br/>"; 498 } 499 500 MainstockState += "&nbsp;" + Translate("Nu leverbaar"); 501 } 502 else 503 { 504 MainstockState = MainsvgInStock + "&nbsp; " + Translate("Op voorraad"); 505 506 } 507 } 508 else 509 { 510 MainstockState = MainsvgOutStock + "&nbsp;" + Translate("Geen voorraad") + "<br/>" + MainexpectedDeliveryDateText; 511 512 } 513 } 514 else 515 { 516 517 MainstockState = MainsvgOutStock + "&nbsp;" + Translate("Discontinued:") + "<br/>" + MainvariantStock + "&nbsp;" + @Translate("left in stock"); 518 519 } 520 /*End stock state*/ 521 522 523 @MainstockState 524 525 526 } 527 </div> 528 } 529 else 530 { 531 <div class="stock-state pt-2 mt-auto"> 532 @MainOutStock @Translate("Discontinued") 533 </div> 534 } 535 <div class="custom-price mt-auto"> 536 @{ 537 538 539 540 541 bool isErpConnectionDown = !Dynamicweb.Core.Converter.ToBoolean(Dynamicweb.Context.Current.Items["IsWebServiceConnectionAvailable"]); 542 bool hidePrice = anonymousUsersLimitations.Contains("price") && anonymousUser || Pageview.AreaSettings.GetBoolean("ErpDownHidePrices") && isErpConnectionDown; 543 544 bool productIsDiscontinued = product is object && product.Discontinued; 545 bool doNotShowPriceIfProductIsDiscontinued = Model.Item.GetBoolean("DoNotShowPriceIfProductIsDiscontinued"); 546 var isDiscontinued = productIsDiscontinued && doNotShowPriceIfProductIsDiscontinued; 547 } 548 549 @if (product is object && !hidePrice && !isDiscontinued) 550 { 551 string unitId = !string.IsNullOrEmpty(Dynamicweb.Context.Current.Request.Form.Get("UnitId")) ? Dynamicweb.Context.Current.Request.Form.Get("UnitId") : string.Empty; 552 553 string priceFontSize = Model.Item.GetRawValueString("PriceSize", "fs-4"); 554 string horizontalAlign = Model.Item.GetRawValueString("HorizontalAlignment", ""); 555 string layout = Model.Item.GetRawValueString("Layout", "horizontal"); 556 string textAlign = horizontalAlign == "center" ? "text-center" : string.Empty; 557 textAlign = horizontalAlign == "end" ? "text-end" : textAlign; 558 559 horizontalAlign = horizontalAlign == "center" && layout == "horizontal" ? "justify-content-center" : horizontalAlign; 560 horizontalAlign = horizontalAlign == "end" && layout == "horizontal" ? "justify-content-end" : horizontalAlign; 561 horizontalAlign = horizontalAlign == "center" && layout == "vertical" ? "align-items-center" : horizontalAlign; 562 horizontalAlign = horizontalAlign == "end" && layout == "vertical" ? "align-items-end" : horizontalAlign; 563 564 string flexDirection = layout == "horizontal" ? string.Empty : "flex-column"; 565 string flexGap = layout == "horizontal" ? "gap-3" : string.Empty; 566 string order = layout == "horizontal" ? string.Empty : "order-2"; 567 568 569 string contentPadding = Model.Item.GetRawValueString("ContentPadding", ""); 570 contentPadding = contentPadding == "none" ? "p-0" : contentPadding; 571 contentPadding = contentPadding == "small" ? "p-1 px-md-2 py-md-1" : contentPadding; 572 contentPadding = contentPadding == "large" ? "p-2 px-md-3 py-md-2" : contentPadding; 573 string liveInfoClass = ""; 574 575 576 577 578 579 580 if (isLazyLoadingForProductInfoEnabled) 581 { 582 if (Dynamicweb.Context.Current.Items.Contains("ProductInfoFeed")) 583 { 584 productInfoFeed = Dynamicweb.Context.Current.Items["ProductInfoFeed"]?.ToString(); 585 if (!string.IsNullOrEmpty(productInfoFeed)) 586 { 587 productInfoFeed = $"data-product-info-feed=\"{productInfoFeed}\""; 588 } 589 } 590 liveInfoClass = "js-live-info"; 591 } 592 593 <div class="@textAlign @liveInfoClass item_@Model.Item.SystemName.ToLower()" data-product-id="@product.Id" data-variant-id="@product.VariantId" @productInfoFeed> 594 @if (showInformativePrice && product.PriceInformative.Price != 0) 595 { 596 <div class="opacity-50"> 597 <span>@Translate("RRP") </span> 598 <span class="text-decoration-line-through text-price">@product.PriceInformative.PriceFormatted</span> 599 </div> 600 } 601 <div class="@priceFontSize m-0 d-flex flex-wrap @flexDirection @flexGap @horizontalAlign" style="row-gap: 0 !important" itemprop="offers" itemscope itemtype="https://schema.org/Offer"> 602 <span itemprop="priceCurrency" content="@product.Price.CurrencyCode" class="d-none"></span> 603 604 605 @if (showPricesWithVat == "false" && !neverShowVat) 606 { 607 if (isLazyLoadingForProductInfoEnabled && !Pageview.IsVisualEditorMode) 608 { 609 <span itemprop="price" content="" class="d-none"></span> 610 <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> 611 } 612 else 613 { 614 string beforePrice = !string.IsNullOrEmpty(unitId) ? product.GetPrice(unitId).PriceBeforeDiscount.PriceWithoutVatFormatted : product.PriceBeforeDiscount.PriceWithoutVatFormatted; 615 616 <span itemprop="price" content="@product.Price.PriceWithoutVat.ToString("0.00", System.Globalization.CultureInfo.InvariantCulture)" class="d-none"></span> 617 if (product.Price.Price != product.PriceBeforeDiscount.Price) 618 { 619 <span class="text-decoration-line-through opacity-75 @order">@beforePrice</span> 620 } 621 } 622 } 623 else 624 { 625 if (isLazyLoadingForProductInfoEnabled && !Pageview.IsVisualEditorMode) 626 { 627 <span itemprop="price" content="" class="d-none"></span> 628 <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> 629 } 630 else 631 { 632 string beforePrice = !string.IsNullOrEmpty(unitId) ? product.GetPrice(unitId).PriceBeforeDiscount.PriceFormatted : product.PriceBeforeDiscount.PriceFormatted; 633 634 <span itemprop="price" content="@product.Price.Price.ToString("0.00", System.Globalization.CultureInfo.InvariantCulture)" class="d-none"></span> 635 636 if (product.Price.Price != product.PriceBeforeDiscount.Price) 637 { 638 <span class="text-decoration-line-through opacity-75 @order"> 639 <span class="text-price">@beforePrice</span> 640 </span> 641 } 642 } 643 } 644 645 @if (showPricesWithVat == "false" && !neverShowVat) 646 { 647 if (isLazyLoadingForProductInfoEnabled && !Pageview.IsVisualEditorMode) 648 { 649 <span class="text-price js-text-price"> 650 <span class="spinner-border" role="status"></span> 651 </span> 652 } 653 else 654 { 655 string price = !string.IsNullOrEmpty(unitId) ? product.GetPrice(unitId).Price.PriceWithoutVatFormatted : product.Price.PriceWithoutVatFormatted; 656 657 if (product?.VariantInfo?.VariantInfo != null) 658 { 659 priceMin = product?.VariantInfo?.PriceMin?.PriceWithoutVatFormatted != null ? product.VariantInfo.PriceMin.PriceWithoutVatFormatted : ""; 660 priceMax = product?.VariantInfo?.PriceMax?.PriceWithoutVatFormatted != null ? product.VariantInfo.PriceMax.PriceWithoutVatFormatted : ""; 661 } 662 if (priceMin != priceMax) 663 { 664 price = priceMin + " - " + priceMax; 665 } 666 <span class="@theme @contentPadding"> 667 <span class="text-price">@price</span> 668 </span> 669 } 670 } 671 else 672 { 673 if (isLazyLoadingForProductInfoEnabled && !Pageview.IsVisualEditorMode) 674 { 675 <span class="text-price js-text-price"> 676 <span class="spinner-border" role="status"></span> 677 </span> 678 } 679 else 680 { 681 string price = !string.IsNullOrEmpty(unitId) ? product.GetPrice(unitId).Price.PriceFormatted : product.Price.PriceFormatted; 682 683 if (product?.VariantInfo?.VariantInfo != null) 684 { 685 priceMin = product?.VariantInfo?.PriceMin?.PriceFormatted != null ? product.VariantInfo.PriceMin.PriceFormatted : ""; 686 priceMax = product?.VariantInfo?.PriceMax?.PriceFormatted != null ? product.VariantInfo.PriceMax.PriceFormatted : ""; 687 } 688 if (priceMin != priceMax) 689 { 690 price = priceMin + " - " + priceMax; 691 } 692 <span class="@theme @contentPadding"> 693 <span class="text-price">@price</span> 694 </span> 695 } 696 } 697 698 @* Stock state for Schema.org, start *@ 699 @{ 700 Uri url = Dynamicweb.Context.Current.Request.Url; 701 } 702 703 <link itemprop="url" href="@url"> 704 705 @{ 706 bool IsNeverOutOfStock = product.NeverOutOfstock; 707 } 708 709 @if (IsNeverOutOfStock) 710 { 711 <span itemprop="availability" class="d-none">@Translate("Available in stock")</span> 712 } 713 else 714 { 715 if (product.StockLevel > 0) 716 { 717 <span itemprop="availability" class="d-none">InStock</span> 718 } 719 else 720 { 721 <span itemprop="availability" class="d-none">OutOfStock</span> 722 } 723 } 724 @* Stock state for Schema.org, stop *@ 725 726 </div> 727 728 @if (showPricesWithVat == "false" && !neverShowVat) 729 { 730 if (isLazyLoadingForProductInfoEnabled && !Pageview.IsVisualEditorMode) 731 { 732 <small class="opacity-85 fst-normal js-text-price-with-vat d-none" data-suffix="@Translate("Incl. VAT")"></small> 733 } 734 else 735 { 736 string price = !string.IsNullOrEmpty(unitId) ? product.GetPrice(unitId).Price.PriceWithVatFormatted : product.Price.PriceWithVatFormatted; 737 738 if (product?.VariantInfo?.VariantInfo != null) 739 { 740 priceMin = product?.VariantInfo?.PriceMin?.PriceWithVatFormatted != null ? product.VariantInfo.PriceMin.PriceWithVatFormatted : ""; 741 priceMax = product?.VariantInfo?.PriceMax?.PriceWithVatFormatted != null ? product.VariantInfo.PriceMax.PriceWithVatFormatted : ""; 742 } 743 if (priceMin != priceMax) 744 { 745 price = priceMin + " - " + priceMax; 746 } 747 <!-- <small class="opacity-85 fst-normal">@price @Translate("Incl. VAT")</small> --> 748 } 749 } 750 </div> 751 } 752 else if (Pageview.IsVisualEditorMode) 753 { 754 <div class="alert alert-dark m-0" role="alert"> 755 <span>@Translate("No products available")</span> 756 </div> 757 } 758 759 </div> 760 } 761 } 762
Tischlampe full moon
Error executing template "Designs/Swift/Paragraph/CustomProductSlider.cshtml"
System.NullReferenceException: Object reference not set to an instance of an object.
   at CompiledRazorTemplates.Dynamic.RazorEngine_3562354021b44d5c892fe73dc2806e4f.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 Dynamicweb.Ecommerce.ProductCatalog 3 @using Dynamicweb.Ecommerce.CustomerExperienceCenter.Favorites 4 @using Dynamicweb.Files 5 @using System.IO 6 @using System.Net 7 @using Dynamicweb.Security.UserManagement 8 9 10 @{ 11 ProductViewModel product = null; 12 if (Dynamicweb.Context.Current.Items.Contains("ProductDetails")) 13 { 14 product = (ProductViewModel)Dynamicweb.Context.Current.Items["ProductDetails"]; 15 } 16 else if (Pageview.Page.Item["DummyProduct"] != null && Pageview.IsVisualEditorMode) 17 { 18 var pageViewModel = Dynamicweb.Frontend.ContentViewModelFactory.CreatePageInfoViewModel(Pageview.Page); 19 ProductListViewModel productList = pageViewModel.Item.GetValue("DummyProduct") != null ? pageViewModel.Item.GetValue("DummyProduct") as ProductListViewModel : new ProductListViewModel(); 20 21 if (productList?.Products is object) 22 { 23 product = productList.Products[0]; 24 } 25 } 26 } 27 28 @{ 29 var currentUser = Pageview?.User; 30 var customerNumber = !string.IsNullOrEmpty(currentUser?.CustomerNumber) 31 ? currentUser.CustomerNumber 32 : ""; 33 } 34 @if (product is object) 35 { 36 string imagePath = product?.DefaultImage?.Value ?? ""; 37 string imagePathUrlEncoded = Dynamicweb.Context.Current.Server.UrlEncode(imagePath); 38 39 string ratio = Model.Item.GetRawValueString("ImageAspectRatio", ""); 40 ratio = ratio != "0" ? ratio : ""; 41 string ratioCssClass = ratio != "" ? " ratio" : ""; 42 string ratioVariable = ratio != "" ? "--bs-aspect-ratio: " + ratio + ";" : ""; 43 44 string width = Model.Item.GetRawValueString("Width", "auto"); 45 int smallImageSize = 640; 46 int largeImageSize = width == "auto" ? 1280 : Convert.ToInt32(width); 47 48 string ImageObjectFit = Model.Item.GetRawValueString("ImageObjectFit", "contain"); 49 50 string imagePathXs = "/Admin/Public/GetImage.ashx?width=" + smallImageSize + "&image=" + imagePathUrlEncoded + "&format=webp"; 51 string imagePathS = "/Admin/Public/GetImage.ashx?width=" + largeImageSize + "&image=" + imagePathUrlEncoded + "&format=webp"; 52 string imagePathFallBack = "/Admin/Public/GetImage.ashx?width=" + largeImageSize + "&image=" + imagePathUrlEncoded + "&format=webp"; 53 54 var badgeParms = new Dictionary<string, object>(); 55 badgeParms.Add("size", "h7"); 56 badgeParms.Add("saleBadgeType", Model.Item.GetRawValue("SaleBadgeType")); 57 badgeParms.Add("saleBadgeCssClassName", Model.Item.GetRawValue("SaleBadgeDesign")); 58 badgeParms.Add("newBadgeCssClassName", Model.Item.GetRawValue("NewBadgeDesign")); 59 badgeParms.Add("newPublicationDays", Model.Item.GetInt32("NewPublicationDays")); 60 badgeParms.Add("campaignBadgesValues", Model.Item.GetList("CampaignBadges")?.GetRawValue().OfType<string>().ToList()); 61 62 string badgeSize = Model.Item.GetRawValueString("BadgeSize", "fs-2"); 63 bool saleBadgeEnabled = !string.IsNullOrWhiteSpace(Model.Item.GetRawValueString("SaleBadgeDesign")) && Model.Item.GetRawValueString("SaleBadgeDesign") != "none" ? true : false; 64 bool newBadgeEnabled = !string.IsNullOrWhiteSpace(Model.Item.GetRawValueString("NewBadgeDesign")) && Model.Item.GetRawValueString("NewBadgeDesign") != "none" ? true : false; 65 66 /*Custom badge*/ 67 var productService = new Dynamicweb.Ecommerce.Products.ProductService(); 68 var currency = Dynamicweb.Ecommerce.Common.Context.Currency.Code; 69 var formatProvider = new System.Globalization.NumberFormatInfo(); 70 formatProvider.NumberDecimalSeparator = "."; 71 formatProvider.NumberGroupSeparator = ","; 72 var MainVariant = productService.GetProductById(product.Id, product.VariantId, false); 73 var fieldValueBlocked = MainVariant?.ProductFieldValues?.GetProductFieldValue("BlockedCustomerList")?.Value; 74 75 76 string isNewProduct = MainVariant?.ProductFieldValues?.GetProductFieldValue("New")?.Value?.ToString().ToLower() ?? ""; 77 string MainisSale = MainVariant?.ProductFieldValues?.GetProductFieldValue("Sale")?.Value?.ToString().ToLower() ?? ""; 78 bool showNewBadge = isNewProduct == "true" ? true : false; 79 bool showSaleBadge = MainisSale == "true" ? true : false; 80 string showNewSaleBadge = "d-none"; 81 if (showSaleBadge) 82 { 83 badgeParms.Add("isSale", "true"); 84 85 } 86 else 87 { 88 badgeParms.Add("isSale", "false"); 89 } 90 if (showNewBadge) 91 { 92 badgeParms.Add("isNew", "true"); 93 } 94 else 95 { 96 badgeParms.Add("isNew", "false"); 97 } 98 /*End Custom badge*/ 99 if (showSaleBadge || showNewBadge) 100 { 101 showNewSaleBadge = ""; 102 } 103 DateTime createdDate = product.Created.Value; 104 bool showBadges = saleBadgeEnabled && product.Discount.Price != 0 ? true : false; 105 106 bool showFavoritesSelector = !string.IsNullOrEmpty(Model.Item.GetString("ShowAddToFavorites")) ? Model.Item.GetBoolean("ShowAddToFavorites") : false; 107 string anonymousUsersLimitations = Pageview.AreaSettings.GetRawValueString("AnonymousUsers", ""); 108 bool anonymousUser = Pageview.User == null; 109 110 var favoriteParameters = new Dictionary<string, object>(); 111 if (!anonymousUser && showFavoritesSelector) 112 { 113 int defaultFavoriteListId = 0; 114 115 IEnumerable<FavoriteList> favoreiteLists = Pageview.User.GetFavoriteLists(); 116 if (favoreiteLists.Count() == 1) 117 { 118 foreach (FavoriteList list in favoreiteLists) 119 { 120 defaultFavoriteListId = list.ListId; 121 } 122 } 123 124 favoriteParameters.Add("ListId", defaultFavoriteListId); 125 } 126 127 MediaViewModel alternativeImage = new MediaViewModel(); 128 if (Model.Item.GetBoolean("ShowAlternativeImageOnHover")) 129 { 130 var selectedImageCategories = Model.Item.GetList("GetAlternativeImageFrom")?.GetRawValue().OfType<string>().ToList(); 131 List<MediaViewModel> allAssetsImages = product.AssetCategories.Where(x => selectedImageCategories.Contains(x.SystemName)).SelectMany(x => x.Assets).ToList(); 132 allAssetsImages.RemoveAll(x => x.Value == product.DefaultImage.Value); 133 alternativeImage = allAssetsImages.FirstOrDefault(); 134 } 135 136 string altImagePathXs = string.Empty; 137 string altImagePathS = string.Empty; 138 139 if (!string.IsNullOrEmpty(alternativeImage?.Value)) 140 { 141 altImagePathXs = "/Admin/Public/GetImage.ashx?width=" + smallImageSize + "&image=" + Dynamicweb.Context.Current.Server.UrlEncode(alternativeImage.Value) + "&format=webp"; 142 altImagePathS = "/Admin/Public/GetImage.ashx?width=" + largeImageSize + "&image=" + Dynamicweb.Context.Current.Server.UrlEncode(alternativeImage.Value) + "&format=webp"; 143 } 144 145 @* Theme settings *@ 146 string theme = !string.IsNullOrWhiteSpace(Model.Item.GetRawValueString("Theme")) ? " theme " + Model.Item.GetRawValueString("Theme").Replace(" ", "").Trim().ToLower() : ""; 147 string themeBorder = !string.IsNullOrWhiteSpace(theme) ? "border: 1px solid rgba(0,0,0,0)" : ""; 148 string themePadding = !string.IsNullOrWhiteSpace(theme) ? "p-2 p-lg-3" : ""; 149 150 string imageId = "ProductImage_" + product.Id; 151 152 153 154 string fullWidth = width == "auto" ? "w-100" : ""; 155 string customWidth = width != "auto" ? "style=\"width: " + width + "px\"" : "style=\"min-width: 60px\""; 156 157 string altImageZindex = Model.Item.GetBoolean("ShowAlternativeImageOnHover") && !string.IsNullOrEmpty(alternativeImage?.Value) ? " z-index: 1" : string.Empty; 158 string groupid = !string.IsNullOrEmpty(Dynamicweb.Context.Current.Request.QueryString.Get("GroupID")) ? Dynamicweb.Context.Current.Request.QueryString.Get("GroupID"):"" ; 159 string link = product.GetProductLink(GetPageIdByNavigationTag("Shop"), false); 160 var productVariantGroups = product.VariantGroups(); 161 string MainOutStock = "<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"25\" height=\"25\" fill=\"#CA0D0D\" class=\"bi bi-x-lg\" viewBox=\"0 0 16 16\"><path d=\"M4.646 4.646a.5.5 0 0 1 .708 0L8 7.293l2.646-2.647a.5.5 0 0 1 .708.708L8.707 8l2.647 2.646a.5.5 0 0 1-.708.708L8 8.707l-2.646 2.647a.5.5 0 0 1-.708-.708L7.293 8 4.646 5.354a.5.5 0 0 1 0-.708\"/></svg>"; 162 163 @if (!string.IsNullOrEmpty(imagePath)) 164 { 165 <div class="@fullWidth @theme position-relative item_@Model.Item.SystemName.ToLower() main-image-container" @customWidth> 166 <div class="" style="@(ratioVariable)@(altImageZindex)"> 167 <div class="d-flex justify-content-center align-items-center"> 168 <a class="main-link-link" href="@link"> 169 @if (imagePath.StartsWith("/Files/", StringComparison.OrdinalIgnoreCase)) 170 { 171 <img id="@imageId" 172 srcset=" 173 @imagePathXs @(smallImageSize)w, 174 @imagePathS @(largeImageSize)w" 175 sizes="(max-width: 992px) 50vw, 25vw" 176 src="@imagePathFallBack" 177 loading="lazy" 178 decoding="async" 179 class="h-100 w-100 @themePadding main-image" 180 style="object-fit: @ImageObjectFit; @themeBorder " 181 alt="@product.Name" 182 itemprop="image"> 183 } 184 else 185 { 186 <img src="@product.DefaultImage.Value" 187 loading="lazy" 188 class="h-100 w-100 @themePadding main-image" 189 style="object-fit: contain; @themeBorder" 190 alt="@product.Name" 191 itemprop="image"> 192 } 193 </a> 194 </div> 195 </div> 196 197 <div class="position-absolute top-0 left-0 p-2 pb-0 custom-badge-product-list @showNewSaleBadge"> 198 @{ 199 @RenderPartial("Components/Custom_EcommerceBadge.cshtml", product, badgeParms) 200 } 201 </div> 202 203 204 </div> 205 } 206 207 <div class="product-info h-100"> 208 <div class="fs-7 pt-1 opacity-85 start item_@Model.Item.SystemName.ToLower() product-number" itemprop="sku">@product.Id / @product.VariantId - @product.VariantName</div> 209 <div class="py-2" data-col-size="12"> 210 <h2 class="h6 start m-0 item_swift_productheader product-name" itemprop="name"><b>@product.Name</b></h2> 211 </div> 212 </div> 213 var sliderId = $"thumb-scroll-{product.Id}"; 214 if (productVariantGroups.Any() && product?.VariantInfo?.VariantInfo != null) 215 216 { 217 @using Dynamicweb.Ecommerce.Prices 218 @{ 219 string[] variantId = product.VariantId.Split('.'); 220 string showPricesWithVat = Pageview.Area.EcomPricesWithVat.ToLower(); 221 bool neverShowVat = string.IsNullOrEmpty(showPricesWithVat); 222 bool showInformativePrice = Model.Item.GetBoolean("ShowInformativePrice"); 223 string productInfoFeed = ""; 224 bool isLazyLoadingForProductInfoEnabled = Dynamicweb.Core.Converter.ToBoolean(Dynamicweb.Context.Current.Items["IsLazyLoadingForProductInfoEnabled"]); 225 if (isLazyLoadingForProductInfoEnabled) 226 { 227 if (Dynamicweb.Context.Current.Items.Contains("ProductInfoFeed")) 228 { 229 productInfoFeed = Dynamicweb.Context.Current.Items["ProductInfoFeed"]?.ToString(); 230 if (!string.IsNullOrEmpty(productInfoFeed)) 231 { 232 productInfoFeed =productInfoFeed; 233 } 234 } 235 236 } 237 string priceMin = ""; 238 string priceMax = ""; 239 int groupNumber = 1; 240 241 242 243 244 string baseUrl = $"Default.aspx?ID={GetPageIdByNavigationTag("Shop")}&GroupID={product.PrimaryOrDefaultGroup.Id}&ProductID={product.Id}"; 245 if (!string.IsNullOrEmpty(baseUrl)) 246 { 247 baseUrl = $"/{baseUrl.TrimStart('/')}"; 248 } 249 string variantUrl = string.Empty; 250 251 252 Dictionary<string, string> 253 variantImages = new Dictionary<string, string> 254 (); 255 <div class="last-row mt-auto"> 256 257 @foreach (var variantGroup in productVariantGroups) 258 { 259 <div class="thumbnail-wrapper"> 260 <button class="thumb-nav prev" onclick="scrollThumbs('@sliderId', -1)"> 261 <svg width="20px" height="20px" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" fill="#1D98A5"> 262 263 <g stroke="none" stroke-width="1" fill="none" fill-rule="evenodd"> 264 <g transform="translate(-336.000000, 0.000000)"> 265 <g id="left_line" transform="translate(336.000000, 0.000000)"> 266 <path d="M24,0 L24,24 L0,24 L0,0 L24,0 Z M12.5934901,23.257841 L12.5819402,23.2595131 L12.5108777,23.2950439 L12.4918791,23.2987469 L12.4918791,23.2987469 L12.4767152,23.2950439 L12.4056548,23.2595131 C12.3958229,23.2563662 12.3870493,23.2590235 12.3821421,23.2649074 L12.3780323,23.275831 L12.360941,23.7031097 L12.3658947,23.7234994 L12.3769048,23.7357139 L12.4804777,23.8096931 L12.4953491,23.8136134 L12.4953491,23.8136134 L12.5071152,23.8096931 L12.6106902,23.7357139 L12.6232938,23.7196733 L12.6232938,23.7196733 L12.6266527,23.7031097 L12.609561,23.275831 C12.6075724,23.2657013 12.6010112,23.2592993 12.5934901,23.257841 L12.5934901,23.257841 Z M12.8583906,23.1452862 L12.8445485,23.1473072 L12.6598443,23.2396597 L12.6498822,23.2499052 L12.6498822,23.2499052 L12.6471943,23.2611114 L12.6650943,23.6906389 L12.6699349,23.7034178 L12.6699349,23.7034178 L12.678386,23.7104931 L12.8793402,23.8032389 C12.8914285,23.8068999 12.9022333,23.8029875 12.9078286,23.7952264 L12.9118235,23.7811639 L12.8776777,23.1665331 C12.8752882,23.1545897 12.8674102,23.1470016 12.8583906,23.1452862 L12.8583906,23.1452862 Z M12.1430473,23.1473072 C12.1332178,23.1423925 12.1221763,23.1452606 12.1156365,23.1525954 L12.1099173,23.1665331 L12.0757714,23.7811639 C12.0751323,23.7926639 12.0828099,23.8018602 12.0926481,23.8045676 L12.108256,23.8032389 L12.3092106,23.7104931 L12.3186497,23.7024347 L12.3186497,23.7024347 L12.3225043,23.6906389 L12.340401,23.2611114 L12.337245,23.2485176 L12.337245,23.2485176 L12.3277531,23.2396597 L12.1430473,23.1473072 Z" id="MingCute" fill-rule="nonzero"> </path> 267 <path d="M8.29292,12.7071 C7.9024,12.3166 7.9024,11.6834 8.29292,11.2929 L13.9498,5.63604 C14.3403,5.24551 14.9735,5.24551 15.364,5.63604 C15.7545,6.02656 15.7545,6.65973 15.364,7.05025 L10.4142,12 L15.364,16.9497 C15.7545,17.3403 15.7545,17.9734 15.364,18.364 C14.9735,18.7545 14.3403,18.7545 13.9498,18.364 L8.29292,12.7071 Z" id="路径" fill="#1D98A5"> </path> 268 </g> 269 </g> 270 </g> 271 </svg> 272 273 </button> 274 <div class="thumbnail-scroll" id="@sliderId"> 275 @{ 276 VariantGroupViewModel group = variantGroup; 277 foreach (var option in group.Options.OrderBy(o => o.Id)) 278 { 279 var productVariant = productService.GetProductById(product.Id, option.Id, false); 280 281 var productSelection = new PriceProductSelection(productVariant, null, 0); 282 283 var currencyCode = string.IsNullOrWhiteSpace(Pageview.User.Currency) ? Pageview.Area.EcomCurrencyId : Pageview.User.Currency; 284 var countryCode = string.IsNullOrWhiteSpace(Pageview.User.CountryCode) ? Pageview.Area.EcomCountryCode : Pageview.User.CountryCode; 285 286 var userCurrency = Dynamicweb.Ecommerce.Services.Currencies.GetCurrency(currencyCode); 287 var userCountry = Dynamicweb.Ecommerce.Services.Countries.GetCountry(countryCode); 288 289 var priceContext = new PriceContext(userCurrency, userCountry, null, Pageview.User, false, null); 290 var productPrice = Dynamicweb.Ecommerce.Services.Prices.FindPrices(priceContext, productSelection, false); 291 292 //throw new Exception(System.Text.Json.JsonSerializer.Serialize(productPrice)); 293 294 var fieldValue = productVariant?.ProductFieldValues?.GetProductFieldValue("BlockedCustomerList")?.Value; 295 296 if ((fieldValue != null && !fieldValue.ToString().Contains(customerNumber)) || String.IsNullOrWhiteSpace(customerNumber)) 297 { 298 299 300 string active = variantId != null && variantId.Contains(option.Id) ? "active" : string.Empty; 301 string buttonId = $"{product.Id}_{option.Id}_{Pageview.CurrentParagraph.ID}"; 302 string contrastColor = string.Empty; 303 304 string searchKey = $"{product.Id}_{option.Id}_"; 305 /*Images*/ 306 var imagePathVariant = option.Image?.Value ?? ""; 307 308 309 var folderPath = Path.GetDirectoryName(imagePathVariant); 310 311 string physicalFolderPath = Dynamicweb.Context.Current.Server.MapPath(folderPath); 312 313 string lastImage = null; 314 315 if (Directory.Exists(physicalFolderPath)) 316 { 317 318 var fileWith15 = Directory.GetFiles(physicalFolderPath) 319 .FirstOrDefault(f => Path.GetFileName(f).Contains($"{product.Id}_{option.Id}_9")); 320 321 if (fileWith15 != null) 322 { 323 lastImage = fileWith15; 324 } 325 else 326 { 327 var files = Directory.GetFiles(physicalFolderPath) 328 .Where(f => Path.GetFileName(f).StartsWith($"{product.Id}_{option.Id}_")) 329 .OrderByDescending(f => 330 { 331 var filename = Path.GetFileNameWithoutExtension(f); 332 var match = System.Text.RegularExpressions.Regex.Match(filename, @"_(\d+)$"); 333 if (match.Success && int.TryParse(match.Groups[1].Value, out int index)) 334 { 335 return index; 336 } 337 return 0; 338 }) 339 .ToList(); 340 341 if (files.Any()) 342 { 343 lastImage = files.First(); 344 } 345 } 346 } 347 348 var lastImageUrl = lastImage != null ? lastImage : "/Files/Images/zijlstra/Afbeeldingen_overig/Coming_Soon.jpg"; 349 int index = lastImageUrl.IndexOf("Files"); 350 string relativePath = index >= 0 ? lastImageUrl.Substring(index).Replace("\\", "/") : lastImageUrl.Replace("\\", "/"); 351 lastImageUrl = "/" + relativePath; 352 lastImageUrl = Dynamicweb.Context.Current.Server.UrlEncode(lastImageUrl); 353 var variantImg = option.Image is object ? Dynamicweb.Context.Current.Server.UrlEncode(option.Image.Value) : null; 354 var variantLink = "/Default.aspx?ID=" + GetPageIdByNavigationTag("Shop") + "&GroupID=" + product.PrimaryOrDefaultGroup.Id + "&ProductID=" + product.Id + "&VariantID=" + option.Id; 355 356 string variantImage = string.Empty; 357 variantImages.TryGetValue(option.Id, out variantImage); 358 /*End Images*/ 359 360 /*stock state*/ 361 double variantStock = productVariant.Stock; 362 string svgInStock = "<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"16\" height=\"16\" fill=\"#44B11A\" class=\"bi bi-check-lg\" viewBox=\"0 0 16 16\"><path d=\"M12.736 3.97a.733.733 0 0 1 1.047 0c.286.289.29.756.01 1.05L7.88 12.01a.733.733 0 0 1-1.065.02L3.217 8.384a.757.757 0 0 1 0-1.06.733.733 0 0 1 1.047 0l3.052 3.093 5.4-6.425z\"/></svg>"; 363 string svgOutStock = "<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"25\" height=\"25\" fill=\"#CA0D0D\" class=\"bi bi-x-lg\" viewBox=\"0 0 16 16\"><path d=\"M4.646 4.646a.5.5 0 0 1 .708 0L8 7.293l2.646-2.647a.5.5 0 0 1 .708.708L8.707 8l2.647 2.646a.5.5 0 0 1-.708.708L8 8.707l-2.646 2.647a.5.5 0 0 1-.708-.708L7.293 8 4.646 5.354a.5.5 0 0 1 0-.708\"/></svg>"; 364 365 string infoStock = "<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"16\" height=\"16\" fill=\"currentColor\" class=\"bi bi-info-circle-fill\" viewBox=\"0 0 16 16\"><path d=\"M8 16A8 8 0 1 0 8 0a8 8 0 0 0 0 16m.93-9.412-1 4.705c-.07.34.029.533.304.533.194 0 .487-.07.686-.246l-.088.416c-.287.346-.92.598-1.465.598-.703 0-1.002-.422-.808-1.319l.738-3.468c.064-.293.006-.399-.287-.47l-.451-.081.082-.381 2.29-.287zM8 5.5a1 1 0 1 1 0-2 1 1 0 0 1 0 2\" /></svg>"; 366 string isNew = productVariant?.ProductFieldValues?.GetProductFieldValue("New")?.Value?.ToString().ToLower() ?? ""; 367 string isNewSvg = "<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"16\" height=\"16\" fill=\"#F2C400\" class=\"bi bi-star-fill\" viewBox=\"0 0 16 16\"><path d = \"M3.612 15.443c-.386.198-.824-.149-.746-.592l.83-4.73L.173 6.765c-.329-.314-.158-.888.283-.95l4.898-.696L7.538.792c.197-.39.73-.39.927 0l2.184 4.327 4.898.696c.441.062.612.636.282.95l-3.522 3.356.83 4.73c.078.443-.36.79-.746.592L8 13.187l-4.389 2.256z\" /></svg> "; 368 string stockState = ""; 369 370 string isSale = productVariant?.ProductFieldValues?.GetProductFieldValue("Sale")?.Value?.ToString().ToLower() ?? ""; 371 string isSaleSvg = "<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"16\" height=\"16\" fill=\"#F03232\" class=\"bi bi-star-fill\" viewBox=\"0 0 16 16\"><path d = \"M3.612 15.443c-.386.198-.824-.149-.746-.592l.83-4.73L.173 6.765c-.329-.314-.158-.888.283-.95l4.898-.696L7.538.792c.197-.39.73-.39.927 0l2.184 4.327 4.898.696c.441.062.612.636.282.95l-3.522 3.356.83 4.73c.078.443-.36.79-.746.592L8 13.187l-4.389 2.256z\" /></svg> "; 372 373 string expectedDeliveryDate = ""; 374 375 if (DateTime.Compare(productVariant.ExpectedDelivery, new DateTime(1900, 1, 1)) != 0) //In DW, if the Date is not set, it is defaulted 01-01-1900 and not null.. 376 { 377 expectedDeliveryDate = productVariant.ExpectedDelivery.ToShortDateString(); 378 } 379 380 string expectedDeliveryDateText = !String.IsNullOrWhiteSpace(expectedDeliveryDate) ? Translate("Verwacht:") + "&nbsp;" + expectedDeliveryDate : ""; 381 382 @if (!(bool?)productVariant.ProductFieldValues.Where(o => o.ProductField.SystemName == "ProductToBeDiscontinued").SingleOrDefault()?.Value ?? false) 383 { 384 if (variantStock > 0) 385 { 386 if (isNew == "true" || isSale == "true") 387 { 388 if (isSale == "true") 389 { 390 stockState += isSaleSvg + "&nbsp; &nbsp;" + Translate("Sale!") + "<br/>"; 391 } 392 393 if (isNew == "true") 394 { 395 stockState += isNewSvg + "&nbsp; &nbsp;" + Translate("New!") + "<br/>"; 396 } 397 398 stockState += "&nbsp;" + Translate("Nu leverbaar"); 399 } 400 else 401 { 402 stockState = svgInStock + "&nbsp; " + Translate("Op voorraad"); 403 404 } 405 } 406 else 407 { 408 stockState = svgOutStock + "&nbsp;" + Translate("Geen voorraad") + "<br/>" + expectedDeliveryDateText; 409 410 } 411 } 412 else 413 { 414 415 stockState = svgOutStock + "&nbsp;" + Translate("Discontinued:") + "<br/>" + variantStock + "&nbsp;" + @Translate("left in stock"); 416 417 } 418 /*End stock state*/ 419 /*Price variants*/ 420 double price = productVariant.DefaultPrice; 421 double cost = productVariant.Cost; 422 423 string priceFormated = Dynamicweb.Ecommerce.Services.Currencies.Format(Dynamicweb.Ecommerce.Services.Currencies.GetCurrency(currency), Convert.ToDouble(productPrice.ToList()[0].Amount, formatProvider)); 424 //string priceFormated = Dynamicweb.Ecommerce.Services.Currencies.Format(Dynamicweb.Ecommerce.Services.Currencies.GetCurrency(currency), Convert.ToDouble(price, formatProvider)); 425 426 427 428 /*End Price variants*/ 429 430 <img class="theme thumbnail" data-stockstate="@WebUtility.HtmlEncode(stockState)" src="/Admin/Public/GetImage.ashx?image=@(lastImageUrl)&width=64&format=webp" onclick="selectVariant('@(product.Id)','/Admin/Public/GetImage.ashx?image=@(variantImg)&format=webp','@variantLink','@product.Id','@option.Id','@option.Name',this.dataset.stockstate,'@isNew','@isSale','@priceFormated','@cost')" /> 431 432 433 } 434 } 435 436 } 437 </div> 438 <button class="thumb-nav next" onclick="scrollThumbs('@sliderId', 1)"> 439 <svg width="20px" height="20px" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" fill="#1D98A5"> 440 441 <g stroke="none" stroke-width="1" fill="none" fill-rule="evenodd"> 442 <g transform="translate(-384.000000, 0.000000)"> 443 <g id="right_line" transform="translate(384.000000, 0.000000)"> 444 <path d="M24,0 L24,24 L0,24 L0,0 L24,0 Z M12.5934901,23.257841 L12.5819402,23.2595131 L12.5108777,23.2950439 L12.4918791,23.2987469 L12.4918791,23.2987469 L12.4767152,23.2950439 L12.4056548,23.2595131 C12.3958229,23.2563662 12.3870493,23.2590235 12.3821421,23.2649074 L12.3780323,23.275831 L12.360941,23.7031097 L12.3658947,23.7234994 L12.3769048,23.7357139 L12.4804777,23.8096931 L12.4953491,23.8136134 L12.4953491,23.8136134 L12.5071152,23.8096931 L12.6106902,23.7357139 L12.6232938,23.7196733 L12.6232938,23.7196733 L12.6266527,23.7031097 L12.609561,23.275831 C12.6075724,23.2657013 12.6010112,23.2592993 12.5934901,23.257841 L12.5934901,23.257841 Z M12.8583906,23.1452862 L12.8445485,23.1473072 L12.6598443,23.2396597 L12.6498822,23.2499052 L12.6498822,23.2499052 L12.6471943,23.2611114 L12.6650943,23.6906389 L12.6699349,23.7034178 L12.6699349,23.7034178 L12.678386,23.7104931 L12.8793402,23.8032389 C12.8914285,23.8068999 12.9022333,23.8029875 12.9078286,23.7952264 L12.9118235,23.7811639 L12.8776777,23.1665331 C12.8752882,23.1545897 12.8674102,23.1470016 12.8583906,23.1452862 L12.8583906,23.1452862 Z M12.1430473,23.1473072 C12.1332178,23.1423925 12.1221763,23.1452606 12.1156365,23.1525954 L12.1099173,23.1665331 L12.0757714,23.7811639 C12.0751323,23.7926639 12.0828099,23.8018602 12.0926481,23.8045676 L12.108256,23.8032389 L12.3092106,23.7104931 L12.3186497,23.7024347 L12.3186497,23.7024347 L12.3225043,23.6906389 L12.340401,23.2611114 L12.337245,23.2485176 L12.337245,23.2485176 L12.3277531,23.2396597 L12.1430473,23.1473072 Z" id="MingCute" fill-rule="nonzero"> </path> 445 <path d="M15.7072,11.2929 C16.0977,11.6834 16.0977,12.3166 15.7072,12.7071 L10.0503,18.364 C9.65982,18.7545 9.02666,18.7545 8.63613,18.364 C8.24561,17.9734 8.24561,17.3403 8.63613,16.9497 L13.5859,12 L8.63613,7.05025 C8.24561,6.65973 8.24561,6.02656 8.63613,5.63604 C9.02666,5.24551 9.65982,5.24551 10.0503,5.63604 L15.7072,11.2929 Z" id="路径" fill="#1D98A5"> </path> 446 </g> 447 </g> 448 449 </svg> 450 451 </button> 452 </div> 453 } 454 455 456 </div> 457 458 } 459 if ((fieldValueBlocked != null && !fieldValueBlocked.ToString().Contains(customerNumber)) || String.IsNullOrWhiteSpace(customerNumber)) 460 { 461 <div class="stock-state pt-2 mt-auto"> 462 @{ 463 464 /*stock state*/ 465 double MainvariantStock = MainVariant.Stock; 466 string MainsvgInStock = "<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"16\" height=\"16\" fill=\"#44B11A\" class=\"bi bi-check-lg\" viewBox=\"0 0 16 16\"><path d=\"M12.736 3.97a.733.733 0 0 1 1.047 0c.286.289.29.756.01 1.05L7.88 12.01a.733.733 0 0 1-1.065.02L3.217 8.384a.757.757 0 0 1 0-1.06.733.733 0 0 1 1.047 0l3.052 3.093 5.4-6.425z\"/></svg>"; 467 string MainsvgOutStock = "<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"25\" height=\"25\" fill=\"#CA0D0D\" class=\"bi bi-x-lg\" viewBox=\"0 0 16 16\"><path d=\"M4.646 4.646a.5.5 0 0 1 .708 0L8 7.293l2.646-2.647a.5.5 0 0 1 .708.708L8.707 8l2.647 2.646a.5.5 0 0 1-.708.708L8 8.707l-2.646 2.647a.5.5 0 0 1-.708-.708L7.293 8 4.646 5.354a.5.5 0 0 1 0-.708\"/></svg>"; 468 469 string MaininfoStock = "<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"16\" height=\"16\" fill=\"currentColor\" class=\"bi bi-info-circle-fill\" viewBox=\"0 0 16 16\"><path d=\"M8 16A8 8 0 1 0 8 0a8 8 0 0 0 0 16m.93-9.412-1 4.705c-.07.34.029.533.304.533.194 0 .487-.07.686-.246l-.088.416c-.287.346-.92.598-1.465.598-.703 0-1.002-.422-.808-1.319l.738-3.468c.064-.293.006-.399-.287-.47l-.451-.081.082-.381 2.29-.287zM8 5.5a1 1 0 1 1 0-2 1 1 0 0 1 0 2\" /></svg>"; 470 string MainisNew = MainVariant?.ProductFieldValues?.GetProductFieldValue("New")?.Value?.ToString().ToLower() ?? ""; 471 string MainisNewSvg = "<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"16\" height=\"16\" fill=\"#F2C400\" class=\"bi bi-star-fill\" viewBox=\"0 0 16 16\"><path d = \"M3.612 15.443c-.386.198-.824-.149-.746-.592l.83-4.73L.173 6.765c-.329-.314-.158-.888.283-.95l4.898-.696L7.538.792c.197-.39.73-.39.927 0l2.184 4.327 4.898.696c.441.062.612.636.282.95l-3.522 3.356.83 4.73c.078.443-.36.79-.746.592L8 13.187l-4.389 2.256z\" /></svg> "; 472 string MainstockState = ""; 473 string MainIsSale = MainVariant?.ProductFieldValues?.GetProductFieldValue("Sale")?.Value?.ToString().ToLower() ?? ""; 474 string MainIsSaleSvg = "<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"16\" height=\"16\" fill=\"#F03232\" class=\"bi bi-star-fill\" viewBox=\"0 0 16 16\"><path d = \"M3.612 15.443c-.386.198-.824-.149-.746-.592l.83-4.73L.173 6.765c-.329-.314-.158-.888.283-.95l4.898-.696L7.538.792c.197-.39.73-.39.927 0l2.184 4.327 4.898.696c.441.062.612.636.282.95l-3.522 3.356.83 4.73c.078.443-.36.79-.746.592L8 13.187l-4.389 2.256z\" /></svg> "; 475 string MainexpectedDeliveryDate = ""; 476 477 if (DateTime.Compare(MainVariant.ExpectedDelivery, new DateTime(1900, 1, 1)) != 0) //In DW, if the Date is not set, it is defaulted 01-01-1900 and not null.. 478 { 479 MainexpectedDeliveryDate = MainVariant.ExpectedDelivery.ToShortDateString(); 480 } 481 482 string MainexpectedDeliveryDateText = !String.IsNullOrWhiteSpace(MainexpectedDeliveryDate) ? Translate("Verwacht:") + "&nbsp;" + MainexpectedDeliveryDate : ""; 483 484 @if (!(bool?)MainVariant.ProductFieldValues.Where(o => o.ProductField.SystemName == "ProductToBeDiscontinued").SingleOrDefault()?.Value ?? false) 485 { 486 if (MainvariantStock > 0) 487 { 488 if (MainisNew == "true" || MainIsSale == "true") 489 { 490 if (MainIsSale == "true") 491 { 492 MainstockState += MainIsSaleSvg + "&nbsp; &nbsp;" + Translate("Sale!") + "<br/>"; 493 } 494 495 if (MainisNew == "true") 496 { 497 MainstockState += MainisNewSvg + "&nbsp; &nbsp;" + Translate("New!") + "<br/>"; 498 } 499 500 MainstockState += "&nbsp;" + Translate("Nu leverbaar"); 501 } 502 else 503 { 504 MainstockState = MainsvgInStock + "&nbsp; " + Translate("Op voorraad"); 505 506 } 507 } 508 else 509 { 510 MainstockState = MainsvgOutStock + "&nbsp;" + Translate("Geen voorraad") + "<br/>" + MainexpectedDeliveryDateText; 511 512 } 513 } 514 else 515 { 516 517 MainstockState = MainsvgOutStock + "&nbsp;" + Translate("Discontinued:") + "<br/>" + MainvariantStock + "&nbsp;" + @Translate("left in stock"); 518 519 } 520 /*End stock state*/ 521 522 523 @MainstockState 524 525 526 } 527 </div> 528 } 529 else 530 { 531 <div class="stock-state pt-2 mt-auto"> 532 @MainOutStock @Translate("Discontinued") 533 </div> 534 } 535 <div class="custom-price mt-auto"> 536 @{ 537 538 539 540 541 bool isErpConnectionDown = !Dynamicweb.Core.Converter.ToBoolean(Dynamicweb.Context.Current.Items["IsWebServiceConnectionAvailable"]); 542 bool hidePrice = anonymousUsersLimitations.Contains("price") && anonymousUser || Pageview.AreaSettings.GetBoolean("ErpDownHidePrices") && isErpConnectionDown; 543 544 bool productIsDiscontinued = product is object && product.Discontinued; 545 bool doNotShowPriceIfProductIsDiscontinued = Model.Item.GetBoolean("DoNotShowPriceIfProductIsDiscontinued"); 546 var isDiscontinued = productIsDiscontinued && doNotShowPriceIfProductIsDiscontinued; 547 } 548 549 @if (product is object && !hidePrice && !isDiscontinued) 550 { 551 string unitId = !string.IsNullOrEmpty(Dynamicweb.Context.Current.Request.Form.Get("UnitId")) ? Dynamicweb.Context.Current.Request.Form.Get("UnitId") : string.Empty; 552 553 string priceFontSize = Model.Item.GetRawValueString("PriceSize", "fs-4"); 554 string horizontalAlign = Model.Item.GetRawValueString("HorizontalAlignment", ""); 555 string layout = Model.Item.GetRawValueString("Layout", "horizontal"); 556 string textAlign = horizontalAlign == "center" ? "text-center" : string.Empty; 557 textAlign = horizontalAlign == "end" ? "text-end" : textAlign; 558 559 horizontalAlign = horizontalAlign == "center" && layout == "horizontal" ? "justify-content-center" : horizontalAlign; 560 horizontalAlign = horizontalAlign == "end" && layout == "horizontal" ? "justify-content-end" : horizontalAlign; 561 horizontalAlign = horizontalAlign == "center" && layout == "vertical" ? "align-items-center" : horizontalAlign; 562 horizontalAlign = horizontalAlign == "end" && layout == "vertical" ? "align-items-end" : horizontalAlign; 563 564 string flexDirection = layout == "horizontal" ? string.Empty : "flex-column"; 565 string flexGap = layout == "horizontal" ? "gap-3" : string.Empty; 566 string order = layout == "horizontal" ? string.Empty : "order-2"; 567 568 569 string contentPadding = Model.Item.GetRawValueString("ContentPadding", ""); 570 contentPadding = contentPadding == "none" ? "p-0" : contentPadding; 571 contentPadding = contentPadding == "small" ? "p-1 px-md-2 py-md-1" : contentPadding; 572 contentPadding = contentPadding == "large" ? "p-2 px-md-3 py-md-2" : contentPadding; 573 string liveInfoClass = ""; 574 575 576 577 578 579 580 if (isLazyLoadingForProductInfoEnabled) 581 { 582 if (Dynamicweb.Context.Current.Items.Contains("ProductInfoFeed")) 583 { 584 productInfoFeed = Dynamicweb.Context.Current.Items["ProductInfoFeed"]?.ToString(); 585 if (!string.IsNullOrEmpty(productInfoFeed)) 586 { 587 productInfoFeed = $"data-product-info-feed=\"{productInfoFeed}\""; 588 } 589 } 590 liveInfoClass = "js-live-info"; 591 } 592 593 <div class="@textAlign @liveInfoClass item_@Model.Item.SystemName.ToLower()" data-product-id="@product.Id" data-variant-id="@product.VariantId" @productInfoFeed> 594 @if (showInformativePrice && product.PriceInformative.Price != 0) 595 { 596 <div class="opacity-50"> 597 <span>@Translate("RRP") </span> 598 <span class="text-decoration-line-through text-price">@product.PriceInformative.PriceFormatted</span> 599 </div> 600 } 601 <div class="@priceFontSize m-0 d-flex flex-wrap @flexDirection @flexGap @horizontalAlign" style="row-gap: 0 !important" itemprop="offers" itemscope itemtype="https://schema.org/Offer"> 602 <span itemprop="priceCurrency" content="@product.Price.CurrencyCode" class="d-none"></span> 603 604 605 @if (showPricesWithVat == "false" && !neverShowVat) 606 { 607 if (isLazyLoadingForProductInfoEnabled && !Pageview.IsVisualEditorMode) 608 { 609 <span itemprop="price" content="" class="d-none"></span> 610 <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> 611 } 612 else 613 { 614 string beforePrice = !string.IsNullOrEmpty(unitId) ? product.GetPrice(unitId).PriceBeforeDiscount.PriceWithoutVatFormatted : product.PriceBeforeDiscount.PriceWithoutVatFormatted; 615 616 <span itemprop="price" content="@product.Price.PriceWithoutVat.ToString("0.00", System.Globalization.CultureInfo.InvariantCulture)" class="d-none"></span> 617 if (product.Price.Price != product.PriceBeforeDiscount.Price) 618 { 619 <span class="text-decoration-line-through opacity-75 @order">@beforePrice</span> 620 } 621 } 622 } 623 else 624 { 625 if (isLazyLoadingForProductInfoEnabled && !Pageview.IsVisualEditorMode) 626 { 627 <span itemprop="price" content="" class="d-none"></span> 628 <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> 629 } 630 else 631 { 632 string beforePrice = !string.IsNullOrEmpty(unitId) ? product.GetPrice(unitId).PriceBeforeDiscount.PriceFormatted : product.PriceBeforeDiscount.PriceFormatted; 633 634 <span itemprop="price" content="@product.Price.Price.ToString("0.00", System.Globalization.CultureInfo.InvariantCulture)" class="d-none"></span> 635 636 if (product.Price.Price != product.PriceBeforeDiscount.Price) 637 { 638 <span class="text-decoration-line-through opacity-75 @order"> 639 <span class="text-price">@beforePrice</span> 640 </span> 641 } 642 } 643 } 644 645 @if (showPricesWithVat == "false" && !neverShowVat) 646 { 647 if (isLazyLoadingForProductInfoEnabled && !Pageview.IsVisualEditorMode) 648 { 649 <span class="text-price js-text-price"> 650 <span class="spinner-border" role="status"></span> 651 </span> 652 } 653 else 654 { 655 string price = !string.IsNullOrEmpty(unitId) ? product.GetPrice(unitId).Price.PriceWithoutVatFormatted : product.Price.PriceWithoutVatFormatted; 656 657 if (product?.VariantInfo?.VariantInfo != null) 658 { 659 priceMin = product?.VariantInfo?.PriceMin?.PriceWithoutVatFormatted != null ? product.VariantInfo.PriceMin.PriceWithoutVatFormatted : ""; 660 priceMax = product?.VariantInfo?.PriceMax?.PriceWithoutVatFormatted != null ? product.VariantInfo.PriceMax.PriceWithoutVatFormatted : ""; 661 } 662 if (priceMin != priceMax) 663 { 664 price = priceMin + " - " + priceMax; 665 } 666 <span class="@theme @contentPadding"> 667 <span class="text-price">@price</span> 668 </span> 669 } 670 } 671 else 672 { 673 if (isLazyLoadingForProductInfoEnabled && !Pageview.IsVisualEditorMode) 674 { 675 <span class="text-price js-text-price"> 676 <span class="spinner-border" role="status"></span> 677 </span> 678 } 679 else 680 { 681 string price = !string.IsNullOrEmpty(unitId) ? product.GetPrice(unitId).Price.PriceFormatted : product.Price.PriceFormatted; 682 683 if (product?.VariantInfo?.VariantInfo != null) 684 { 685 priceMin = product?.VariantInfo?.PriceMin?.PriceFormatted != null ? product.VariantInfo.PriceMin.PriceFormatted : ""; 686 priceMax = product?.VariantInfo?.PriceMax?.PriceFormatted != null ? product.VariantInfo.PriceMax.PriceFormatted : ""; 687 } 688 if (priceMin != priceMax) 689 { 690 price = priceMin + " - " + priceMax; 691 } 692 <span class="@theme @contentPadding"> 693 <span class="text-price">@price</span> 694 </span> 695 } 696 } 697 698 @* Stock state for Schema.org, start *@ 699 @{ 700 Uri url = Dynamicweb.Context.Current.Request.Url; 701 } 702 703 <link itemprop="url" href="@url"> 704 705 @{ 706 bool IsNeverOutOfStock = product.NeverOutOfstock; 707 } 708 709 @if (IsNeverOutOfStock) 710 { 711 <span itemprop="availability" class="d-none">@Translate("Available in stock")</span> 712 } 713 else 714 { 715 if (product.StockLevel > 0) 716 { 717 <span itemprop="availability" class="d-none">InStock</span> 718 } 719 else 720 { 721 <span itemprop="availability" class="d-none">OutOfStock</span> 722 } 723 } 724 @* Stock state for Schema.org, stop *@ 725 726 </div> 727 728 @if (showPricesWithVat == "false" && !neverShowVat) 729 { 730 if (isLazyLoadingForProductInfoEnabled && !Pageview.IsVisualEditorMode) 731 { 732 <small class="opacity-85 fst-normal js-text-price-with-vat d-none" data-suffix="@Translate("Incl. VAT")"></small> 733 } 734 else 735 { 736 string price = !string.IsNullOrEmpty(unitId) ? product.GetPrice(unitId).Price.PriceWithVatFormatted : product.Price.PriceWithVatFormatted; 737 738 if (product?.VariantInfo?.VariantInfo != null) 739 { 740 priceMin = product?.VariantInfo?.PriceMin?.PriceWithVatFormatted != null ? product.VariantInfo.PriceMin.PriceWithVatFormatted : ""; 741 priceMax = product?.VariantInfo?.PriceMax?.PriceWithVatFormatted != null ? product.VariantInfo.PriceMax.PriceWithVatFormatted : ""; 742 } 743 if (priceMin != priceMax) 744 { 745 price = priceMin + " - " + priceMax; 746 } 747 <!-- <small class="opacity-85 fst-normal">@price @Translate("Incl. VAT")</small> --> 748 } 749 } 750 </div> 751 } 752 else if (Pageview.IsVisualEditorMode) 753 { 754 <div class="alert alert-dark m-0" role="alert"> 755 <span>@Translate("No products available")</span> 756 </div> 757 } 758 759 </div> 760 } 761 } 762
Tischleuchte aus Holz mit Kreuzrahmen
Error executing template "Designs/Swift/Paragraph/CustomProductSlider.cshtml"
System.NullReferenceException: Object reference not set to an instance of an object.
   at CompiledRazorTemplates.Dynamic.RazorEngine_3562354021b44d5c892fe73dc2806e4f.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 Dynamicweb.Ecommerce.ProductCatalog 3 @using Dynamicweb.Ecommerce.CustomerExperienceCenter.Favorites 4 @using Dynamicweb.Files 5 @using System.IO 6 @using System.Net 7 @using Dynamicweb.Security.UserManagement 8 9 10 @{ 11 ProductViewModel product = null; 12 if (Dynamicweb.Context.Current.Items.Contains("ProductDetails")) 13 { 14 product = (ProductViewModel)Dynamicweb.Context.Current.Items["ProductDetails"]; 15 } 16 else if (Pageview.Page.Item["DummyProduct"] != null && Pageview.IsVisualEditorMode) 17 { 18 var pageViewModel = Dynamicweb.Frontend.ContentViewModelFactory.CreatePageInfoViewModel(Pageview.Page); 19 ProductListViewModel productList = pageViewModel.Item.GetValue("DummyProduct") != null ? pageViewModel.Item.GetValue("DummyProduct") as ProductListViewModel : new ProductListViewModel(); 20 21 if (productList?.Products is object) 22 { 23 product = productList.Products[0]; 24 } 25 } 26 } 27 28 @{ 29 var currentUser = Pageview?.User; 30 var customerNumber = !string.IsNullOrEmpty(currentUser?.CustomerNumber) 31 ? currentUser.CustomerNumber 32 : ""; 33 } 34 @if (product is object) 35 { 36 string imagePath = product?.DefaultImage?.Value ?? ""; 37 string imagePathUrlEncoded = Dynamicweb.Context.Current.Server.UrlEncode(imagePath); 38 39 string ratio = Model.Item.GetRawValueString("ImageAspectRatio", ""); 40 ratio = ratio != "0" ? ratio : ""; 41 string ratioCssClass = ratio != "" ? " ratio" : ""; 42 string ratioVariable = ratio != "" ? "--bs-aspect-ratio: " + ratio + ";" : ""; 43 44 string width = Model.Item.GetRawValueString("Width", "auto"); 45 int smallImageSize = 640; 46 int largeImageSize = width == "auto" ? 1280 : Convert.ToInt32(width); 47 48 string ImageObjectFit = Model.Item.GetRawValueString("ImageObjectFit", "contain"); 49 50 string imagePathXs = "/Admin/Public/GetImage.ashx?width=" + smallImageSize + "&image=" + imagePathUrlEncoded + "&format=webp"; 51 string imagePathS = "/Admin/Public/GetImage.ashx?width=" + largeImageSize + "&image=" + imagePathUrlEncoded + "&format=webp"; 52 string imagePathFallBack = "/Admin/Public/GetImage.ashx?width=" + largeImageSize + "&image=" + imagePathUrlEncoded + "&format=webp"; 53 54 var badgeParms = new Dictionary<string, object>(); 55 badgeParms.Add("size", "h7"); 56 badgeParms.Add("saleBadgeType", Model.Item.GetRawValue("SaleBadgeType")); 57 badgeParms.Add("saleBadgeCssClassName", Model.Item.GetRawValue("SaleBadgeDesign")); 58 badgeParms.Add("newBadgeCssClassName", Model.Item.GetRawValue("NewBadgeDesign")); 59 badgeParms.Add("newPublicationDays", Model.Item.GetInt32("NewPublicationDays")); 60 badgeParms.Add("campaignBadgesValues", Model.Item.GetList("CampaignBadges")?.GetRawValue().OfType<string>().ToList()); 61 62 string badgeSize = Model.Item.GetRawValueString("BadgeSize", "fs-2"); 63 bool saleBadgeEnabled = !string.IsNullOrWhiteSpace(Model.Item.GetRawValueString("SaleBadgeDesign")) && Model.Item.GetRawValueString("SaleBadgeDesign") != "none" ? true : false; 64 bool newBadgeEnabled = !string.IsNullOrWhiteSpace(Model.Item.GetRawValueString("NewBadgeDesign")) && Model.Item.GetRawValueString("NewBadgeDesign") != "none" ? true : false; 65 66 /*Custom badge*/ 67 var productService = new Dynamicweb.Ecommerce.Products.ProductService(); 68 var currency = Dynamicweb.Ecommerce.Common.Context.Currency.Code; 69 var formatProvider = new System.Globalization.NumberFormatInfo(); 70 formatProvider.NumberDecimalSeparator = "."; 71 formatProvider.NumberGroupSeparator = ","; 72 var MainVariant = productService.GetProductById(product.Id, product.VariantId, false); 73 var fieldValueBlocked = MainVariant?.ProductFieldValues?.GetProductFieldValue("BlockedCustomerList")?.Value; 74 75 76 string isNewProduct = MainVariant?.ProductFieldValues?.GetProductFieldValue("New")?.Value?.ToString().ToLower() ?? ""; 77 string MainisSale = MainVariant?.ProductFieldValues?.GetProductFieldValue("Sale")?.Value?.ToString().ToLower() ?? ""; 78 bool showNewBadge = isNewProduct == "true" ? true : false; 79 bool showSaleBadge = MainisSale == "true" ? true : false; 80 string showNewSaleBadge = "d-none"; 81 if (showSaleBadge) 82 { 83 badgeParms.Add("isSale", "true"); 84 85 } 86 else 87 { 88 badgeParms.Add("isSale", "false"); 89 } 90 if (showNewBadge) 91 { 92 badgeParms.Add("isNew", "true"); 93 } 94 else 95 { 96 badgeParms.Add("isNew", "false"); 97 } 98 /*End Custom badge*/ 99 if (showSaleBadge || showNewBadge) 100 { 101 showNewSaleBadge = ""; 102 } 103 DateTime createdDate = product.Created.Value; 104 bool showBadges = saleBadgeEnabled && product.Discount.Price != 0 ? true : false; 105 106 bool showFavoritesSelector = !string.IsNullOrEmpty(Model.Item.GetString("ShowAddToFavorites")) ? Model.Item.GetBoolean("ShowAddToFavorites") : false; 107 string anonymousUsersLimitations = Pageview.AreaSettings.GetRawValueString("AnonymousUsers", ""); 108 bool anonymousUser = Pageview.User == null; 109 110 var favoriteParameters = new Dictionary<string, object>(); 111 if (!anonymousUser && showFavoritesSelector) 112 { 113 int defaultFavoriteListId = 0; 114 115 IEnumerable<FavoriteList> favoreiteLists = Pageview.User.GetFavoriteLists(); 116 if (favoreiteLists.Count() == 1) 117 { 118 foreach (FavoriteList list in favoreiteLists) 119 { 120 defaultFavoriteListId = list.ListId; 121 } 122 } 123 124 favoriteParameters.Add("ListId", defaultFavoriteListId); 125 } 126 127 MediaViewModel alternativeImage = new MediaViewModel(); 128 if (Model.Item.GetBoolean("ShowAlternativeImageOnHover")) 129 { 130 var selectedImageCategories = Model.Item.GetList("GetAlternativeImageFrom")?.GetRawValue().OfType<string>().ToList(); 131 List<MediaViewModel> allAssetsImages = product.AssetCategories.Where(x => selectedImageCategories.Contains(x.SystemName)).SelectMany(x => x.Assets).ToList(); 132 allAssetsImages.RemoveAll(x => x.Value == product.DefaultImage.Value); 133 alternativeImage = allAssetsImages.FirstOrDefault(); 134 } 135 136 string altImagePathXs = string.Empty; 137 string altImagePathS = string.Empty; 138 139 if (!string.IsNullOrEmpty(alternativeImage?.Value)) 140 { 141 altImagePathXs = "/Admin/Public/GetImage.ashx?width=" + smallImageSize + "&image=" + Dynamicweb.Context.Current.Server.UrlEncode(alternativeImage.Value) + "&format=webp"; 142 altImagePathS = "/Admin/Public/GetImage.ashx?width=" + largeImageSize + "&image=" + Dynamicweb.Context.Current.Server.UrlEncode(alternativeImage.Value) + "&format=webp"; 143 } 144 145 @* Theme settings *@ 146 string theme = !string.IsNullOrWhiteSpace(Model.Item.GetRawValueString("Theme")) ? " theme " + Model.Item.GetRawValueString("Theme").Replace(" ", "").Trim().ToLower() : ""; 147 string themeBorder = !string.IsNullOrWhiteSpace(theme) ? "border: 1px solid rgba(0,0,0,0)" : ""; 148 string themePadding = !string.IsNullOrWhiteSpace(theme) ? "p-2 p-lg-3" : ""; 149 150 string imageId = "ProductImage_" + product.Id; 151 152 153 154 string fullWidth = width == "auto" ? "w-100" : ""; 155 string customWidth = width != "auto" ? "style=\"width: " + width + "px\"" : "style=\"min-width: 60px\""; 156 157 string altImageZindex = Model.Item.GetBoolean("ShowAlternativeImageOnHover") && !string.IsNullOrEmpty(alternativeImage?.Value) ? " z-index: 1" : string.Empty; 158 string groupid = !string.IsNullOrEmpty(Dynamicweb.Context.Current.Request.QueryString.Get("GroupID")) ? Dynamicweb.Context.Current.Request.QueryString.Get("GroupID"):"" ; 159 string link = product.GetProductLink(GetPageIdByNavigationTag("Shop"), false); 160 var productVariantGroups = product.VariantGroups(); 161 string MainOutStock = "<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"25\" height=\"25\" fill=\"#CA0D0D\" class=\"bi bi-x-lg\" viewBox=\"0 0 16 16\"><path d=\"M4.646 4.646a.5.5 0 0 1 .708 0L8 7.293l2.646-2.647a.5.5 0 0 1 .708.708L8.707 8l2.647 2.646a.5.5 0 0 1-.708.708L8 8.707l-2.646 2.647a.5.5 0 0 1-.708-.708L7.293 8 4.646 5.354a.5.5 0 0 1 0-.708\"/></svg>"; 162 163 @if (!string.IsNullOrEmpty(imagePath)) 164 { 165 <div class="@fullWidth @theme position-relative item_@Model.Item.SystemName.ToLower() main-image-container" @customWidth> 166 <div class="" style="@(ratioVariable)@(altImageZindex)"> 167 <div class="d-flex justify-content-center align-items-center"> 168 <a class="main-link-link" href="@link"> 169 @if (imagePath.StartsWith("/Files/", StringComparison.OrdinalIgnoreCase)) 170 { 171 <img id="@imageId" 172 srcset=" 173 @imagePathXs @(smallImageSize)w, 174 @imagePathS @(largeImageSize)w" 175 sizes="(max-width: 992px) 50vw, 25vw" 176 src="@imagePathFallBack" 177 loading="lazy" 178 decoding="async" 179 class="h-100 w-100 @themePadding main-image" 180 style="object-fit: @ImageObjectFit; @themeBorder " 181 alt="@product.Name" 182 itemprop="image"> 183 } 184 else 185 { 186 <img src="@product.DefaultImage.Value" 187 loading="lazy" 188 class="h-100 w-100 @themePadding main-image" 189 style="object-fit: contain; @themeBorder" 190 alt="@product.Name" 191 itemprop="image"> 192 } 193 </a> 194 </div> 195 </div> 196 197 <div class="position-absolute top-0 left-0 p-2 pb-0 custom-badge-product-list @showNewSaleBadge"> 198 @{ 199 @RenderPartial("Components/Custom_EcommerceBadge.cshtml", product, badgeParms) 200 } 201 </div> 202 203 204 </div> 205 } 206 207 <div class="product-info h-100"> 208 <div class="fs-7 pt-1 opacity-85 start item_@Model.Item.SystemName.ToLower() product-number" itemprop="sku">@product.Id / @product.VariantId - @product.VariantName</div> 209 <div class="py-2" data-col-size="12"> 210 <h2 class="h6 start m-0 item_swift_productheader product-name" itemprop="name"><b>@product.Name</b></h2> 211 </div> 212 </div> 213 var sliderId = $"thumb-scroll-{product.Id}"; 214 if (productVariantGroups.Any() && product?.VariantInfo?.VariantInfo != null) 215 216 { 217 @using Dynamicweb.Ecommerce.Prices 218 @{ 219 string[] variantId = product.VariantId.Split('.'); 220 string showPricesWithVat = Pageview.Area.EcomPricesWithVat.ToLower(); 221 bool neverShowVat = string.IsNullOrEmpty(showPricesWithVat); 222 bool showInformativePrice = Model.Item.GetBoolean("ShowInformativePrice"); 223 string productInfoFeed = ""; 224 bool isLazyLoadingForProductInfoEnabled = Dynamicweb.Core.Converter.ToBoolean(Dynamicweb.Context.Current.Items["IsLazyLoadingForProductInfoEnabled"]); 225 if (isLazyLoadingForProductInfoEnabled) 226 { 227 if (Dynamicweb.Context.Current.Items.Contains("ProductInfoFeed")) 228 { 229 productInfoFeed = Dynamicweb.Context.Current.Items["ProductInfoFeed"]?.ToString(); 230 if (!string.IsNullOrEmpty(productInfoFeed)) 231 { 232 productInfoFeed =productInfoFeed; 233 } 234 } 235 236 } 237 string priceMin = ""; 238 string priceMax = ""; 239 int groupNumber = 1; 240 241 242 243 244 string baseUrl = $"Default.aspx?ID={GetPageIdByNavigationTag("Shop")}&GroupID={product.PrimaryOrDefaultGroup.Id}&ProductID={product.Id}"; 245 if (!string.IsNullOrEmpty(baseUrl)) 246 { 247 baseUrl = $"/{baseUrl.TrimStart('/')}"; 248 } 249 string variantUrl = string.Empty; 250 251 252 Dictionary<string, string> 253 variantImages = new Dictionary<string, string> 254 (); 255 <div class="last-row mt-auto"> 256 257 @foreach (var variantGroup in productVariantGroups) 258 { 259 <div class="thumbnail-wrapper"> 260 <button class="thumb-nav prev" onclick="scrollThumbs('@sliderId', -1)"> 261 <svg width="20px" height="20px" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" fill="#1D98A5"> 262 263 <g stroke="none" stroke-width="1" fill="none" fill-rule="evenodd"> 264 <g transform="translate(-336.000000, 0.000000)"> 265 <g id="left_line" transform="translate(336.000000, 0.000000)"> 266 <path d="M24,0 L24,24 L0,24 L0,0 L24,0 Z M12.5934901,23.257841 L12.5819402,23.2595131 L12.5108777,23.2950439 L12.4918791,23.2987469 L12.4918791,23.2987469 L12.4767152,23.2950439 L12.4056548,23.2595131 C12.3958229,23.2563662 12.3870493,23.2590235 12.3821421,23.2649074 L12.3780323,23.275831 L12.360941,23.7031097 L12.3658947,23.7234994 L12.3769048,23.7357139 L12.4804777,23.8096931 L12.4953491,23.8136134 L12.4953491,23.8136134 L12.5071152,23.8096931 L12.6106902,23.7357139 L12.6232938,23.7196733 L12.6232938,23.7196733 L12.6266527,23.7031097 L12.609561,23.275831 C12.6075724,23.2657013 12.6010112,23.2592993 12.5934901,23.257841 L12.5934901,23.257841 Z M12.8583906,23.1452862 L12.8445485,23.1473072 L12.6598443,23.2396597 L12.6498822,23.2499052 L12.6498822,23.2499052 L12.6471943,23.2611114 L12.6650943,23.6906389 L12.6699349,23.7034178 L12.6699349,23.7034178 L12.678386,23.7104931 L12.8793402,23.8032389 C12.8914285,23.8068999 12.9022333,23.8029875 12.9078286,23.7952264 L12.9118235,23.7811639 L12.8776777,23.1665331 C12.8752882,23.1545897 12.8674102,23.1470016 12.8583906,23.1452862 L12.8583906,23.1452862 Z M12.1430473,23.1473072 C12.1332178,23.1423925 12.1221763,23.1452606 12.1156365,23.1525954 L12.1099173,23.1665331 L12.0757714,23.7811639 C12.0751323,23.7926639 12.0828099,23.8018602 12.0926481,23.8045676 L12.108256,23.8032389 L12.3092106,23.7104931 L12.3186497,23.7024347 L12.3186497,23.7024347 L12.3225043,23.6906389 L12.340401,23.2611114 L12.337245,23.2485176 L12.337245,23.2485176 L12.3277531,23.2396597 L12.1430473,23.1473072 Z" id="MingCute" fill-rule="nonzero"> </path> 267 <path d="M8.29292,12.7071 C7.9024,12.3166 7.9024,11.6834 8.29292,11.2929 L13.9498,5.63604 C14.3403,5.24551 14.9735,5.24551 15.364,5.63604 C15.7545,6.02656 15.7545,6.65973 15.364,7.05025 L10.4142,12 L15.364,16.9497 C15.7545,17.3403 15.7545,17.9734 15.364,18.364 C14.9735,18.7545 14.3403,18.7545 13.9498,18.364 L8.29292,12.7071 Z" id="路径" fill="#1D98A5"> </path> 268 </g> 269 </g> 270 </g> 271 </svg> 272 273 </button> 274 <div class="thumbnail-scroll" id="@sliderId"> 275 @{ 276 VariantGroupViewModel group = variantGroup; 277 foreach (var option in group.Options.OrderBy(o => o.Id)) 278 { 279 var productVariant = productService.GetProductById(product.Id, option.Id, false); 280 281 var productSelection = new PriceProductSelection(productVariant, null, 0); 282 283 var currencyCode = string.IsNullOrWhiteSpace(Pageview.User.Currency) ? Pageview.Area.EcomCurrencyId : Pageview.User.Currency; 284 var countryCode = string.IsNullOrWhiteSpace(Pageview.User.CountryCode) ? Pageview.Area.EcomCountryCode : Pageview.User.CountryCode; 285 286 var userCurrency = Dynamicweb.Ecommerce.Services.Currencies.GetCurrency(currencyCode); 287 var userCountry = Dynamicweb.Ecommerce.Services.Countries.GetCountry(countryCode); 288 289 var priceContext = new PriceContext(userCurrency, userCountry, null, Pageview.User, false, null); 290 var productPrice = Dynamicweb.Ecommerce.Services.Prices.FindPrices(priceContext, productSelection, false); 291 292 //throw new Exception(System.Text.Json.JsonSerializer.Serialize(productPrice)); 293 294 var fieldValue = productVariant?.ProductFieldValues?.GetProductFieldValue("BlockedCustomerList")?.Value; 295 296 if ((fieldValue != null && !fieldValue.ToString().Contains(customerNumber)) || String.IsNullOrWhiteSpace(customerNumber)) 297 { 298 299 300 string active = variantId != null && variantId.Contains(option.Id) ? "active" : string.Empty; 301 string buttonId = $"{product.Id}_{option.Id}_{Pageview.CurrentParagraph.ID}"; 302 string contrastColor = string.Empty; 303 304 string searchKey = $"{product.Id}_{option.Id}_"; 305 /*Images*/ 306 var imagePathVariant = option.Image?.Value ?? ""; 307 308 309 var folderPath = Path.GetDirectoryName(imagePathVariant); 310 311 string physicalFolderPath = Dynamicweb.Context.Current.Server.MapPath(folderPath); 312 313 string lastImage = null; 314 315 if (Directory.Exists(physicalFolderPath)) 316 { 317 318 var fileWith15 = Directory.GetFiles(physicalFolderPath) 319 .FirstOrDefault(f => Path.GetFileName(f).Contains($"{product.Id}_{option.Id}_9")); 320 321 if (fileWith15 != null) 322 { 323 lastImage = fileWith15; 324 } 325 else 326 { 327 var files = Directory.GetFiles(physicalFolderPath) 328 .Where(f => Path.GetFileName(f).StartsWith($"{product.Id}_{option.Id}_")) 329 .OrderByDescending(f => 330 { 331 var filename = Path.GetFileNameWithoutExtension(f); 332 var match = System.Text.RegularExpressions.Regex.Match(filename, @"_(\d+)$"); 333 if (match.Success && int.TryParse(match.Groups[1].Value, out int index)) 334 { 335 return index; 336 } 337 return 0; 338 }) 339 .ToList(); 340 341 if (files.Any()) 342 { 343 lastImage = files.First(); 344 } 345 } 346 } 347 348 var lastImageUrl = lastImage != null ? lastImage : "/Files/Images/zijlstra/Afbeeldingen_overig/Coming_Soon.jpg"; 349 int index = lastImageUrl.IndexOf("Files"); 350 string relativePath = index >= 0 ? lastImageUrl.Substring(index).Replace("\\", "/") : lastImageUrl.Replace("\\", "/"); 351 lastImageUrl = "/" + relativePath; 352 lastImageUrl = Dynamicweb.Context.Current.Server.UrlEncode(lastImageUrl); 353 var variantImg = option.Image is object ? Dynamicweb.Context.Current.Server.UrlEncode(option.Image.Value) : null; 354 var variantLink = "/Default.aspx?ID=" + GetPageIdByNavigationTag("Shop") + "&GroupID=" + product.PrimaryOrDefaultGroup.Id + "&ProductID=" + product.Id + "&VariantID=" + option.Id; 355 356 string variantImage = string.Empty; 357 variantImages.TryGetValue(option.Id, out variantImage); 358 /*End Images*/ 359 360 /*stock state*/ 361 double variantStock = productVariant.Stock; 362 string svgInStock = "<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"16\" height=\"16\" fill=\"#44B11A\" class=\"bi bi-check-lg\" viewBox=\"0 0 16 16\"><path d=\"M12.736 3.97a.733.733 0 0 1 1.047 0c.286.289.29.756.01 1.05L7.88 12.01a.733.733 0 0 1-1.065.02L3.217 8.384a.757.757 0 0 1 0-1.06.733.733 0 0 1 1.047 0l3.052 3.093 5.4-6.425z\"/></svg>"; 363 string svgOutStock = "<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"25\" height=\"25\" fill=\"#CA0D0D\" class=\"bi bi-x-lg\" viewBox=\"0 0 16 16\"><path d=\"M4.646 4.646a.5.5 0 0 1 .708 0L8 7.293l2.646-2.647a.5.5 0 0 1 .708.708L8.707 8l2.647 2.646a.5.5 0 0 1-.708.708L8 8.707l-2.646 2.647a.5.5 0 0 1-.708-.708L7.293 8 4.646 5.354a.5.5 0 0 1 0-.708\"/></svg>"; 364 365 string infoStock = "<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"16\" height=\"16\" fill=\"currentColor\" class=\"bi bi-info-circle-fill\" viewBox=\"0 0 16 16\"><path d=\"M8 16A8 8 0 1 0 8 0a8 8 0 0 0 0 16m.93-9.412-1 4.705c-.07.34.029.533.304.533.194 0 .487-.07.686-.246l-.088.416c-.287.346-.92.598-1.465.598-.703 0-1.002-.422-.808-1.319l.738-3.468c.064-.293.006-.399-.287-.47l-.451-.081.082-.381 2.29-.287zM8 5.5a1 1 0 1 1 0-2 1 1 0 0 1 0 2\" /></svg>"; 366 string isNew = productVariant?.ProductFieldValues?.GetProductFieldValue("New")?.Value?.ToString().ToLower() ?? ""; 367 string isNewSvg = "<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"16\" height=\"16\" fill=\"#F2C400\" class=\"bi bi-star-fill\" viewBox=\"0 0 16 16\"><path d = \"M3.612 15.443c-.386.198-.824-.149-.746-.592l.83-4.73L.173 6.765c-.329-.314-.158-.888.283-.95l4.898-.696L7.538.792c.197-.39.73-.39.927 0l2.184 4.327 4.898.696c.441.062.612.636.282.95l-3.522 3.356.83 4.73c.078.443-.36.79-.746.592L8 13.187l-4.389 2.256z\" /></svg> "; 368 string stockState = ""; 369 370 string isSale = productVariant?.ProductFieldValues?.GetProductFieldValue("Sale")?.Value?.ToString().ToLower() ?? ""; 371 string isSaleSvg = "<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"16\" height=\"16\" fill=\"#F03232\" class=\"bi bi-star-fill\" viewBox=\"0 0 16 16\"><path d = \"M3.612 15.443c-.386.198-.824-.149-.746-.592l.83-4.73L.173 6.765c-.329-.314-.158-.888.283-.95l4.898-.696L7.538.792c.197-.39.73-.39.927 0l2.184 4.327 4.898.696c.441.062.612.636.282.95l-3.522 3.356.83 4.73c.078.443-.36.79-.746.592L8 13.187l-4.389 2.256z\" /></svg> "; 372 373 string expectedDeliveryDate = ""; 374 375 if (DateTime.Compare(productVariant.ExpectedDelivery, new DateTime(1900, 1, 1)) != 0) //In DW, if the Date is not set, it is defaulted 01-01-1900 and not null.. 376 { 377 expectedDeliveryDate = productVariant.ExpectedDelivery.ToShortDateString(); 378 } 379 380 string expectedDeliveryDateText = !String.IsNullOrWhiteSpace(expectedDeliveryDate) ? Translate("Verwacht:") + "&nbsp;" + expectedDeliveryDate : ""; 381 382 @if (!(bool?)productVariant.ProductFieldValues.Where(o => o.ProductField.SystemName == "ProductToBeDiscontinued").SingleOrDefault()?.Value ?? false) 383 { 384 if (variantStock > 0) 385 { 386 if (isNew == "true" || isSale == "true") 387 { 388 if (isSale == "true") 389 { 390 stockState += isSaleSvg + "&nbsp; &nbsp;" + Translate("Sale!") + "<br/>"; 391 } 392 393 if (isNew == "true") 394 { 395 stockState += isNewSvg + "&nbsp; &nbsp;" + Translate("New!") + "<br/>"; 396 } 397 398 stockState += "&nbsp;" + Translate("Nu leverbaar"); 399 } 400 else 401 { 402 stockState = svgInStock + "&nbsp; " + Translate("Op voorraad"); 403 404 } 405 } 406 else 407 { 408 stockState = svgOutStock + "&nbsp;" + Translate("Geen voorraad") + "<br/>" + expectedDeliveryDateText; 409 410 } 411 } 412 else 413 { 414 415 stockState = svgOutStock + "&nbsp;" + Translate("Discontinued:") + "<br/>" + variantStock + "&nbsp;" + @Translate("left in stock"); 416 417 } 418 /*End stock state*/ 419 /*Price variants*/ 420 double price = productVariant.DefaultPrice; 421 double cost = productVariant.Cost; 422 423 string priceFormated = Dynamicweb.Ecommerce.Services.Currencies.Format(Dynamicweb.Ecommerce.Services.Currencies.GetCurrency(currency), Convert.ToDouble(productPrice.ToList()[0].Amount, formatProvider)); 424 //string priceFormated = Dynamicweb.Ecommerce.Services.Currencies.Format(Dynamicweb.Ecommerce.Services.Currencies.GetCurrency(currency), Convert.ToDouble(price, formatProvider)); 425 426 427 428 /*End Price variants*/ 429 430 <img class="theme thumbnail" data-stockstate="@WebUtility.HtmlEncode(stockState)" src="/Admin/Public/GetImage.ashx?image=@(lastImageUrl)&width=64&format=webp" onclick="selectVariant('@(product.Id)','/Admin/Public/GetImage.ashx?image=@(variantImg)&format=webp','@variantLink','@product.Id','@option.Id','@option.Name',this.dataset.stockstate,'@isNew','@isSale','@priceFormated','@cost')" /> 431 432 433 } 434 } 435 436 } 437 </div> 438 <button class="thumb-nav next" onclick="scrollThumbs('@sliderId', 1)"> 439 <svg width="20px" height="20px" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" fill="#1D98A5"> 440 441 <g stroke="none" stroke-width="1" fill="none" fill-rule="evenodd"> 442 <g transform="translate(-384.000000, 0.000000)"> 443 <g id="right_line" transform="translate(384.000000, 0.000000)"> 444 <path d="M24,0 L24,24 L0,24 L0,0 L24,0 Z M12.5934901,23.257841 L12.5819402,23.2595131 L12.5108777,23.2950439 L12.4918791,23.2987469 L12.4918791,23.2987469 L12.4767152,23.2950439 L12.4056548,23.2595131 C12.3958229,23.2563662 12.3870493,23.2590235 12.3821421,23.2649074 L12.3780323,23.275831 L12.360941,23.7031097 L12.3658947,23.7234994 L12.3769048,23.7357139 L12.4804777,23.8096931 L12.4953491,23.8136134 L12.4953491,23.8136134 L12.5071152,23.8096931 L12.6106902,23.7357139 L12.6232938,23.7196733 L12.6232938,23.7196733 L12.6266527,23.7031097 L12.609561,23.275831 C12.6075724,23.2657013 12.6010112,23.2592993 12.5934901,23.257841 L12.5934901,23.257841 Z M12.8583906,23.1452862 L12.8445485,23.1473072 L12.6598443,23.2396597 L12.6498822,23.2499052 L12.6498822,23.2499052 L12.6471943,23.2611114 L12.6650943,23.6906389 L12.6699349,23.7034178 L12.6699349,23.7034178 L12.678386,23.7104931 L12.8793402,23.8032389 C12.8914285,23.8068999 12.9022333,23.8029875 12.9078286,23.7952264 L12.9118235,23.7811639 L12.8776777,23.1665331 C12.8752882,23.1545897 12.8674102,23.1470016 12.8583906,23.1452862 L12.8583906,23.1452862 Z M12.1430473,23.1473072 C12.1332178,23.1423925 12.1221763,23.1452606 12.1156365,23.1525954 L12.1099173,23.1665331 L12.0757714,23.7811639 C12.0751323,23.7926639 12.0828099,23.8018602 12.0926481,23.8045676 L12.108256,23.8032389 L12.3092106,23.7104931 L12.3186497,23.7024347 L12.3186497,23.7024347 L12.3225043,23.6906389 L12.340401,23.2611114 L12.337245,23.2485176 L12.337245,23.2485176 L12.3277531,23.2396597 L12.1430473,23.1473072 Z" id="MingCute" fill-rule="nonzero"> </path> 445 <path d="M15.7072,11.2929 C16.0977,11.6834 16.0977,12.3166 15.7072,12.7071 L10.0503,18.364 C9.65982,18.7545 9.02666,18.7545 8.63613,18.364 C8.24561,17.9734 8.24561,17.3403 8.63613,16.9497 L13.5859,12 L8.63613,7.05025 C8.24561,6.65973 8.24561,6.02656 8.63613,5.63604 C9.02666,5.24551 9.65982,5.24551 10.0503,5.63604 L15.7072,11.2929 Z" id="路径" fill="#1D98A5"> </path> 446 </g> 447 </g> 448 449 </svg> 450 451 </button> 452 </div> 453 } 454 455 456 </div> 457 458 } 459 if ((fieldValueBlocked != null && !fieldValueBlocked.ToString().Contains(customerNumber)) || String.IsNullOrWhiteSpace(customerNumber)) 460 { 461 <div class="stock-state pt-2 mt-auto"> 462 @{ 463 464 /*stock state*/ 465 double MainvariantStock = MainVariant.Stock; 466 string MainsvgInStock = "<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"16\" height=\"16\" fill=\"#44B11A\" class=\"bi bi-check-lg\" viewBox=\"0 0 16 16\"><path d=\"M12.736 3.97a.733.733 0 0 1 1.047 0c.286.289.29.756.01 1.05L7.88 12.01a.733.733 0 0 1-1.065.02L3.217 8.384a.757.757 0 0 1 0-1.06.733.733 0 0 1 1.047 0l3.052 3.093 5.4-6.425z\"/></svg>"; 467 string MainsvgOutStock = "<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"25\" height=\"25\" fill=\"#CA0D0D\" class=\"bi bi-x-lg\" viewBox=\"0 0 16 16\"><path d=\"M4.646 4.646a.5.5 0 0 1 .708 0L8 7.293l2.646-2.647a.5.5 0 0 1 .708.708L8.707 8l2.647 2.646a.5.5 0 0 1-.708.708L8 8.707l-2.646 2.647a.5.5 0 0 1-.708-.708L7.293 8 4.646 5.354a.5.5 0 0 1 0-.708\"/></svg>"; 468 469 string MaininfoStock = "<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"16\" height=\"16\" fill=\"currentColor\" class=\"bi bi-info-circle-fill\" viewBox=\"0 0 16 16\"><path d=\"M8 16A8 8 0 1 0 8 0a8 8 0 0 0 0 16m.93-9.412-1 4.705c-.07.34.029.533.304.533.194 0 .487-.07.686-.246l-.088.416c-.287.346-.92.598-1.465.598-.703 0-1.002-.422-.808-1.319l.738-3.468c.064-.293.006-.399-.287-.47l-.451-.081.082-.381 2.29-.287zM8 5.5a1 1 0 1 1 0-2 1 1 0 0 1 0 2\" /></svg>"; 470 string MainisNew = MainVariant?.ProductFieldValues?.GetProductFieldValue("New")?.Value?.ToString().ToLower() ?? ""; 471 string MainisNewSvg = "<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"16\" height=\"16\" fill=\"#F2C400\" class=\"bi bi-star-fill\" viewBox=\"0 0 16 16\"><path d = \"M3.612 15.443c-.386.198-.824-.149-.746-.592l.83-4.73L.173 6.765c-.329-.314-.158-.888.283-.95l4.898-.696L7.538.792c.197-.39.73-.39.927 0l2.184 4.327 4.898.696c.441.062.612.636.282.95l-3.522 3.356.83 4.73c.078.443-.36.79-.746.592L8 13.187l-4.389 2.256z\" /></svg> "; 472 string MainstockState = ""; 473 string MainIsSale = MainVariant?.ProductFieldValues?.GetProductFieldValue("Sale")?.Value?.ToString().ToLower() ?? ""; 474 string MainIsSaleSvg = "<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"16\" height=\"16\" fill=\"#F03232\" class=\"bi bi-star-fill\" viewBox=\"0 0 16 16\"><path d = \"M3.612 15.443c-.386.198-.824-.149-.746-.592l.83-4.73L.173 6.765c-.329-.314-.158-.888.283-.95l4.898-.696L7.538.792c.197-.39.73-.39.927 0l2.184 4.327 4.898.696c.441.062.612.636.282.95l-3.522 3.356.83 4.73c.078.443-.36.79-.746.592L8 13.187l-4.389 2.256z\" /></svg> "; 475 string MainexpectedDeliveryDate = ""; 476 477 if (DateTime.Compare(MainVariant.ExpectedDelivery, new DateTime(1900, 1, 1)) != 0) //In DW, if the Date is not set, it is defaulted 01-01-1900 and not null.. 478 { 479 MainexpectedDeliveryDate = MainVariant.ExpectedDelivery.ToShortDateString(); 480 } 481 482 string MainexpectedDeliveryDateText = !String.IsNullOrWhiteSpace(MainexpectedDeliveryDate) ? Translate("Verwacht:") + "&nbsp;" + MainexpectedDeliveryDate : ""; 483 484 @if (!(bool?)MainVariant.ProductFieldValues.Where(o => o.ProductField.SystemName == "ProductToBeDiscontinued").SingleOrDefault()?.Value ?? false) 485 { 486 if (MainvariantStock > 0) 487 { 488 if (MainisNew == "true" || MainIsSale == "true") 489 { 490 if (MainIsSale == "true") 491 { 492 MainstockState += MainIsSaleSvg + "&nbsp; &nbsp;" + Translate("Sale!") + "<br/>"; 493 } 494 495 if (MainisNew == "true") 496 { 497 MainstockState += MainisNewSvg + "&nbsp; &nbsp;" + Translate("New!") + "<br/>"; 498 } 499 500 MainstockState += "&nbsp;" + Translate("Nu leverbaar"); 501 } 502 else 503 { 504 MainstockState = MainsvgInStock + "&nbsp; " + Translate("Op voorraad"); 505 506 } 507 } 508 else 509 { 510 MainstockState = MainsvgOutStock + "&nbsp;" + Translate("Geen voorraad") + "<br/>" + MainexpectedDeliveryDateText; 511 512 } 513 } 514 else 515 { 516 517 MainstockState = MainsvgOutStock + "&nbsp;" + Translate("Discontinued:") + "<br/>" + MainvariantStock + "&nbsp;" + @Translate("left in stock"); 518 519 } 520 /*End stock state*/ 521 522 523 @MainstockState 524 525 526 } 527 </div> 528 } 529 else 530 { 531 <div class="stock-state pt-2 mt-auto"> 532 @MainOutStock @Translate("Discontinued") 533 </div> 534 } 535 <div class="custom-price mt-auto"> 536 @{ 537 538 539 540 541 bool isErpConnectionDown = !Dynamicweb.Core.Converter.ToBoolean(Dynamicweb.Context.Current.Items["IsWebServiceConnectionAvailable"]); 542 bool hidePrice = anonymousUsersLimitations.Contains("price") && anonymousUser || Pageview.AreaSettings.GetBoolean("ErpDownHidePrices") && isErpConnectionDown; 543 544 bool productIsDiscontinued = product is object && product.Discontinued; 545 bool doNotShowPriceIfProductIsDiscontinued = Model.Item.GetBoolean("DoNotShowPriceIfProductIsDiscontinued"); 546 var isDiscontinued = productIsDiscontinued && doNotShowPriceIfProductIsDiscontinued; 547 } 548 549 @if (product is object && !hidePrice && !isDiscontinued) 550 { 551 string unitId = !string.IsNullOrEmpty(Dynamicweb.Context.Current.Request.Form.Get("UnitId")) ? Dynamicweb.Context.Current.Request.Form.Get("UnitId") : string.Empty; 552 553 string priceFontSize = Model.Item.GetRawValueString("PriceSize", "fs-4"); 554 string horizontalAlign = Model.Item.GetRawValueString("HorizontalAlignment", ""); 555 string layout = Model.Item.GetRawValueString("Layout", "horizontal"); 556 string textAlign = horizontalAlign == "center" ? "text-center" : string.Empty; 557 textAlign = horizontalAlign == "end" ? "text-end" : textAlign; 558 559 horizontalAlign = horizontalAlign == "center" && layout == "horizontal" ? "justify-content-center" : horizontalAlign; 560 horizontalAlign = horizontalAlign == "end" && layout == "horizontal" ? "justify-content-end" : horizontalAlign; 561 horizontalAlign = horizontalAlign == "center" && layout == "vertical" ? "align-items-center" : horizontalAlign; 562 horizontalAlign = horizontalAlign == "end" && layout == "vertical" ? "align-items-end" : horizontalAlign; 563 564 string flexDirection = layout == "horizontal" ? string.Empty : "flex-column"; 565 string flexGap = layout == "horizontal" ? "gap-3" : string.Empty; 566 string order = layout == "horizontal" ? string.Empty : "order-2"; 567 568 569 string contentPadding = Model.Item.GetRawValueString("ContentPadding", ""); 570 contentPadding = contentPadding == "none" ? "p-0" : contentPadding; 571 contentPadding = contentPadding == "small" ? "p-1 px-md-2 py-md-1" : contentPadding; 572 contentPadding = contentPadding == "large" ? "p-2 px-md-3 py-md-2" : contentPadding; 573 string liveInfoClass = ""; 574 575 576 577 578 579 580 if (isLazyLoadingForProductInfoEnabled) 581 { 582 if (Dynamicweb.Context.Current.Items.Contains("ProductInfoFeed")) 583 { 584 productInfoFeed = Dynamicweb.Context.Current.Items["ProductInfoFeed"]?.ToString(); 585 if (!string.IsNullOrEmpty(productInfoFeed)) 586 { 587 productInfoFeed = $"data-product-info-feed=\"{productInfoFeed}\""; 588 } 589 } 590 liveInfoClass = "js-live-info"; 591 } 592 593 <div class="@textAlign @liveInfoClass item_@Model.Item.SystemName.ToLower()" data-product-id="@product.Id" data-variant-id="@product.VariantId" @productInfoFeed> 594 @if (showInformativePrice && product.PriceInformative.Price != 0) 595 { 596 <div class="opacity-50"> 597 <span>@Translate("RRP") </span> 598 <span class="text-decoration-line-through text-price">@product.PriceInformative.PriceFormatted</span> 599 </div> 600 } 601 <div class="@priceFontSize m-0 d-flex flex-wrap @flexDirection @flexGap @horizontalAlign" style="row-gap: 0 !important" itemprop="offers" itemscope itemtype="https://schema.org/Offer"> 602 <span itemprop="priceCurrency" content="@product.Price.CurrencyCode" class="d-none"></span> 603 604 605 @if (showPricesWithVat == "false" && !neverShowVat) 606 { 607 if (isLazyLoadingForProductInfoEnabled && !Pageview.IsVisualEditorMode) 608 { 609 <span itemprop="price" content="" class="d-none"></span> 610 <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> 611 } 612 else 613 { 614 string beforePrice = !string.IsNullOrEmpty(unitId) ? product.GetPrice(unitId).PriceBeforeDiscount.PriceWithoutVatFormatted : product.PriceBeforeDiscount.PriceWithoutVatFormatted; 615 616 <span itemprop="price" content="@product.Price.PriceWithoutVat.ToString("0.00", System.Globalization.CultureInfo.InvariantCulture)" class="d-none"></span> 617 if (product.Price.Price != product.PriceBeforeDiscount.Price) 618 { 619 <span class="text-decoration-line-through opacity-75 @order">@beforePrice</span> 620 } 621 } 622 } 623 else 624 { 625 if (isLazyLoadingForProductInfoEnabled && !Pageview.IsVisualEditorMode) 626 { 627 <span itemprop="price" content="" class="d-none"></span> 628 <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> 629 } 630 else 631 { 632 string beforePrice = !string.IsNullOrEmpty(unitId) ? product.GetPrice(unitId).PriceBeforeDiscount.PriceFormatted : product.PriceBeforeDiscount.PriceFormatted; 633 634 <span itemprop="price" content="@product.Price.Price.ToString("0.00", System.Globalization.CultureInfo.InvariantCulture)" class="d-none"></span> 635 636 if (product.Price.Price != product.PriceBeforeDiscount.Price) 637 { 638 <span class="text-decoration-line-through opacity-75 @order"> 639 <span class="text-price">@beforePrice</span> 640 </span> 641 } 642 } 643 } 644 645 @if (showPricesWithVat == "false" && !neverShowVat) 646 { 647 if (isLazyLoadingForProductInfoEnabled && !Pageview.IsVisualEditorMode) 648 { 649 <span class="text-price js-text-price"> 650 <span class="spinner-border" role="status"></span> 651 </span> 652 } 653 else 654 { 655 string price = !string.IsNullOrEmpty(unitId) ? product.GetPrice(unitId).Price.PriceWithoutVatFormatted : product.Price.PriceWithoutVatFormatted; 656 657 if (product?.VariantInfo?.VariantInfo != null) 658 { 659 priceMin = product?.VariantInfo?.PriceMin?.PriceWithoutVatFormatted != null ? product.VariantInfo.PriceMin.PriceWithoutVatFormatted : ""; 660 priceMax = product?.VariantInfo?.PriceMax?.PriceWithoutVatFormatted != null ? product.VariantInfo.PriceMax.PriceWithoutVatFormatted : ""; 661 } 662 if (priceMin != priceMax) 663 { 664 price = priceMin + " - " + priceMax; 665 } 666 <span class="@theme @contentPadding"> 667 <span class="text-price">@price</span> 668 </span> 669 } 670 } 671 else 672 { 673 if (isLazyLoadingForProductInfoEnabled && !Pageview.IsVisualEditorMode) 674 { 675 <span class="text-price js-text-price"> 676 <span class="spinner-border" role="status"></span> 677 </span> 678 } 679 else 680 { 681 string price = !string.IsNullOrEmpty(unitId) ? product.GetPrice(unitId).Price.PriceFormatted : product.Price.PriceFormatted; 682 683 if (product?.VariantInfo?.VariantInfo != null) 684 { 685 priceMin = product?.VariantInfo?.PriceMin?.PriceFormatted != null ? product.VariantInfo.PriceMin.PriceFormatted : ""; 686 priceMax = product?.VariantInfo?.PriceMax?.PriceFormatted != null ? product.VariantInfo.PriceMax.PriceFormatted : ""; 687 } 688 if (priceMin != priceMax) 689 { 690 price = priceMin + " - " + priceMax; 691 } 692 <span class="@theme @contentPadding"> 693 <span class="text-price">@price</span> 694 </span> 695 } 696 } 697 698 @* Stock state for Schema.org, start *@ 699 @{ 700 Uri url = Dynamicweb.Context.Current.Request.Url; 701 } 702 703 <link itemprop="url" href="@url"> 704 705 @{ 706 bool IsNeverOutOfStock = product.NeverOutOfstock; 707 } 708 709 @if (IsNeverOutOfStock) 710 { 711 <span itemprop="availability" class="d-none">@Translate("Available in stock")</span> 712 } 713 else 714 { 715 if (product.StockLevel > 0) 716 { 717 <span itemprop="availability" class="d-none">InStock</span> 718 } 719 else 720 { 721 <span itemprop="availability" class="d-none">OutOfStock</span> 722 } 723 } 724 @* Stock state for Schema.org, stop *@ 725 726 </div> 727 728 @if (showPricesWithVat == "false" && !neverShowVat) 729 { 730 if (isLazyLoadingForProductInfoEnabled && !Pageview.IsVisualEditorMode) 731 { 732 <small class="opacity-85 fst-normal js-text-price-with-vat d-none" data-suffix="@Translate("Incl. VAT")"></small> 733 } 734 else 735 { 736 string price = !string.IsNullOrEmpty(unitId) ? product.GetPrice(unitId).Price.PriceWithVatFormatted : product.Price.PriceWithVatFormatted; 737 738 if (product?.VariantInfo?.VariantInfo != null) 739 { 740 priceMin = product?.VariantInfo?.PriceMin?.PriceWithVatFormatted != null ? product.VariantInfo.PriceMin.PriceWithVatFormatted : ""; 741 priceMax = product?.VariantInfo?.PriceMax?.PriceWithVatFormatted != null ? product.VariantInfo.PriceMax.PriceWithVatFormatted : ""; 742 } 743 if (priceMin != priceMax) 744 { 745 price = priceMin + " - " + priceMax; 746 } 747 <!-- <small class="opacity-85 fst-normal">@price @Translate("Incl. VAT")</small> --> 748 } 749 } 750 </div> 751 } 752 else if (Pageview.IsVisualEditorMode) 753 { 754 <div class="alert alert-dark m-0" role="alert"> 755 <span>@Translate("No products available")</span> 756 </div> 757 } 758 759 </div> 760 } 761 } 762
Indem Sie auf „Alle akzeptieren“ klicken, stimmen Sie zu, dass wir Informationen über Sie für verschiedene Zwecke sammeln dürfen, darunter: Statistiken und Marketing