Error executing template "Designs/Hags2024/eCom/Product/Product.cshtml" System.ComponentModel.Win32Exception (0x80004005): Multiple connections to a server or shared resource by the same user, using more than one user name, are not allowed. Disconnect all previous connections to the server or shared resource and try again at HagsWeb.Library.Services.FileSystemService.FindFile.Win32Error(Int32 errorCode) at HagsWeb.Library.Services.FileSystemService.FindFile.FindFileEx(FileFoundEventArgs args, Int32 slength) at HagsWeb.Library.Services.FileSystemService.FindFile.Find() at HagsWeb.Library.Methods.AssetManager.AssetManager_Repository.GetDirectoryStructure(String directory, String directorySource) at HagsWeb.Library.Methods.AssetManager.AssetManager_Repository.GetAssets(String productId, AssetType assetType, Boolean cacheResult) at CompiledRazorTemplates.Dynamic.RazorEngine_1ef0d5a61e7f4d11a08dde21d73494fb.Execute() in B:\Projects\Hags_Dw915\Files\Templates\Designs\Hags2024\eCom\Product\Product.cshtml:line 267 at RazorEngine.Templating.TemplateBase.RazorEngine.Templating.ITemplate.Run(ExecuteContext context, TextWriter reader) at RazorEngine.Templating.RazorEngineCore.RunTemplate(ICompiledTemplate template, TextWriter writer, Object model, DynamicViewBag viewBag) at RazorEngine.Templating.RazorEngineService.RunCompile(ITemplateKey key, TextWriter writer, Type modelType, Object model, DynamicViewBag viewBag) at RazorEngine.Templating.DynamicWrapperService.RunCompile(ITemplateKey key, TextWriter writer, Type modelType, Object model, DynamicViewBag viewBag) at RazorEngine.Templating.RazorEngineServiceExtensions.<>c__DisplayClass16_0.<RunCompile>b__0(TextWriter writer) at RazorEngine.Templating.RazorEngineServiceExtensions.WithWriter(Action`1 withWriter) at RazorEngine.Templating.RazorEngineServiceExtensions.RunCompile(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.RazorTemplateBase<Dynamicweb.Rendering.RazorTemplateModel<Dynamicweb.Rendering.Template>> 2 @using System; 3 @using System.Globalization; 4 @using System.Collections.Generic; 5 @using System.Linq; 6 @using System.Web.Optimization; 7 @using HagsWeb.Library.Services.FileSystemService; 8 @using HagsWeb.Library.Utilities; 9 @using System.Text.RegularExpressions; 10 @using System.Text; 11 12 13 @* scripts required by this template - this snippet is rendered in the head tag of base.cshtml *@ 14 15 @SnippetStart("productScripts") 16 @* expand this for re-design debugging *@ 17 @* Scripts.Render("~/bundle/ProductFilter") *@ 18 19 @{ 20 string designBaseUrl = GetString("Template:DesignBaseUrl"); 21 string weglotHeader = System.Web.HttpContext.Current.Request.Headers["weglot-language"]; 22 } 23 24 <!--script type="text/javascript" src="@(designBaseUrl)assets/js/functions/variant-filter.js"></script--> 25 <script type="text/javascript" src="@(designBaseUrl)assets/js/functions/product-create-pdf.js?v=1.5"></script> 26 <script type="text/javascript" src="@(designBaseUrl)assets/js/libraries/wheel-zoom/wheel-zoom.min.js"></script> 27 28 @SnippetEnd("productScripts") 29 30 @* for this page we don't want the header to be positioned over the content *@ 31 @*SnippetStart("headerClass")@("in-flow")@SnippetEnd("headerClass")*@ 32 33 @* all the product model query code - sets up the models and variables used in this template *@ 34 @inherits Dynamicweb.Rendering.RazorTemplateBase<Dynamicweb.Rendering.RazorTemplateModel<Dynamicweb.Rendering.Template>> 35 @using Dynamicweb.Content.Items; 36 @using Dynamicweb.Ecommerce.Products; 37 @using HagsWeb.Library.Methods.AssetManager; 38 @using HagsWeb.Library.BusinessObjects.UsersLists; 39 @using HagsWeb.Library.Methods.AssetSearch; 40 @using HagsWeb.Library.Methods.Page; 41 @using HagsWeb.Library.Methods.ProductImages; 42 @using HagsWeb.Library.Methods.ProductProperties; 43 @using HagsWeb.Library.Methods.ProductFilter; 44 @using HagsWeb.Library.Services.IPService; 45 @using HagsWeb.Library.State; 46 @{ 47 Dynamicweb.Frontend.PageView thisPage = Dynamicweb.Frontend.PageView.Current() ?? Dynamicweb.Frontend.PageView.Current(); 48 Item areaItem = Item.GetItemById("Website_Settings", thisPage.Area.Item.Id); 49 string pageUrl = GetGlobalValue("Global:Request.Scheme") + "://" + GetGlobalValue("Global:Request.Host") + thisPage.SearchFriendlyUrl; 50 string themeTag = HagsPages.GetThemeByNavigationTag(GetGlobalValue("Global:Page.Top.ID")); // gets the page ID at the top of the tree this page sits on. 51 var siteSection = HagsPages.GetSiteSection(thisPage.AreaID, thisPage.ID); 52 string salesPhoneNumber = areaItem["Telephone"].ToString(); 53 54 string productNumber = GetString("Ecom:Product.Number"); // The Product NUMBER 55 //int areaId = GetGlobalValue("Global:Area.ID"); 56 57 string canonicalProductUrl = GetGlobalValue("Global:Request.Scheme") + "://" + GetGlobalValue("Global:Request.Host") + HagsWeb.Library.Utilities.DWUtilities.GetProductSearchResultUrl("ProductNumber=" + productNumber, false, "LANG1", thisPage.AreaID); 58 canonicalProductUrl = "<link rel=\"canonical\" href=\"" + canonicalProductUrl + "\" />"; 59 //override the canonical tag added by hagspages 60 Pageview.Meta.AddTag("customCan", canonicalProductUrl); 61 Pageview.Meta.Title = GetString("Ecom:Product.Name") + " | HAGS"; 62 63 string currentCulture = GetGlobalValue("Global:Area.LongLang"); //en-GB, sv-SE 64 string currentCountry = currentCulture.Substring(currentCulture.Length - 2); // GB, SE 65 string currentlanguage = currentCulture.Substring(0, 2); // en, sv "de";// 66 string ipPriceAllowed = string.Empty; 67 68 if (thisPage.AreaID == 2 || thisPage.AreaID == 7) // Sweden and UK 69 { 70 ipPriceAllowed = IPCheck.CountryPriceAllowed(currentCountry); //ZZZ,Hags_GB,Hags_SE and Hags_, Anon_GB, Anon_SE network range checker(Web.config) 71 } 72 73 IEnumerable<ProductAsset> assets = AssetManager_Repository.GetAssets(productNumber, AssetType.All, true); 74 IEnumerable<ProductAsset> allImages = assets.Where(n => n.Index == AssetTypeEnum.ToFriendlyAssetName(AssetType.Images)).ToList(); 75 76 var imagesCount = assets.Select(n => n).Where(n => n.Index == AssetTypeEnum.ToFriendlyAssetName(AssetType.Images)).Count(); 77 var brochCount = assets.Select(n => n).Where(n => n.Index == AssetTypeEnum.ToFriendlyAssetName(AssetType.Brochures)).Count(); 78 79 // New sorting for Product Images, thumbs and hiResDownloads for Zoom Images 80 Tuple<SortedList<int, string[,]>, IEnumerable<ProductAsset>> mainProductImages = ProductImages.MarshallZoomImages(allImages, productNumber); 81 SortedList<int, string[,]> zoomList = mainProductImages.Item1; 82 IEnumerable<ProductAsset> hiResDownloads = mainProductImages.Item2; 83 84 85 // The users Product Collection in session 86 List<ProductCollectionItem> productCollectionItems = SessionManager.UsersMyProductCollection != null ? SessionManager.UsersMyProductCollection : new List<ProductCollectionItem>(); 87 bool isProductCollection = productCollectionItems.Any(n => n.ProductNumber == productNumber); 88 89 // users Product Collection 90 string collectionData = string.Format("CCAddToMyLists={0}&CCAddToListVariantID={1}&CCAreaID={2}&CCAddToListCulture={3}&CCAddToListLanguageID={4}#{5}", 91 GetString("Ecom:Product.Number"), GetString("Ecom:Product.VariantID"), GetGlobalValue("Global:Area.ID"), GetGlobalValue("Global:Area.LongLang"), @GetString("Ecom:Product.LanguageID"), siteSection); 92 93 94 // New Age Ranges. Some Template Tags dont work very well in upgraded DW version 9.7.2 95 List<string> ageRanges = new List<string>(); 96 if (!string.IsNullOrEmpty(GetString("Ecom:Product:Field.AgeRange"))) 97 { 98 ageRanges = ProductAgeRanges.GetAgeRanges(GetString("Ecom:Product:Field.AgeRange"), GetString("Ecom:Product.LanguageID")); 99 } 100 101 // New Product Functions. Some Template Tags dont work very well in upgraded DW version 9.7.2 102 List<ResultField> productFunctions = new List<ResultField>(); 103 if (!string.IsNullOrEmpty(GetString("Ecom:Product:Field.ProductFunctions"))) 104 { 105 productFunctions = ProductFieldValues.GetProductFieldOptions(GetString("Ecom:Product:Field.ProductFunctions"), "ProductFunctions", GetString("Ecom:Product.LanguageID")); 106 } 107 108 // For filtering the variants of this product 109 ResultSet colourOptions = new ResultSet(); 110 ResultSet materialOptions = new ResultSet(); 111 ResultSet anchoringOptions = new ResultSet(); 112 ResultSet optionOptions = new ResultSet(); 113 114 115 string selectedColourVariant = string.Empty; 116 string selectedAnchoringVariant = string.Empty; 117 string selectedAnchoringVariantId = string.Empty; 118 string selectedAnchoringIcon = string.Empty; 119 string selectedMaterialVariant = string.Empty; 120 string selectedOptionVariant = string.Empty; 121 //List<VariantOption> selectedProductOptions = new List<VariantOption>(); 122 123 124 125 if (GetInteger("Ecom:Product.VariantCount") > 0) 126 { 127 foreach (var variantGroup in GetLoop("VariantGroups").Where(n => n.GetString("Ecom:VariantGroup.ID") != "D")) // Remove All Date Variants 128 { 129 int optionsCount = variantGroup.GetLoop("VariantAvailableOptions").Count(); 130 131 if (optionsCount > 0) 132 { 133 if (!string.IsNullOrEmpty("Ecom:Product.SelectedVariantComboID")) // optionsCount == 1 134 { 135 foreach (var availableOption in variantGroup.GetLoop("VariantAvailableOptions")) 136 { 137 138 if (variantGroup.GetString("Ecom:VariantGroup.ID") == "S55") 139 { 140 colourOptions.Name = variantGroup.GetString("Ecom:VariantGroup.Name"); 141 142 if (availableOption.GetString("Ecom:VariantOption.Name") != "Not applicable") 143 { 144 145 colourOptions.Results.Add(new ResultField() { Name = availableOption.GetString("Ecom:VariantOption.Name"), Value = availableOption.GetString("Ecom:VariantOption.ID"), Sort = availableOption.GetInteger("Ecom:VariantOption.SortOrder"), Disabled = false }); 146 147 if (availableOption.GetBoolean("Ecom:VariantOption.Selected")) 148 { 149 selectedColourVariant = availableOption.GetString("Ecom:VariantOption.Name"); 150 } 151 } 152 } 153 if (variantGroup.GetString("Ecom:VariantGroup.ID") == "ATP1") 154 { 155 materialOptions.Name = variantGroup.GetString("Ecom:VariantGroup.Name"); 156 157 if (availableOption.GetString("Ecom:VariantOption.Name") != "Not applicable") 158 { 159 materialOptions.Results.Add(new ResultField() { Name = availableOption.GetString("Ecom:VariantOption.Name"), Value = availableOption.GetString("Ecom:VariantOption.ID"), Sort = availableOption.GetInteger("Ecom:VariantOption.SortOrder"), Disabled = false }); 160 161 if (availableOption.GetBoolean("Ecom:VariantOption.Selected")) 162 { 163 selectedMaterialVariant = availableOption.GetString("Ecom:VariantOption.Name"); 164 } 165 } 166 } 167 if (variantGroup.GetString("Ecom:VariantGroup.ID") == "ATP3") 168 { 169 anchoringOptions.Name = variantGroup.GetString("Ecom:VariantGroup.Name"); 170 171 if (availableOption.GetString("Ecom:VariantOption.Name") != "Not applicable") 172 { 173 anchoringOptions.Results.Add(new ResultField() { Name = availableOption.GetString("Ecom:VariantOption.Name"), Value = availableOption.GetString("Ecom:VariantOption.ID"), Sort = availableOption.GetInteger("Ecom:VariantOption.SortOrder"), Disabled = false }); 174 175 if (availableOption.GetBoolean("Ecom:VariantOption.Selected")) 176 { 177 selectedAnchoringVariant = availableOption.GetString("Ecom:VariantOption.Name"); 178 selectedAnchoringVariantId = availableOption.GetString("Ecom:VariantOption.ID"); 179 selectedAnchoringIcon = availableOption.GetString("Ecom:VariantOption.ID") + ".png"; 180 } 181 } 182 } 183 if (variantGroup.GetString("Ecom:VariantGroup.ID") == "ATP4") 184 { 185 optionOptions.Name = variantGroup.GetString("Ecom:VariantGroup.Name"); 186 187 if (availableOption.GetString("Ecom:VariantOption.Name") != "Not applicable") 188 { 189 optionOptions.Results.Add(new ResultField() { Name = availableOption.GetString("Ecom:VariantOption.Name"), Value = availableOption.GetString("Ecom:VariantOption.ID"), Sort = availableOption.GetInteger("Ecom:VariantOption.SortOrder"), Disabled = false }); 190 191 if (availableOption.GetBoolean("Ecom:VariantOption.Selected")) 192 { 193 selectedOptionVariant = availableOption.GetString("Ecom:VariantOption.Name"); 194 } 195 } 196 197 } 198 } 199 } 200 } 201 } 202 } 203 204 205 string assemblyInstructionsProductNumber = productNumber; 206 207 // Related Products are only assigned to Master Products, not Variant Products so we need the related Products from the Master to get the full list of 208 // Assembly Instructions 209 Product product = new ProductService().GetProductById(GetString("Ecom:Product.ID"), GetString("Ecom:Product.VariantID"), GetString("Ecom:Product.LanguageID")); 210 211 // Check if its a Master product. 212 if (!product.IsVariantMaster) 213 { 214 assemblyInstructionsProductNumber = new ProductService().GetProductsAndVariantsByProduct(product) 215 .FirstOrDefault<Product>(n => string.IsNullOrEmpty(n.VariantId)).Number; 216 } 217 218 // Check if its a Master product. 219 // Implementation of Variant Fallback overrides if no Variant is specified Original Product.cshtml is maintained in ProductV21TESTING.cshtml 220 221 //Tuple<string, string, string, string, string> optionsTuple; 222 string VariantId = string.Empty; 223 if (!string.IsNullOrEmpty(GetString("Ecom:Product.VariantID")) || !string.IsNullOrEmpty(GetString("Ecom:Product.ProductDefaultVariantComboId")) || !string.IsNullOrEmpty(GetString("Ecom:Product:Field.ProductVariantFallback"))) 224 { 225 VariantId = string.IsNullOrEmpty(GetString("Ecom:Product.VariantID")) ? GetString("Ecom:Product.ProductDefaultVariantComboId") : GetString("Ecom:Product.VariantID"); 226 227 // Implementation of Variant Fallback overrides if no Variant is specified Original Product.cshtml is maintained in ProductV21TESTING.cshtml 228 if (string.IsNullOrEmpty(VariantId)) 229 { 230 VariantId = GetString("Ecom:Product:Field.ProductVariantFallback"); 231 } 232 233 //optionsTuple = ProductFieldValues.GetProductOptions(VariantId, GetString("Ecom:Product.LanguageID")); 234 235 //selectedColourVariant = optionsTuple.Item1; 236 //selectedAnchoringVariant = optionsTuple.Item2; 237 //selectedMaterialVariant = optionsTuple.Item3; 238 //selectedOptionVariant = optionsTuple.Item4; 239 //selectedAnchoringIcon = optionsTuple.Item5; 240 //selectedProductOptions = optionsTuple.Item6; // used to filter related products by the variant values of this product 241 242 } 243 244 // Related Products and their Assembly Instructions 245 List<Product> relatedProducts = new List<Product>(); // Play Functions // Related products are now not required to be shown as a list of products. Gareth 17/02/2020 246 List<Product> relatedComponentProducts = new List<Product>(); 247 List<ProductAsset> relatedProductsAssemblyInstructions = new List<ProductAsset>(); 248 249 string variantOptions = selectedMaterialVariant + " " + selectedAnchoringVariant + " " + selectedOptionVariant + " " + selectedColourVariant; 250 251 if (GetInteger("Ecom:Product.RelatedCount") > 0) 252 { 253 // Play Functions // 254 if (GetLoop("ProductRelatedGroups").Where(n => n.GetString("Ecom:Product:RelatedGroup.Name") == "Product Modules") != null) 255 { 256 relatedProducts = ProductFilter.GetRelatedProducts(GetString("Ecom:Product.Number"), VariantId, "Product Modules", GetString("Ecom:Product.LanguageID")); 257 } 258 259 if (GetLoop("ProductRelatedGroups").Where(n => n.GetString("Ecom:Product:RelatedGroup.Name") == "Product Components") != null) 260 { 261 relatedComponentProducts = ProductFilter.GetRelatedProducts(assemblyInstructionsProductNumber, VariantId, "Product Components", GetString("Ecom:Product.LanguageID")); 262 //// Lookup Assembly Instructions Assets 263 foreach (Product relatedComponentProduct in relatedComponentProducts) 264 { 265 if (relatedComponentProduct != null) 266 { 267 List<ProductAsset> productAssemblyInstructions = AssetManager_Repository.GetAssets(relatedComponentProduct.Number, AssetType.AssemblyInstructions, true); 268 if (productAssemblyInstructions.Any()) 269 { 270 //List<ProductAsset> result = productAssemblyInstructions.Where(pa => !relatedProductsAssemblyInstructions.Any(pa2 => pa2.FileName == pa.FileName)).ToList(); 271 List<ProductAsset> result = productAssemblyInstructions 272 .Where(pa => !relatedProductsAssemblyInstructions.Any(pa2 => pa2.FileName.Substring(8, pa2.FileName.Length - 8) == pa.FileName.Substring(8, pa.FileName.Length - 8))).ToList(); 273 result.ForEach(n => n.RelatedProduct = productNumber); 274 relatedProductsAssemblyInstructions.AddRange(result); 275 } 276 } 277 } 278 } 279 } 280 } 281 282 @* these contain helpers for rendering futher down the page *@ 283 @inherits Dynamicweb.Rendering.RazorTemplateBase<Dynamicweb.Rendering.RazorTemplateModel<Dynamicweb.Rendering.Template>> 284 @using Dynamicweb.Rendering; 285 @using System; 286 @using System.Web; 287 @using System.Collections.Generic; 288 @using System.Linq; 289 @using Ionic.Zip; 290 @using System.IO; 291 @using System.Threading; 292 293 @helper GetButton(List<string> files, string sender, string productNumber) 294 { 295 var request = HttpContext.Current.Request.Form; 296 var response = HttpContext.Current.Response; 297 298 if (!string.IsNullOrEmpty(request["ProductNumber"])) 299 { 300 // Currently only used for Product Image download on results page - see also GetDownload.cshtml 301 // To do KOD extract this into a service in Library, also consider Hags\Application\Ajax\UsersProductCollection\UsersProductCollection.aspx.cs(398) 302 if ( files.Any() ) 303 { 304 try 305 { 306 var zipArchives = System.Web.HttpContext.Current.Server.MapPath("Files/System/UserDownloads/Zips"); 307 var transferFolder = System.Web.HttpContext.Current.Server.MapPath("Files/System/UserDownloads/Transfers"); 308 309 // empty the zipArchives folder of zips that are 30 mins old (if any) 310 var oldZips = new DirectoryInfo(zipArchives).EnumerateFiles().Where(f => f.CreationTime < DateTime.Now.AddMinutes(-30)).ToList(); 311 oldZips.ForEach(f => f.Delete()); 312 313 DirectoryInfo Folder = new DirectoryInfo(transferFolder); 314 // Occasionally some files are read only and cannot be deleted so change all files, remove readonly before the delete 315 Folder.EnumerateFiles().ToList().ForEach(file => file.Attributes = FileAttributes.Normal); 316 Directory.EnumerateFiles(transferFolder).ToList().ForEach(f => System.IO.File.Delete(f)); 317 318 // copy the selected files to the transferFolder and change from ReadOnly to try to prevent access to the path is denied error 319 files.ForEach(f => System.IO.File.Copy(f, Path.Combine(transferFolder, Path.GetFileName(f)), true)); 320 Folder.EnumerateFiles().ToList().ForEach(file => file.Attributes = FileAttributes.Normal); 321 322 // Set up our new zip folder 323 var downloadFileName = string.Format(request["ProductNumber"] +"_"+ request["ProductName"] +"_Bilder {0}.zip", DateTime.Now.ToString("dd-MM-yyyy-HH_mm_ss")); 324 // var downloadFileName = string.Format("Hags_Download_Pack-{0}.zip", DateTime.Now.ToString("dd-MM-yyyy-HH_mm_ss")); 325 326 //var zipLocationUrl = "Files/System/UserDownloads/Zips/" + downloadFileName; // Use this to return a link to the folder saved to disk 327 328 HttpContext.Current.Response.ContentType = "application/x-zip-compressed"; // Important - as is AppendHeader, not AddHeader 329 HttpContext.Current.Response.AppendHeader("Content-Disposition", "filename=" + downloadFileName); 330 331 using (var zip = new ZipFile()) 332 { 333 List<string> fileList = Directory.EnumerateFiles(transferFolder).ToList(); 334 //zip.AddDirectoryByName(subfolderName); 335 foreach (string file in fileList) 336 { 337 zip.AddFile(file, string.Empty); 338 } 339 340 // Save to the OutputStream 341 zip.Save(HttpContext.Current.Response.OutputStream); 342 // Or save the file to the file system using TransmitFile to stream the file without storing to memory 343 //zip.Save(zipArchives + "/" + downloadFileName); 344 } 345 346 // Transmit a file that was created on disk 347 //HttpContext.Current.Response.ContentType = "application/x-zip-compressed"; 348 //HttpContext.Current.Response.AppendHeader("Content-Disposition", "filename=" + downloadFileName); 349 //HttpContext.Current.Response.TransmitFile(zipArchives + "/" + downloadFileName); 350 351 352 353 } 354 catch (ZipException ze) 355 { 356 string message = ze + "ProductDownload/GetDownloadButton.cshtml ZipException download file error (" + sender + ") - Original File Count: " + files.Count() + "InnerEx: " + ze.InnerException + ""; 357 Dynamicweb.Logging.ILogger log = Dynamicweb.Logging.LogManager.Current.GetLogger("File Download Service"); 358 log.Info(message); 359 } 360 catch (System.IO.FileNotFoundException notFoundEx) 361 { 362 string message = notFoundEx + "../Templates/HagsModules/UsersAssetsSearch/ProductDownloads/GetDownloadButton.cshtml (" + sender + ") " + notFoundEx.Message + " - The File: " + notFoundEx.FileName +""; 363 Dynamicweb.Logging.ILogger log = Dynamicweb.Logging.LogManager.Current.GetLogger("File Download Service"); 364 log.Info(message); 365 } 366 catch (ThreadAbortException) 367 { 368 // A normal Thread abort after HttpContext.Current.Response.End(); we dont record it 369 } 370 catch (Exception ex) 371 { 372 string message = ex + "../Templates/HagsModules/UsersAssetsSearch/ProductDownloads/GetDownloadButton.cshtml (" + sender + ") " + ex.Message + " - The Inner Ex: " + ex.InnerException + ""; 373 Dynamicweb.Logging.ILogger log = Dynamicweb.Logging.LogManager.Current.GetLogger("File Download Service"); 374 log.Info(message); 375 } 376 finally 377 { 378 HttpContext.Current.Response.End(); 379 } 380 381 } 382 } 383 else 384 { 385 string buttonCaption = string.Empty; 386 if (sender == "Product") 387 { 388 buttonCaption = Translate("ImageDownloads", "Image Downloads"); 389 <button class="images-form btn btn--outline" role="button" 390 data-action-page="Product" 391 data-action-type="Button" 392 data-action-label="Image downloads" 393 data-action-value="@productNumber"> 394 @buttonCaption 395 </button> 396 } 397 if (sender == "AdvancedSearch") 398 { 399 buttonCaption = Translate("DownloadAll", "Download All"); 400 <button class="images-form btn btn--outline" role="button" data-action-type="" data-action-label=""> 401 @buttonCaption 402 </button> 403 } 404 405 406 } 407 } 408 409 410 411 @helper renderPageBreadcrumb(string thisUrl, string currentCulture, string productName, string variantOptions) { 412 413 string[] segments = Array.Empty<string>(); 414 Uri uri = new Uri(thisUrl); 415 if (uri.IsWellFormedOriginalString()) 416 { 417 segments = uri.Segments; 418 } 419 420 @* set up this so we can use it's title case method *@ 421 TextInfo thisTextInfo = new CultureInfo(currentCulture,false).TextInfo; 422 423 string first = segments.FirstOrDefault(); 424 string last = segments.LastOrDefault(); 425 426 if (!string.IsNullOrEmpty(productName)) 427 { 428 string stripSpaces = Regex.Replace(productName, @"\s+", " "); // some product names may have 2 or 3 spaces in them 429 productName = stripSpaces.Replace(" ", "-").ToLower(); 430 } 431 432 string concat = string.Empty; 433 434 StringBuilder sb = new StringBuilder(); 435 sb.Append("<ul class=\"product-nav product-nav--arrows\" role=\"list\">"); 436 437 438 foreach (var item in segments.Select((value,i)=>new{i,value})) 439 { 440 var index = item.i; 441 if (true) 442 { 443 string linkText = item.value.Replace("/",""); 444 concat += item.value; 445 446 if (segments.Length <= 2) // A shorthand URL like www.hags.com/hags-dragonfly or www.hags.de/hags-dragonfly 447 { 448 sb.Append("<li>" + thisTextInfo.ToTitleCase(linkText.Replace("-", " ")) + "</li>"); 449 } 450 // Request from the Product List with no Product Name 451 else if (item.value.Equals(last, StringComparison.CurrentCultureIgnoreCase) && string.IsNullOrEmpty(productName)) 452 { 453 sb.Append("<li><a href='" + concat.TrimEnd('/') + "' class=''> " + thisTextInfo.ToTitleCase(linkText.Replace("-", " ")) + "</a></li>"); 454 break; 455 } 456 // will be either the master product or the variant 457 else if (item.value.Equals(last, StringComparison.CurrentCultureIgnoreCase) && !item.value.Equals(productName, StringComparison.CurrentCultureIgnoreCase)) 458 { 459 linkText = variantOptions.Trim().Replace("Not applicable", "").ToLower(); 460 461 462 sb.Append("<li><a href='" + concat.TrimEnd('/') + "' class=''> " + thisTextInfo.ToTitleCase(linkText.Replace("-", " ")) + "</a></li>"); 463 } 464 else if (index == 2) 465 { 466 sb.Append("<li><a href='" + concat.TrimEnd('/') + "' class=''>Home</a></li>"); 467 } else if ( index > 2 ) { 468 sb.Append("<li><a href='" + concat.TrimEnd('/') + "' class=''>" + thisTextInfo.ToTitleCase(linkText.Replace("-", " ")) + "</a></li>"); 469 } 470 } 471 } 472 473 sb.Append("</ul>"); 474 475 @(sb.ToString()) 476 } 477 478 @* canonical debug code *@ 479 @* 480 481 IncludeFile("../includes/product-canonical-debug.cshtml") 482 483 @if ( System.Web.HttpContext.Current.Request["dc"] == "yes" ) 484 { 485 string currentResult = HagsWeb.Library.Utilities.DWUtilities.GetProductSearchResultUrl("ProductNumber=" + productNumber, false, "LANG1", thisPage.AreaID); 486 int areaId = thisPage.AreaID; 487 @debugCanonical(currentResult, productNumber, areaId) 488 } 489 490 *@ 491 492 493 <article class="flow"> 494 495 <nav class="breadcrumb"> 496 <div class="wrapper"> 497 @renderPageBreadcrumb(pageUrl, GetGlobalValue("Global:Area.LongLang"), @GetString("Ecom:Product.Name"), variantOptions) 498 </div> 499 </nav> 500 501 502 <section class="product-header"> 503 504 <div class="wrapper flow"> 505 <h1>@GetString("Ecom:Product.Name")</h1> 506 507 @using System.Web; 508 @using System.Globalization; 509 510 @{ 511 bool centralStock = GetBoolean("Ecom:Product:Field.CentralStock"); 512 bool swedishStock = GetBoolean("Ecom:Product:Field.SwedishStock"); 513 string ipAddress = HttpContext.Current.Request.ServerVariables["remote_addr"]; 514 string weglotLang = System.Web.HttpContext.Current.Request.Headers["weglot-language"]; 515 string productNumberDisplay = productNumber; 516 string formattedCurrency = GetInteger("Ecom:Product.DBPrice").ToString("C", new CultureInfo("sv-SE")); 517 } 518 @if ( weglotLang == "se" || weglotLang == "da" ) 519 { 520 if ( swedishStock ) 521 { 522 productNumberDisplay = productNumber + "-1"; 523 } 524 } 525 else 526 { 527 if (centralStock) 528 { 529 productNumberDisplay = productNumberDisplay + "-2"; 530 } 531 } 532 533 534 <p class="product-number">@productNumberDisplay</p> 535 536 @* 537 <!-- central: @centralStock swedish: @swedishStock --> 538 <!-- Integer DB price: @GetInteger("Ecom:Product.DBPrice") --> 539 <!-- String Price Formatted: @GetString("Ecom:Product.Price.PriceFormatted") --> 540 <!-- String Price: @GetString("Ecom:Product.Price") --> 541 <!-- IP address: @ipAddress --> 542 <!-- Weglot language: @weglotLang --> 543 <!-- formatted currency: @formattedCurrency --> 544 *@ 545 546 547 </div> 548 549 <div class="wrapper"> 550 551 <div class="fc-zoom"> 552 @*Zoom Product Images*@ 553 @if (zoomList.Count > 0) 554 555 { 556 <div class="fc-zoom__view" id="js-zoom-view-1"> 557 <div class="fc-zoom__gripper"> </div> 558 <div class="fc-zoom__target" id="zoom-target-1"> 559 @{ 560 var i = 0; 561 string resizeUrl = "/Admin/Public/GetImage.ashx?Image="; 562 string resizeOptions = "&Crop=0&Format=jpg&Height=350&Compression=75"; 563 } 564 @foreach (var zoomSet in zoomList) 565 { 566 string[,] imgSet = zoomSet.Value; 567 string imgId = string.Format("img_0{0}", zoomSet.Key); 568 string imageUrl = resizeUrl + imgSet[0, 2] + resizeOptions; 569 570 571 if (i == 0) 572 { 573 574 <img class="fc-zoom__img active" id="zoom-full-image-@i" src="@imgSet[0, 2]" data-zoom-image="@imgSet[0, 2]" alt="@GetString("Ecom:Product.Name")"> 575 } 576 else 577 { 578 <img class="fc-zoom__img" id="zoom-full-image-@i" src="@imgSet[0, 2]" data-zoom-image="@imgSet[0, 2]" alt="@GetString("Ecom:Product.Name")"> 579 } 580 i++; 581 } 582 583 </div> 584 585 <button class="fc-zoom__button fc-zoom__button--in reel-cards__btn" id="zoom-toggle"> 586 <span class="visually-hidden">Toggle Zoom</span> 587 <span class="fc-zoom__icon fc-zoom__icon--in"> 588 <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 212 212" class="h24-icon h24-icon--bigger"><path fill="currentColor" fill-rule="evenodd" d="M106 6c55.193 0 100 44.807 100 100s-44.807 100-100 100S6 161.193 6 106 50.807 6 106 6Zm0 5.333c-26.124 0-49.792 10.603-66.928 27.74C21.936 56.207 11.333 79.875 11.333 106c0 26.124 10.603 49.792 27.74 66.928 17.135 17.136 40.803 27.739 66.927 27.739 26.124 0 49.792-10.603 66.928-27.74 17.136-17.135 27.739-40.803 27.739-66.927 0-26.124-10.603-49.792-27.74-66.928C155.793 21.936 132.125 11.333 106 11.333Zm14.215 100.332 38.614 38.615v-28.357a5 5 0 0 1 10 0v40c0 .389-.045.767-.128 1.13a5.002 5.002 0 0 1-4.93 4.163h-40a5 5 0 1 1 0-10h27.852l-38.48-38.48a5 5 0 0 1 7.072-7.071ZM89.738 43.201a5 5 0 1 1 0 10H61.885l38.48 38.48a5 5 0 0 1-7.072 7.07L54.68 60.138v28.357a5 5 0 1 1-10 0v-40c0-.389.045-.767.128-1.13a5.002 5.002 0 0 1 4.93-4.163h40Z"/></svg> 589 </span> 590 <span class="fc-zoom__icon fc-zoom__icon--out"> 591 <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 212 212" class="h24-icon h24-icon--smaller"><path fill="currentColor" fill-rule="evenodd" d="M106 6c55.193 0 100 44.807 100 100s-44.807 100-100 100S6 161.193 6 106 50.807 6 106 6Zm0 5.333c-26.124 0-49.792 10.603-66.928 27.74C21.936 56.207 11.333 79.875 11.333 106c0 26.124 10.603 49.792 27.74 66.928 17.135 17.136 40.803 27.739 66.927 27.739 26.124 0 49.792-10.603 66.928-27.74 17.136-17.135 27.739-40.803 27.739-66.927 0-26.124-10.603-49.792-27.74-66.928C155.793 21.936 132.125 11.333 106 11.333Zm50.738 97.868a5 5 0 0 1 0 10h-27.853l38.48 38.48a5 5 0 1 1-7.072 7.07l-38.614-38.614v28.357a5 5 0 1 1-10 0v-40c0-.389.045-.767.128-1.13a5.002 5.002 0 0 1 4.93-4.163h40ZM53.215 45.665 91.829 84.28V55.923a5 5 0 1 1 10 0v40c0 .389-.045.767-.128 1.13a5.002 5.002 0 0 1-4.93 4.163h-40a5 5 0 0 1 0-10h27.852l-38.48-38.48a5 5 0 0 1 7.072-7.071Z"/></svg> 592 </span> 593 </button> 594 </div> 595 596 <div class="reel-thumbs fc-zoom__thumbs" id="zoom-gallery"> 597 598 <button 599 class="reel-cards__btn reel-cards__btn--prev" 600 data-action-page="Product" 601 data-action-type="Button" 602 data-action-label="Gallery prev" 603 data-action-value="@productNumber"> 604 <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 212 212" class="h24-icon h24-icon--up"><path fill="currentColor" fill-rule="evenodd" d="M106 6c55.193 0 100 44.807 100 100s-44.807 100-100 100S6 161.193 6 106 50.807 6 106 6Zm0 5.333c-26.124 0-49.792 10.603-66.928 27.74C21.936 56.207 11.333 79.875 11.333 106c0 26.124 10.603 49.792 27.74 66.928 17.135 17.136 40.803 27.739 66.927 27.739 26.124 0 49.792-10.603 66.928-27.74 17.136-17.135 27.739-40.803 27.739-66.927 0-26.124-10.603-49.792-27.74-66.928C155.793 21.936 132.125 11.333 106 11.333Zm0 67.467c4.307 0 8.347 2.08 10.847 5.587l8.714 12.197.739 1.034 1.114 1.559.744 1.042 1.116 1.561.741 1.038 14.745 20.642c2.14 2.993 1.44 7.16-1.553 9.3-2.994 2.14-7.16 1.44-9.3-1.553L106 92.133l-27.907 39.074c-2.14 2.993-6.306 3.693-9.3 1.553-2.993-2.14-3.693-6.307-1.553-9.3l14.745-20.642.741-1.038 1.116-1.561.744-1.042 1.114-1.559.739-1.034 8.714-12.197A13.319 13.319 0 0 1 106 78.8Z"/></svg> 605 <span class="visually-hidden">@Translate("page_Previous", "Previous")</span> 606 </button> 607 608 <div class="reel-thumbs__viewport"> 609 610 <div class="fc-zoom__thumbs-list reel-thumbs__container"> 611 @{ i = 0; } 612 @foreach (var zoomSet in zoomList) 613 { 614 string[,] imgSet = zoomSet.Value; 615 string imgId = string.Format("img_0{0}", zoomSet.Key); 616 <div class="reel-thumbs__frame"> 617 <a class="fc-zoom__link" href="@imgSet[0, 1]" data-image-target="zoom-full-image-@i" data-image="" data-zoom-image="@imgSet[0, 2]"> 618 <img class="fc-zoom__thumb" src="@imgSet[0, 0]" alt="@GetString("Ecom:Product.Name")"> 619 </a> 620 </div> 621 i++; 622 623 } 624 </div> 625 626 </div> 627 628 <button 629 class="reel-cards__btn reel-cards__btn--next" 630 data-action-page="Product" 631 data-action-type="Button" 632 data-action-label="Gallery next" 633 data-action-value="@productNumber"> 634 <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 212 212" class="h24-icon h24-icon--down"><path fill="currentColor" fill-rule="evenodd" d="M106 6c55.193 0 100 44.807 100 100s-44.807 100-100 100S6 161.193 6 106 50.807 6 106 6Zm0 5.333c-26.124 0-49.792 10.603-66.928 27.74C21.936 56.207 11.333 79.875 11.333 106c0 26.124 10.603 49.792 27.74 66.928 17.135 17.136 40.803 27.739 66.927 27.739 26.124 0 49.792-10.603 66.928-27.74 17.136-17.135 27.739-40.803 27.739-66.927 0-26.124-10.603-49.792-27.74-66.928C155.793 21.936 132.125 11.333 106 11.333Zm37.207 68.707c2.993 2.14 3.693 6.307 1.553 9.3l-14.745 20.642-.741 1.038-1.116 1.562-.744 1.041-10.567 14.79A13.319 13.319 0 0 1 106 134c-4.307 0-8.347-2.08-10.847-5.586l-10.567-14.79-.744-1.042-1.116-1.562-.741-1.038L67.24 89.34c-2.14-2.993-1.44-7.16 1.553-9.3 2.994-2.14 7.16-1.44 9.3 1.554L106 120.667l14.79-20.708.834-1.168 12.283-17.197c2.14-2.994 6.306-3.694 9.3-1.554Z"/></svg> 635 <span class="visually-hidden">@Translate("page_Next", "Next")</span> 636 </button> 637 638 639 640 </div> 641 } 642 </div> 643 644 645 </section> 646 647 648 <div class="page-intro wrapper"> 649 650 <div class="page-intro__copy flow"> 651 652 <div class="cluster"> 653 @* add to collection button *@ 654 @if (isProductCollection) 655 { 656 <button type="button" class="btn btn--outline print-hide" data-removeproductlist="@productNumber" data-addproductlist=""> 657 @Translate("RemoveFromCollection", "Remove from my Collection") 658 </button> 659 } 660 else 661 { 662 <button 663 type="button" 664 class="btn btn--outline print-hide" 665 data-removeproductlist="" 666 data-addproductlist="@collectionData" 667 data-action-page="Product" data-action-type="button" data-action-label="Add to collection" data-action-value="@productNumber"> 668 @Translate("AddToCollection", "Add to my collection") 669 </button> 670 } 671 672 @* download images button *@ 673 @if (hiResDownloads.Count() > 0) 674 { 675 List <string> fileList = new List<string>(); 676 foreach (var file in hiResDownloads) 677 { 678 fileList.Add(file.FullPath); 679 } 680 <form method="post" id="downloadImagesForm"> 681 <input type="hidden" name="ProductNumber" value="@productNumber" /> 682 <input type="hidden" name="ProductName" value="@GetString("Ecom:Product.Name")" /> 683 @GetButton(fileList, "Product", productNumber) 684 </form> 685 } 686 687 @* PDF Product sheet button *@ 688 @{ 689 string printShout = Translate("SaveOrPrint", "Save or Print your Product PDF "); 690 string productId = @GetString("Ecom:Product.ID"); 691 string productVariantId = @GetString("Ecom:Product.VariantID"); 692 } 693 <button type="button" id="productSheetButton" data-target="#CreateProductPdf" 694 name="productPublishing" data-productid="@productId" data-productnumber="@productNumber" 695 data-variantid="@productVariantId" data-open-modal="#CreateProductPdf" data-request="technicalsheet" data-shout="@printShout" 696 class="btn btn--outline" 697 data-action-page="Product" data-action-type="button" data-action-label="Create product PDF" data-action-value="@productNumber"> 698 @Translate("ProductSheet", "PDF Product Sheet") 699 </button> 700 701 702 </div> 703 704 @*if (!string.IsNullOrWhiteSpace(GetString("Ecom:Product.ShortDescription"))) 705 { 706 <p>@GetString("Ecom:Product.ShortDescription")</p> 707 } 708 *@ 709 710 @if (!string.IsNullOrWhiteSpace(GetString("Ecom:Product.LongDescription"))) 711 { 712 @* 713 string paragraph = GetString("Ecom:Product.LongDescription"); 714 string[] paragraphs = paragraph.Split(new[] { '.' }, StringSplitOptions.RemoveEmptyEntries); 715 foreach (var p in paragraphs) 716 { 717 <p>@p.Trim().</p> 718 } 719 *@ 720 <p>@GetString("Ecom:Product.LongDescription")</p> 721 722 } 723 724 <div class="cluster" title="@Translate(" Anchoring", "Anchoring"): @selectedAnchoringVariant"> 725 726 @if ( GetBoolean("Ecom:Product:Field.CentralStock") && (weglotLang != "se" && weglotLang != "da") ) 727 { 728 <div class="product-icon" title="Leverans ex lager från Sverige"> 729 <img class="product-icon__icon" src="/Files/Images/Other/Playground box/Lorry.jpg" alt="Leverans ex lager från Sverige" /> 730 <p>Fast Delivery</p> 731 </div> 732 } 733 734 @if ( (weglotLang == "se" || weglotLang == "da") && swedishStock ) 735 { 736 <div class="product-icon" title="Leverans ex lager från Sverige"> 737 <img class="product-icon__icon" src="/Files/Images/Other/Playground box/Lorry.jpg" alt="Leverans ex lager från Sverige" /> 738 <p>Fast Delivery</p> 739 </div> 740 } 741 742 743 744 @if (!string.IsNullOrWhiteSpace(selectedAnchoringIcon ?? selectedAnchoringVariant)) 745 { 746 747 <div class="product-icon"> 748 <img class="product-icon__icon" src="Files/Templates/Designs/HagsCore/res/img/icons/anchoring/@selectedAnchoringIcon" alt="@selectedAnchoringVariant" /> 749 @selectedAnchoringVariant 750 </div> 751 } 752 753 </div> 754 755 <p> 756 @(selectedMaterialVariant != "" ? selectedMaterialVariant + " - " : "") 757 @(selectedOptionVariant != "" ? selectedOptionVariant + " - " : "") 758 @(@selectedColourVariant != "" ? selectedColourVariant : "") 759 </p> 760 761 @using System.Web; 762 @using System.Globalization; 763 @using System.IO; 764 @using System.Linq; 765 @using System.Net; 766 @using System.Configuration; 767 768 @using System.Web; 769 @using System.IO; 770 @using System.Linq; 771 @using System.Net; 772 @using System.Configuration; 773 774 @functions { 775 776 public string maxMindIpCheck(string ipToCheck) { 777 778 string apiKey = "1146064"; 779 string apiSecret = "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"; 780 781 string encodedKey = WebUtility.UrlEncode(apiKey); 782 string encodedSecret = WebUtility.UrlEncode(apiSecret); 783 784 string apiResponse = ""; 785 string authHeader = ""; 786 string requestBody = ""; 787 bool requestError = false; 788 789 string countryReturn = ""; 790 791 string apiUrl = "https://geoip.maxmind.com/geoip/v2.1/country/" + ipToCheck; 792 793 try 794 { 795 HttpWebRequest apiRequest = (HttpWebRequest)WebRequest.Create(apiUrl); 796 apiRequest.Method = "GET"; 797 apiRequest.Accept = "application/json"; 798 string credentials = Convert.ToBase64String(Encoding.ASCII.GetBytes($"{encodedKey}:{encodedSecret}")); 799 //string credentials = consumerKey + ":" + consumerSecret; 800 apiRequest.Headers["Authorization"] = "Basic " + credentials; 801 802 // Get the response 803 using (var response = (HttpWebResponse)apiRequest.GetResponse()) 804 { 805 using (var reader = new StreamReader(response.GetResponseStream())) 806 { 807 apiResponse = reader.ReadToEnd(); // Return the response as a string 808 } 809 } 810 } 811 812 catch (Exception ex) 813 { 814 // Handle any errors 815 apiResponse = "ERROR ** " + ex.Message; 816 requestError = true; 817 } 818 819 if ( !requestError ) { 820 821 // convert the woo json into an object 822 Newtonsoft.Json.Linq.JToken apiObject = Newtonsoft.Json.Linq.JToken.Parse(apiResponse); 823 824 var countryObj = apiObject["country"]; 825 countryReturn = countryObj["iso_code"]?.ToString(); 826 827 } 828 829 return countryReturn; 830 831 } 832 833 public string extremeIpLookup(string ipAddress) { 834 835 string ipLookupKey = ConfigurationManager.AppSettings["ExtremeIpLookupApiKey"].ToString(); 836 string ipLookupUrl = "http://extreme-ip-lookup.com/json/" + ipAddress + "?key=" + ipLookupKey; 837 string ipLookupError = ""; 838 string ipCountryCode = ""; 839 840 841 HttpWebRequest ipLookupRequest = (HttpWebRequest)WebRequest.Create(ipLookupUrl); 842 ipLookupRequest.Method = "GET"; // Set method to GET 843 ipLookupRequest.ContentType = "application/json"; 844 845 try 846 { 847 // Get the response from the API 848 using (HttpWebResponse ipLookupResponse = (HttpWebResponse)ipLookupRequest.GetResponse()) 849 { 850 // Check if the response is OK 851 if (ipLookupResponse.StatusCode == HttpStatusCode.OK) 852 { 853 // Read the response stream 854 using (StreamReader reader = new StreamReader(ipLookupResponse.GetResponseStream())) 855 { 856 // Parse the JSON response 857 string jsonResponse = reader.ReadToEnd(); 858 859 // Parse JSON using JObject (from Newtonsoft.Json.Linq) 860 Newtonsoft.Json.Linq.JObject jsonObject = Newtonsoft.Json.Linq.JObject.Parse(jsonResponse); 861 862 // Extract a specific value (assuming the JSON has a field named "desiredField") 863 ipCountryCode = (string)jsonObject["countryCode"]; 864 ipCountryCode = ipCountryCode.ToLower(); 865 } 866 } 867 } 868 } 869 870 catch (Exception ex) 871 { 872 // Handle any errors 873 //set default to au 874 ipCountryCode = ""; 875 ipLookupError = ex.Message; 876 } 877 878 return ipCountryCode; 879 880 } 881 882 } 883 884 885 886 @{ 887 //string ipAddress = HttpContext.Current.Request.ServerVariables["remote_addr"]; 888 //string weglotLang = System.Web.HttpContext.Current.Request.Headers["weglot-language"]; 889 //string formattedCurrency = GetInteger("Ecom:Product.DBPrice").ToString("C", new CultureInfo("sv-SE")); 890 891 892 bool showPrice = false; 893 string ipCountryCode = ""; 894 var initialRequest = HttpContext.Current.Request; 895 896 if ( (weglotLang == "se") ) 897 { 898 899 //check if the show prices cookie is set 900 HttpCookie spCookieGet = initialRequest.Cookies["hags-sp"]; 901 902 if ( spCookieGet != null ) 903 { 904 if ( spCookieGet.Value == "true" ) { 905 showPrice = true; 906 } 907 } 908 909 //if show price is still false after cookie check do the IP lookup 910 if ( !showPrice ) 911 { 912 913 ipCountryCode = maxMindIpCheck(ipAddress).ToLower(); 914 915 if ( ipCountryCode == "se" ) { 916 showPrice = true; 917 } 918 } 919 } 920 921 } 922 923 924 @if ( showPrice ) { 925 926 <p> 927 <span class="ts-3">@formattedCurrency</span> <span>(Excluding VAT)</span> 928 </p> 929 930 } 931 932 @if ( !showPrice && weglotLang != "se") 933 { 934 <p style="color: #eee;">@(ipCountryCode)</p> 935 } 936 937 @* 938 <!-- IP address: @ipAddress --> 939 <!-- Weglot language: @weglotLang --> 940 <!-- formatted currency: @formattedCurrency --> 941 *@ 942 943 </div> 944 </div> 945 946 947 948 <section> 949 <div class="wrapper"> 950 951 <div class="center-copy"> 952 953 @{ 954 string[] badges = GetString("Ecom:Product:Field.EnvironmentalBadge.Value").Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries).ToArray(); 955 } 956 <div> 957 <ul class="badges"> 958 @foreach (var badge in badges) 959 { 960 string altText = ""; 961 962 if (badge == "NSEL") 963 { 964 altText = Translate("CertifiedNordicSwan", "Certified by Nordic Swan"); 965 } 966 967 if ( badge == "BVB8" ) { 968 altText = Translate("BVBGradeAccepted", "Assessed by Byggvarubedömningen, Grade: Accepted"); 969 } 970 971 if ( badge == "BVB7" ) { 972 altText = Translate("BVBGradeRecommended", "Assessed by Byggvarubedömningen, Grade: Recommended"); 973 } 974 975 if ( badge == "SH1" ) { 976 altText = Translate("SundaHusGradeB", "Assessed by SundaHus, Grade: B"); 977 } 978 979 if ( badge == "SH2" ) { 980 altText = Translate("SundaHusGradeA", "Assessed by SundaHus, Grade: A"); 981 } 982 <li class="badges__item"><img src="@(designBaseUrl)assets/img/badges/@(badge).png" alt="@altText" title="@altText" /></li> 983 } 984 </ul> 985 </div> 986 987 <div class="accordians"> 988 @if (!string.IsNullOrEmpty(GetString("Ecom:Product:Field.PlayEnablers"))) 989 { 990 string[] playEnablers = GetString("Ecom:Product:Field.PlayEnablers.Value").Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries).ToArray(); 991 992 //string[] playEnablers = ("1,2,3,7,8,9,10").Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries).ToArray(); 993 994 var playCategories = new Dictionary<string, bool> { }; 995 996 var playEnablersMap = new Dictionary<string, string> 997 { 998 { "1","Significant challenge" }, 999 { "2","Ground level access" }, 1000 { "3","Passive access" }, 1001 { "4","Multi-sensory" }, 1002 { "5","Sight not required" }, 1003 { "6","Hearing not required" }, 1004 { "7","Low cognitive demand" }, 1005 { "8","Adult accessible" }, 1006 { "9","Calming" }, 1007 { "10","Solitary Play" } 1008 }; 1009 1010 1011 1012 <section class="accordian"> 1013 <div class="wrapper"> 1014 <h3> 1015 <button id="accordian-spec" aria-expanded="true" aria-controls="accordian-spec-panel" type="button" class="accordian__button" data-action-page="Product" data-action-type="Text block expand" data-action-label="Experiences" data-action-value="@productNumber">Play Enablers<span class="accordian__icon accordian__icon--close" aria-hidden="true"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 212 212" class="h24-icon h24-icon--minus"><path fill="currentColor" fill-rule="evenodd" d="M106 6c55.193 0 100 44.807 100 100s-44.807 100-100 100S6 161.193 6 106 50.807 6 106 6Zm0 5.333c-26.124 0-49.792 10.603-66.928 27.74C21.936 56.207 11.333 79.875 11.333 106c0 26.124 10.603 49.792 27.74 66.928 17.135 17.136 40.803 27.739 66.927 27.739 26.124 0 49.792-10.603 66.928-27.74 17.136-17.135 27.739-40.803 27.739-66.927 0-26.124-10.603-49.792-27.74-66.928C155.793 21.936 132.125 11.333 106 11.333Zm28.772 87.504a6.5 6.5 0 0 1 6.5 6.5v1a6.5 6.5 0 0 1-6.5 6.5h-57a6.5 6.5 0 0 1-6.5-6.5v-1a6.5 6.5 0 0 1 6.5-6.5h57Z"/></svg></span><span class="accordian__icon accordian__icon--open" aria-hidden="true"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 212 212" class="h24-icon h24-icon--plus"><path fill="currentColor" fill-rule="evenodd" d="M106 6c55.193 0 100 44.807 100 100s-44.807 100-100 100S6 161.193 6 106 50.807 6 106 6Zm0 5.333c-26.124 0-49.792 10.603-66.928 27.74C21.936 56.207 11.333 79.875 11.333 106c0 26.124 10.603 49.792 27.74 66.928 17.135 17.136 40.803 27.739 66.927 27.739 26.124 0 49.792-10.603 66.928-27.74 17.136-17.135 27.739-40.803 27.739-66.927 0-26.124-10.603-49.792-27.74-66.928C155.793 21.936 132.125 11.333 106 11.333Zm.772 59.504a6.5 6.5 0 0 1 6.5 6.5v21.5h21.5a6.5 6.5 0 0 1 6.5 6.5v1a6.5 6.5 0 0 1-6.5 6.5h-21.5v21.5a6.5 6.5 0 0 1-6.5 6.5h-1a6.5 6.5 0 0 1-6.5-6.5v-21.5h-21.5a6.5 6.5 0 0 1-6.5-6.5v-1a6.5 6.5 0 0 1 6.5-6.5h21.5v-21.5a6.5 6.5 0 0 1 6.5-6.5h1Z"/></svg></span></button> 1016 </h3> 1017 <div class="accordian__panel" id="accordian-spec-panel"> 1018 <div class="accordian__content flow"> 1019 1020 @* Play Enablers *@ 1021 <ul class="enablers__list"> 1022 @foreach (var playEnabler in playEnablersMap) 1023 { 1024 string playEnablerTitle = playEnabler.Value; 1025 string playEnablerKey = playEnabler.Key; 1026 string enablerActive = ""; 1027 1028 if ( playEnablers.Contains(playEnablerKey) ) { 1029 enablerActive = " active"; 1030 } 1031 1032 <li class="enablers__item@(enablerActive)"> 1033 <span class="enablers__tick"> 1034 <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round" class="feather feather-check"><polyline points="20 6 9 17 4 12"></polyline></svg> 1035 </span> 1036 <span>@playEnablerTitle</span> 1037 </li> 1038 } 1039 </ul> 1040 1041 1042 </div> 1043 </div> 1044 </section> 1045 } 1046 @if (!string.IsNullOrEmpty(GetString("Ecom:Product:Field.PlayValues"))) 1047 { 1048 string[] playValues = GetString("Ecom:Product:Field.PlayValues.Value").Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries).ToArray(); 1049 1050 var playCategories = new Dictionary<string,List<string>>{}; 1051 1052 1053 var playMap = new Dictionary<string, (string, string)> 1054 { 1055 { "50",("Spinning and Rolling","Physical") }, 1056 { "51",("Sliding","Physical") }, 1057 { "52",("Swinging / Rocking","Physical") }, 1058 { "53",("Climbing","Physical") }, 1059 { "54",("Crawling","Physical") }, 1060 { "55",("Balancing","Physical") }, 1061 { "56",("Jumping / Bouncing","Physical") }, 1062 { "57",("Walking and running","Physical") }, 1063 { "58",("Hanging<br/>(from the arms)","Physical") }, 1064 { "59",("Pointing and touching","Physical") }, 1065 { "60",("Cooperating","Social") }, 1066 { "61",("Sharing","Social") }, 1067 { "62",("Communicating","Social") }, 1068 { "63",("Turn-taking","Social") }, 1069 { "64",("Competing","Social") }, 1070 { "65",("Playing with mathematical concepts","Cognitive") }, 1071 { "66",("Playing with literacy concepts","Cognitive") }, 1072 { "67",("Problem solving","Cognitive") }, 1073 { "68",("Concentrating","Cognitive") }, 1074 { "69",("Remembering","Cognitive") }, 1075 { "70",("Planning / Tactics","Cognitive") }, 1076 { "71",("Growing / Planting","Creative") }, 1077 { "72",("Painting / Drawing / Mark Making","Creative") }, 1078 { "73",("Building / Arranging","Creative") }, 1079 { "74",("Sound making","Creative") }, 1080 { "75",("Imagining / Storytelling","Creative") } 1081 }; 1082 1083 @* Add the values to the play categories *@ 1084 1085 foreach (var value in playValues) 1086 { 1087 string playCategoryName = playMap.ContainsKey(value) ? playMap[value].Item2 : "unknown"; 1088 if (!playCategories.ContainsKey(playCategoryName)) 1089 { 1090 playCategories[playCategoryName] = new List<string>(); 1091 } 1092 playCategories[playCategoryName].Add(value); 1093 } 1094 1095 <section class="accordian"> 1096 <div class="wrapper"> 1097 <h3> 1098 <button id="accordian-spec" aria-expanded="true" aria-controls="accordian-spec-panel" type="button" class="accordian__button" data-action-page="Product" data-action-type="Text block expand" data-action-label="Experiences" data-action-value="@productNumber">Play Experiences<span class="accordian__icon accordian__icon--close" aria-hidden="true"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 212 212" class="h24-icon h24-icon--minus"><path fill="currentColor" fill-rule="evenodd" d="M106 6c55.193 0 100 44.807 100 100s-44.807 100-100 100S6 161.193 6 106 50.807 6 106 6Zm0 5.333c-26.124 0-49.792 10.603-66.928 27.74C21.936 56.207 11.333 79.875 11.333 106c0 26.124 10.603 49.792 27.74 66.928 17.135 17.136 40.803 27.739 66.927 27.739 26.124 0 49.792-10.603 66.928-27.74 17.136-17.135 27.739-40.803 27.739-66.927 0-26.124-10.603-49.792-27.74-66.928C155.793 21.936 132.125 11.333 106 11.333Zm28.772 87.504a6.5 6.5 0 0 1 6.5 6.5v1a6.5 6.5 0 0 1-6.5 6.5h-57a6.5 6.5 0 0 1-6.5-6.5v-1a6.5 6.5 0 0 1 6.5-6.5h57Z"/></svg></span><span class="accordian__icon accordian__icon--open" aria-hidden="true"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 212 212" class="h24-icon h24-icon--plus"><path fill="currentColor" fill-rule="evenodd" d="M106 6c55.193 0 100 44.807 100 100s-44.807 100-100 100S6 161.193 6 106 50.807 6 106 6Zm0 5.333c-26.124 0-49.792 10.603-66.928 27.74C21.936 56.207 11.333 79.875 11.333 106c0 26.124 10.603 49.792 27.74 66.928 17.135 17.136 40.803 27.739 66.927 27.739 26.124 0 49.792-10.603 66.928-27.74 17.136-17.135 27.739-40.803 27.739-66.927 0-26.124-10.603-49.792-27.74-66.928C155.793 21.936 132.125 11.333 106 11.333Zm.772 59.504a6.5 6.5 0 0 1 6.5 6.5v21.5h21.5a6.5 6.5 0 0 1 6.5 6.5v1a6.5 6.5 0 0 1-6.5 6.5h-21.5v21.5a6.5 6.5 0 0 1-6.5 6.5h-1a6.5 6.5 0 0 1-6.5-6.5v-21.5h-21.5a6.5 6.5 0 0 1-6.5-6.5v-1a6.5 6.5 0 0 1 6.5-6.5h21.5v-21.5a6.5 6.5 0 0 1 6.5-6.5h1Z"/></svg></span></button> 1099 </h3> 1100 <div class="accordian__panel" id="accordian-spec-panel"> 1101 <div class="accordian__content flow"> 1102 @* Play Value Icons *@ 1103 1104 @* now loop through the category keys - building a list for each key *@ 1105 1106 @foreach (var playCategory in playCategories ) 1107 { 1108 <h6>@playCategory.Key</h6> 1109 <ul class="badges"> 1110 @foreach (var value in playCategory.Value) 1111 { 1112 string playTitle = playMap.ContainsKey(value) ? playMap[value].Item1 : "Unknown"; 1113 string valueImg = value + ".svg"; 1114 <li class="badges__item badges__item--text"> 1115 <img src="@(designBaseUrl)icons/play-values-icons/@valueImg" alt="@playTitle" title="@playTitle" /> 1116 <span>@playTitle</span> 1117 </li> 1118 } 1119 </ul> 1120 } 1121 1122 1123 </div> 1124 </div> 1125 </section> 1126 } 1127 1128 <section class="accordian"> 1129 <div class="wrapper"> 1130 1131 <h3><button 1132 id="accordian-spec" 1133 aria-expanded="true" aria-controls="accordian-spec-panel" type="button" 1134 class="accordian__button" 1135 data-action-page="Product" 1136 data-action-type="Text block expand" 1137 data-action-label="Specifications" 1138 data-action-value="@productNumber"> 1139 @Translate("ProductSpecifications", "Product Specifications") 1140 <span class="accordian__icon accordian__icon--close" aria-hidden="true"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 212 212" class="h24-icon h24-icon--minus"><path fill="currentColor" fill-rule="evenodd" d="M106 6c55.193 0 100 44.807 100 100s-44.807 100-100 100S6 161.193 6 106 50.807 6 106 6Zm0 5.333c-26.124 0-49.792 10.603-66.928 27.74C21.936 56.207 11.333 79.875 11.333 106c0 26.124 10.603 49.792 27.74 66.928 17.135 17.136 40.803 27.739 66.927 27.739 26.124 0 49.792-10.603 66.928-27.74 17.136-17.135 27.739-40.803 27.739-66.927 0-26.124-10.603-49.792-27.74-66.928C155.793 21.936 132.125 11.333 106 11.333Zm28.772 87.504a6.5 6.5 0 0 1 6.5 6.5v1a6.5 6.5 0 0 1-6.5 6.5h-57a6.5 6.5 0 0 1-6.5-6.5v-1a6.5 6.5 0 0 1 6.5-6.5h57Z"/></svg></span> 1141 <span class="accordian__icon accordian__icon--open" aria-hidden="true"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 212 212" class="h24-icon h24-icon--plus"><path fill="currentColor" fill-rule="evenodd" d="M106 6c55.193 0 100 44.807 100 100s-44.807 100-100 100S6 161.193 6 106 50.807 6 106 6Zm0 5.333c-26.124 0-49.792 10.603-66.928 27.74C21.936 56.207 11.333 79.875 11.333 106c0 26.124 10.603 49.792 27.74 66.928 17.135 17.136 40.803 27.739 66.927 27.739 26.124 0 49.792-10.603 66.928-27.74 17.136-17.135 27.739-40.803 27.739-66.927 0-26.124-10.603-49.792-27.74-66.928C155.793 21.936 132.125 11.333 106 11.333Zm.772 59.504a6.5 6.5 0 0 1 6.5 6.5v21.5h21.5a6.5 6.5 0 0 1 6.5 6.5v1a6.5 6.5 0 0 1-6.5 6.5h-21.5v21.5a6.5 6.5 0 0 1-6.5 6.5h-1a6.5 6.5 0 0 1-6.5-6.5v-21.5h-21.5a6.5 6.5 0 0 1-6.5-6.5v-1a6.5 6.5 0 0 1 6.5-6.5h21.5v-21.5a6.5 6.5 0 0 1 6.5-6.5h1Z"/></svg></span> 1142 </button> 1143 </h3> 1144 1145 <div class="accordian__panel" id="accordian-spec-panel"> 1146 <div class="accordian__content flow"> 1147 1148 @if (!String.IsNullOrWhiteSpace(@GetString("Ecom:Product:Field.IPEMA_Specification"))) 1149 { 1150 string ipemaData = GetString("Ecom:Product:Field.IPEMA_Specification"); 1151 // Get IPEMA Product Specification data from a Field on the Product data from Jeeves 1152 //System.Xml.Linq.XDocument dataXML = System.Xml.Linq.XDocument.Load(System.Web.HttpContext.Current.Server.MapPath("~/Files/Templates/eCom/Product/meterial_xml_out_putV2_Edit.xml")); 1153 System.Xml.Linq.XDocument dataXML = System.Xml.Linq.XDocument.Parse(ipemaData); 1154 1155 if (dataXML != null) 1156 { 1157 @*<h1> @GetString("Ecom:Product.Name") </h1>*@ 1158 @*<p>@dataXML</p>*@ 1159 System.Globalization.NumberFormatInfo format = new System.Globalization.NumberFormatInfo(); 1160 1161 var details = from dat in dataXML.Descendants("Item") 1162 select new 1163 { 1164 name = dat.Element("name").Value, 1165 enValue = dat.Element("EN_value").Value, 1166 astmValue = dat.Element("ASTM_value").Value, 1167 csaValue = dat.Element("CSA_value").Value 1168 }; 1169 1170 <table class="table"> 1171 <thead> 1172 <tr> 1173 <th scope="col"></th> 1174 <th scope="col">@Translate("Europe","Europe")<br>EN1176</th> 1175 <th scope="col">@Translate("USA", "USA")<br>ASTM F1487</th> 1176 <th scope="col">@Translate("Canada", "Canada")<br>CSA Z614</th> 1177 </tr> 1178 </thead> 1179 1180 <tbody> 1181 @foreach (var item in details) 1182 { 1183 <tr> 1184 <td>@item.name</td> 1185 <td>@item.enValue</td> 1186 <td>@item.astmValue</td> 1187 <td>@item.csaValue</td> 1188 </tr> 1189 } 1190 </tbody> 1191 </table> 1192 1193 @*#table-IPEMA Product Spec*@ 1194 } 1195 1196 } else { 1197 <table class="table"> 1198 <thead> 1199 <tr> 1200 <th scope="col"></th> 1201 <th scope="col"></th> 1202 </tr> 1203 </thead> 1204 <tbody> 1205 1206 @if (!String.IsNullOrWhiteSpace(GetString("Ecom:Product:Field.NumberOfChildren"))) 1207 { 1208 <tr> 1209 <td>@GetString("Ecom:Product:Field.NumberOfChildren.Name")</td> 1210 <td>@GetString("Ecom:Product:Field.NumberOfChildren.Value")</td> 1211 </tr> 1212 } 1213 @if (!String.IsNullOrWhiteSpace(GetString("Ecom:Product:Field.AgeRange")) && ageRanges.Any()) 1214 { 1215 <tr> 1216 <td>@GetString("Ecom:Product:Field.AgeRange.Name")</td> 1217 <td>@string.Join(", ", ageRanges)</td> 1218 </tr> 1219 } 1220 @if (GetDouble("Ecom:Product:Field.AssemblyTime.Value.Raw") > 0) 1221 { 1222 <tr> 1223 <td>@GetString("Ecom:Product:Field.AssemblyTime.Name")</td> 1224 <td>@GetDouble("Ecom:Product:Field.AssemblyTime.Value.Raw") @Translate("Hours", "hours")</td> 1225 </tr> 1226 } 1227 @if (GetDouble("Ecom:Product:Field.Length.Value.Raw") > 0) 1228 { 1229 <tr> 1230 <td>@GetString("Ecom:Product:Field.Length.Name").Replace(" (mm)", "")</td> 1231 <td>@GetString("Ecom:Product:Field.Length.Value.Raw") mm</td> 1232 </tr> 1233 } 1234 @if (GetDouble("Ecom:Product:Field.Width.Value.Raw") > 0) 1235 { 1236 <tr> 1237 <td>@GetString("Ecom:Product:Field.Width.Name").Replace(" (mm)", "")</td> 1238 <td>@GetString("Ecom:Product:Field.Width.Value.Raw") mm</td> 1239 </tr> 1240 } 1241 @if (GetDouble("Ecom:Product:Field.Height.Value.Raw") > 0) 1242 { 1243 <tr> 1244 <td>@GetString("Ecom:Product:Field.Height.Name").Replace(" (mm)", "")</td> 1245 <td>@GetString("Ecom:Product:Field.Height.Value.Raw") mm</td> 1246 </tr> 1247 } 1248 @if (GetDouble("Ecom:Product:Field.NetWeight.Value.Raw") > 0) 1249 { 1250 <tr> 1251 <td>@GetString("Ecom:Product:Field.NetWeight.Name")</td> 1252 <td>@GetString("Ecom:Product:Field.NetWeight.Value") kg</td> 1253 </tr> 1254 } 1255 @if (GetDouble("Ecom:Product:Field.Volume.Value.Raw") > 0) 1256 { 1257 <tr> 1258 <td>@GetString("Ecom:Product:Field.Volume.Name")</td> 1259 <td>@GetString("Ecom:Product:Field.Volume.Value.Raw") m³</td> 1260 </tr> 1261 } 1262 @if (GetDouble("Ecom:Product:Field.FallHeight.Value.Raw") > 0) 1263 { 1264 <tr> 1265 <td>@GetString("Ecom:Product:Field.FallHeight.Name").Replace(" (mm)", "")</td> 1266 <td>@GetString("Ecom:Product:Field.FallHeight.Value.Raw") mm</td> 1267 </tr> 1268 } 1269 @if (GetDouble("Ecom:Product:Field.SafetyAreaWidth.Value.Raw") > 0) 1270 { 1271 <tr> 1272 <td>@GetString("Ecom:Product:Field.SafetyAreaWidth.Name").Replace(" (mm)", "")</td> 1273 <td>@GetString("Ecom:Product:Field.SafetyAreaWidth.Value.Raw") mm</td> 1274 </tr> 1275 } 1276 @if (GetDouble("Ecom:Product:Field.SafetyAreaLength.Value.Raw") > 0) 1277 { 1278 <tr> 1279 <td>@GetString("Ecom:Product:Field.SafetyAreaLength.Name").Replace(" (mm)", "")</td> 1280 <td>@GetString("Ecom:Product:Field.SafetyAreaLength.Value.Raw") mm</td> 1281 </tr> 1282 } 1283 @if (GetDouble("Ecom:Product:Field.SafetyArea.Value.Raw") > 0) 1284 { 1285 <tr> 1286 <td>@GetString("Ecom:Product:Field.SafetyArea.Name")</td> 1287 <td>@GetDouble("Ecom:Product:Field.SafetyArea.Value") m²</td> 1288 </tr> 1289 } 1290 1291 </tbody> 1292 </table> 1293 1294 } 1295 1296 @*SafetyAreaDetails*@ 1297 @if (GetDouble("Ecom:Product:Field.SafetyArea.Value") > 0 && thisPage.AreaID == 1) 1298 { 1299 string safetyAreaPage = DWUtilities.GetPageByNavigationTag("SafetyArea", thisPage.AreaID); 1300 if (!string.IsNullOrEmpty(safetyAreaPage)) 1301 { 1302 <p><a href="@safetyAreaPage" class="print-hide">@Translate("ReadMoreSafetyArea", "Read more about safety areas")</a></p> 1303 } 1304 1305 } 1306 1307 @*Anchoring from Variant*@ 1308 @if (!string.IsNullOrEmpty(selectedAnchoringVariant)) 1309 { 1310 string anchoringPage = DWUtilities.GetPageByNavigationTag("AnchoringTypes", thisPage.AreaID) + "#" + GetGlobalValue("Global:HagsTheme"); 1311 1312 if (!string.IsNullOrEmpty(anchoringPage)) 1313 { 1314 <p><a href="@anchoringPage" class="btn btn--outline print-hide">@Translate("ReadMoreAnchoring", "Read more about anchoring")</a></p> 1315 } 1316 1317 } 1318 1319 @*Guarantee Page for Sweden*@ 1320 @if (thisPage.AreaID == 2) 1321 { 1322 <p><a href="/sv-se/om-hags/garantier" target="_blank" class="print-hide">Läs mer om produktgarantier</a></p> 1323 } 1324 </div> 1325 </div> 1326 </section> 1327 @helper materialsTable(string materialData) { 1328 1329 // this is a hack until this information can be delivered from Jeeves 1330 // there is a speadsheet on the site to generate this 1331 var materials = new Dictionary<string, Dictionary<string, string>> 1332 { 1333 { "Pine", new Dictionary<string, string>{{ "Swan", "Yes" },{ "Certified", "Yes" },{ "Recycled", "0" },{ "Recyclable", "100" },{ "Renewable", "100" }}}, 1334 { "Jatoba", new Dictionary<string, string>{{ "Swan", "No" },{ "Certified", "Yes" },{ "Recycled", "0" },{ "Recyclable", "100" },{ "Renewable", "100" }}}, 1335 { "Oak", new Dictionary<string, string>{{ "Swan", "Yes" },{ "Certified", "Yes" },{ "Recycled", "0" },{ "Recyclable", "100" },{ "Renewable", "100" }}}, 1336 { "Robinia Pseudoacacia", new Dictionary<string, string>{{ "Swan", "No" },{ "Certified", "Yes" },{ "Recycled", "0" },{ "Recyclable", "100" },{ "Renewable", "100" }}}, 1337 { "Sibirian larch wood", new Dictionary<string, string>{{ "Swan", "No" },{ "Certified", "No" },{ "Recycled", "0" },{ "Recyclable", "100" },{ "Renewable", "100" }}}, 1338 { "Fir", new Dictionary<string, string>{{ "Swan", "No" },{ "Certified", "No" },{ "Recycled", "0" },{ "Recyclable", "100" },{ "Renewable", "100" }}}, 1339 { "Douglas fir", new Dictionary<string, string>{{ "Swan", "No" },{ "Certified", "No" },{ "Recycled", "0" },{ "Recyclable", "100" },{ "Renewable", "100" }}}, 1340 { "Bilinga", new Dictionary<string, string>{{ "Swan", "No" },{ "Certified", "Yes" },{ "Recycled", "0" },{ "Recyclable", "100" },{ "Renewable", "100" }}}, 1341 { "FSC Hardwood", new Dictionary<string, string>{{ "Swan", "No" },{ "Certified", "Yes" },{ "Recycled", "0" },{ "Recyclable", "100" },{ "Renewable", "100" }}}, 1342 { "Plywood", new Dictionary<string, string>{{ "Swan", "Yes" },{ "Certified", "Yes" },{ "Recycled", "0" },{ "Recyclable", "100" },{ "Renewable", "100" }}}, 1343 { "Fibreboard", new Dictionary<string, string>{{ "Swan", "Yes" },{ "Certified", "Yes" },{ "Recycled", "90" },{ "Recyclable", "100" },{ "Renewable", "100" }}}, 1344 { "HPL", new Dictionary<string, string>{{ "Swan", "Yes" },{ "Certified", "No" },{ "Recycled", "66" },{ "Recyclable", "0" },{ "Renewable", "66" }}}, 1345 { "Untreated Steel", new Dictionary<string, string>{{ "Swan", "Yes" },{ "Certified", "No" },{ "Recycled", "69" },{ "Recyclable", "100" },{ "Renewable", "0" }}}, 1346 { "Brass", new Dictionary<string, string>{{ "Swan", "No" },{ "Certified", "No" },{ "Recycled", "0" },{ "Recyclable", "100" },{ "Renewable", "0" }}}, 1347 { "Cast iron", new Dictionary<string, string>{{ "Swan", "No" },{ "Certified", "No" },{ "Recycled", "10" },{ "Recyclable", "100" },{ "Renewable", "0" }}}, 1348 { "Stainless steel", new Dictionary<string, string>{{ "Swan", "No" },{ "Certified", "No" },{ "Recycled", "0" },{ "Recyclable", "0" },{ "Renewable", "0" }}}, 1349 { "Stainless steel EN 1.4301", new Dictionary<string, string>{{ "Swan", "Yes" },{ "Certified", "No" },{ "Recycled", "85" },{ "Recyclable", "100" },{ "Renewable", "0" }}}, 1350 { "Stainless steel EN 1.4404", new Dictionary<string, string>{{ "Swan", "No" },{ "Certified", "No" },{ "Recycled", "0" },{ "Recyclable", "0" },{ "Renewable", "0" }}}, 1351 { "Aluminum", new Dictionary<string, string>{{ "Swan", "Yes" },{ "Certified", "No" },{ "Recycled", "24" },{ "Recyclable", "100" },{ "Renewable", "0" }}}, 1352 { "Recycled Aluminum", new Dictionary<string, string>{{ "Swan", "No" },{ "Certified", "No" },{ "Recycled", "24" },{ "Recyclable", "100" },{ "Renewable", "0" }}}, 1353 { "Zink (hot-galvanised)", new Dictionary<string, string>{{ "Swan", "Yes" },{ "Certified", "No" },{ "Recycled", "70" },{ "Recyclable", "100" },{ "Renewable", "0" }}}, 1354 { "Zink (electro-galvanised)", new Dictionary<string, string>{{ "Swan", "Yes" },{ "Certified", "No" },{ "Recycled", "0" },{ "Recyclable", "100" },{ "Renewable", "0" }}}, 1355 { "Aluzinc", new Dictionary<string, string>{{ "Swan", "No" },{ "Certified", "No" },{ "Recycled", "0" },{ "Recyclable", "0" },{ "Renewable", "0" }}}, 1356 { "Glasfiberarm polyester", new Dictionary<string, string>{{ "Swan", "Yes" },{ "Certified", "No" },{ "Recycled", "0" },{ "Recyclable", "0" },{ "Renewable", "0" }}}, 1357 { "Polyester", new Dictionary<string, string>{{ "Swan", "Yes" },{ "Certified", "No" },{ "Recycled", "0" },{ "Recyclable", "0" },{ "Renewable", "0" }}}, 1358 { "Polyeser PET", new Dictionary<string, string>{{ "Swan", "No" },{ "Certified", "No" },{ "Recycled", "10" },{ "Recyclable", "100" },{ "Renewable", "0" }}}, 1359 { "Polyamide (PA)", new Dictionary<string, string>{{ "Swan", "Yes" },{ "Certified", "No" },{ "Recycled", "0" },{ "Recyclable", "100" },{ "Renewable", "0" }}}, 1360 { "Polycarbonate (PC)", new Dictionary<string, string>{{ "Swan", "Yes" },{ "Certified", "No" },{ "Recycled", "0" },{ "Recyclable", "100" },{ "Renewable", "0" }}}, 1361 { "Polyethylene (PE)", new Dictionary<string, string>{{ "Swan", "Yes" },{ "Certified", "No" },{ "Recycled", "100" },{ "Recyclable", "100" },{ "Renewable", "0" }}}, 1362 { "Acrylic (PMMA)", new Dictionary<string, string>{{ "Swan", "No" },{ "Certified", "No" },{ "Recycled", "0" },{ "Recyclable", "100" },{ "Renewable", "0" }}}, 1363 { "Polyacetal (POM)", new Dictionary<string, string>{{ "Swan", "Yes" },{ "Certified", "No" },{ "Recycled", "10" },{ "Recyclable", "100" },{ "Renewable", "0" }}}, 1364 { "Polypropylene (PP)", new Dictionary<string, string>{{ "Swan", "Yes" },{ "Certified", "No" },{ "Recycled", "0" },{ "Recyclable", "0" },{ "Renewable", "0" }}}, 1365 { "Nylon rope, Glued braided, 16mm (16BN-FC)", new Dictionary<string, string>{{ "Swan", "No" },{ "Certified", "No" },{ "Recycled", "48" },{ "Recyclable", "0" },{ "Renewable", "0" }}}, 1366 { "Nylon rope, Glued braided, 18mm (18BN-FC)", new Dictionary<string, string>{{ "Swan", "No" },{ "Certified", "No" },{ "Recycled", "48" },{ "Recyclable", "0" },{ "Renewable", "0" }}}, 1367 { "Nylon rope, Glued braided, 22mm (22BN-FC)", new Dictionary<string, string>{{ "Swan", "No" },{ "Certified", "No" },{ "Recycled", "48" },{ "Recyclable", "0" },{ "Renewable", "0" }}}, 1368 { "Nylon rope, Glued braided, 23mm (23BN-IRWC)", new Dictionary<string, string>{{ "Swan", "No" },{ "Certified", "No" },{ "Recycled", "48" },{ "Recyclable", "0" },{ "Renewable", "0" }}}, 1369 { "Nylon rope, Glued braided, 24mm (24BN-IRWC)", new Dictionary<string, string>{{ "Swan", "No" },{ "Certified", "No" },{ "Recycled", "48" },{ "Recyclable", "0" },{ "Renewable", "0" }}}, 1370 { "Nylon rope, Glued braided, 18mm (18BN-IRWC)", new Dictionary<string, string>{{ "Swan", "No" },{ "Certified", "No" },{ "Recycled", "48" },{ "Recyclable", "0" },{ "Renewable", "0" }}}, 1371 { "Nylon rope, Fendex, 140mm (PP)", new Dictionary<string, string>{{ "Swan", "No" },{ "Certified", "No" },{ "Recycled", "48" },{ "Recyclable", "0" },{ "Renewable", "0" }}}, 1372 { "Woven acrylic", new Dictionary<string, string>{{ "Swan", "No" },{ "Certified", "No" },{ "Recycled", "48" },{ "Recyclable", "0" },{ "Renewable", "0" }}}, 1373 { "Polyurethane solid (PUR)", new Dictionary<string, string>{{ "Swan", "Yes" },{ "Certified", "No" },{ "Recycled", "0" },{ "Recyclable", "0" },{ "Renewable", "0" }}}, 1374 { "Polyurethane foam/flex", new Dictionary<string, string>{{ "Swan", "Yes" },{ "Certified", "No" },{ "Recycled", "0" },{ "Recyclable", "0" },{ "Renewable", "0" }}}, 1375 { "Thermo plastic elastomer (TPE)", new Dictionary<string, string>{{ "Swan", "Yes" },{ "Certified", "No" },{ "Recycled", "0" },{ "Recyclable", "0" },{ "Renewable", "0" }}}, 1376 { "Recycled thermoplastics", new Dictionary<string, string>{{ "Swan", "No" },{ "Certified", "No" },{ "Recycled", "100" },{ "Recyclable", "100" },{ "Renewable", "0" }}}, 1377 { "Taifun rope", new Dictionary<string, string>{{ "Swan", "No" },{ "Certified", "No" },{ "Recycled", "0" },{ "Recyclable", "0" },{ "Renewable", "0" }}}, 1378 { "Hercules Rope (PES) with steel core", new Dictionary<string, string>{{ "Swan", "No" },{ "Certified", "No" },{ "Recycled", "0" },{ "Recyclable", "0" },{ "Renewable", "0" }}}, 1379 { "Powder coating polyester", new Dictionary<string, string>{{ "Swan", "Yes" },{ "Certified", "No" },{ "Recycled", "0" },{ "Recyclable", "0" },{ "Renewable", "0" }}}, 1380 { "Wet paint for wood", new Dictionary<string, string>{{ "Swan", "Yes" },{ "Certified", "No" },{ "Recycled", "0" },{ "Recyclable", "0" },{ "Renewable", "0" }}}, 1381 { "Rubber", new Dictionary<string, string>{{ "Swan", "Yes" },{ "Certified", "No" },{ "Recycled", "89" },{ "Recyclable", "100" },{ "Renewable", "0" }}}, 1382 { "Recycled rubber", new Dictionary<string, string>{{ "Swan", "No" },{ "Certified", "No" },{ "Recycled", "89" },{ "Recyclable", "100" },{ "Renewable", "0" }}}, 1383 { "Glass", new Dictionary<string, string>{{ "Swan", "No" },{ "Certified", "No" },{ "Recycled", "19" },{ "Recyclable", "100" },{ "Renewable", "0" }}}, 1384 { "Concrete", new Dictionary<string, string>{{ "Swan", "Yes" },{ "Certified", "No" },{ "Recycled", "0" },{ "Recyclable", "0" },{ "Renewable", "0" }}}, 1385 { "Polyurethane concrete", new Dictionary<string, string>{{ "Swan", "No" },{ "Certified", "No" },{ "Recycled", "0" },{ "Recyclable", "0" },{ "Renewable", "0" }}}, 1386 { "Cardboard", new Dictionary<string, string>{{ "Swan", "No" },{ "Certified", "No" },{ "Recycled", "100" },{ "Recyclable", "100" },{ "Renewable", "100" }}}, 1387 { "Hydraulic oil (rapeseed-based)", new Dictionary<string, string>{{ "Swan", "No" },{ "Certified", "No" },{ "Recycled", "0" },{ "Recyclable", "0" },{ "Renewable", "0" }}}, 1388 { "Polytehelene (Eco-Grip)", new Dictionary<string, string>{{ "Swan", "No" },{ "Certified", "No" },{ "Recycled", "89" },{ "Recyclable", "100" },{ "Renewable", "0" }}}, 1389 { "Powder coat Primer", new Dictionary<string, string>{{ "Swan", "No" },{ "Certified", "No" },{ "Recycled", "0" },{ "Recyclable", "0" },{ "Renewable", "0" }}}, 1390 { "Steel Reinforced Rope", new Dictionary<string, string>{{ "Swan", "No" },{ "Certified", "No" },{ "Recycled", "48" },{ "Recyclable", "0" },{ "Renewable", "0" }}}, 1391 { "EPDM", new Dictionary<string, string>{{ "Swan", "No" },{ "Certified", "No" },{ "Recycled", "84" },{ "Recyclable", "100" },{ "Renewable", "0" }}}, 1392 { "Thermopine", new Dictionary<string, string>{{ "Swan", "" },{ "Certified", "" },{ "Recycled", "0" },{ "Recyclable", "100" },{ "Renewable", "100" }}} 1393 }; 1394 1395 if (!string.IsNullOrEmpty(materialData)) 1396 { 1397 //System.Xml.Linq.XDocument dataXML = System.Xml.Linq.XDocument.Load(System.Web.HttpContext.Current.Server.MapPath("~/Files/Templates/eCom/Product/meterial_xml_out_put.xml")); 1398 System.Xml.Linq.XDocument dataXML = System.Xml.Linq.XDocument.Parse(materialData); 1399 1400 if (dataXML != null) 1401 { 1402 System.Globalization.NumberFormatInfo format = new System.Globalization.NumberFormatInfo(); 1403 //format.NumberGroupSeparator = ","; //for thousands 1404 //format.NumberDecimalSeparator = "."; //the decimal seperator 1405 1406 var totalweight = Math.Round((from nd in dataXML.Descendants("kg") 1407 select Double.Parse(nd.Value, format)).Sum(), 0).ToString(); 1408 1409 var totalpercent = Math.Round((from nd in dataXML.Descendants("percent") 1410 select Double.Parse(nd.Value, format)).Sum(), 0).ToString(); 1411 1412 var details = from dat in dataXML.Descendants("Item") 1413 select new 1414 { 1415 material = dat.Element("material").Value, 1416 //weight = dat.Element("kg").Value,// string.Format("{0:0.00}", Double.Parse(dat.Element("kg").Value)), Occasionally throwing format errors 1417 weight = Math.Round(Double.Parse(dat.Element("kg").Value, format), 3).ToString(),// string.Format("{0:0.00}", Double.Parse(dat.Element("kg").Value)), Occasionally throwing format errors 1418 percent = Math.Round(Double.Parse(dat.Element("percent").Value, format), 3).ToString() // string.Format("{0:0.00}", Double.Parse(dat.Element("percent").Value)) 1419 }; 1420 // add note if required after materials table 1421 bool hplNote = false; 1422 1423 <table class="materials-table pdf-table"> 1424 <thead> 1425 <tr> 1426 <th scope="col">Material Name</th> 1427 <th scope="col">kg</th> 1428 <th scope="col">%</th> 1429 <th scope="col">Recycled</th> 1430 <th scope="col">Recyclable</th> 1431 <th scope="col">Renewable</th> 1432 </tr> 1433 </thead> 1434 1435 <tbody> 1436 1437 @foreach (var item in details) 1438 { 1439 var materialProperties = materials.ContainsKey(item.material) ? materials[item.material] : null; 1440 string useMaterialName = item.material; 1441 if ( item.material == "Thermopine" ) { 1442 useMaterialName = "Thermally treated pine"; 1443 } 1444 string addNoteRenewable = ""; 1445 1446 if ( item.material == "HPL" ) { 1447 addNoteRenewable = "<sup>*</sup>"; 1448 hplNote = true; 1449 } 1450 <tr> 1451 <td>@useMaterialName</td> 1452 <td>@item.weight</td> 1453 <td>@item.percent</td> 1454 @if ( !(materialProperties == null) ) 1455 { 1456 1457 <td>@(materialProperties["Recycled"])%</td> 1458 <td>@(materialProperties["Recyclable"])%</td> 1459 <td>@(materialProperties["Renewable"])%@(addNoteRenewable)</td> 1460 } else { 1461 <td></td><td></td><td></td> 1462 } 1463 1464 </tr> 1465 } 1466 1467 1468 1469 </tbody> 1470 1471 <tfoot> 1472 <tr> 1473 <td> </td> 1474 <td><strong>@totalweight kg</strong></td> 1475 <td><strong>@totalpercent%</strong></td> 1476 <td> </td> 1477 <td> </td> 1478 <td> </td> 1479 </tr> 1480 </tfoot> 1481 </table> <!--! #table-materials --> 1482 1483 if ( hplNote ) 1484 { 1485 <p class="ts--1"><sup>*</sup>Renewable % of the HPL core is made out of paper and is biodegradable</p> 1486 } 1487 1488 <div class="flow-2xs ts--1"> 1489 <p><strong>Recycled:</strong> Made from materials that have been processed and reused instead of discarded.</p> 1490 <p><strong>Recyclable:</strong> Can be collected, processed, and turned into new products instead of becoming waste.</p> 1491 <p><strong>Renewable:</strong> Comes from natural sources that can replenish over time such as sustainably harvested wood.</p> 1492 </div> 1493 1494 <p> 1495 Transparency is key for HAGS. Our materials come from various suppliers, 1496 therefore the Recycled, Recyclable, and Renewable percentages are shown as the maximum possible 1497 values used in the materials. As we source more sustainable materials, 1498 these numbers will change. 1499 </p> 1500 1501 } 1502 1503 } else { 1504 <p class="ts-2">Sorry, sustainability information for this product is currently unavailable.</p> 1505 } 1506 } 1507 1508 1509 1510 @if (!string.IsNullOrWhiteSpace(GetString("Ecom:Product:Field.Material"))) 1511 { 1512 <section class="accordian"> 1513 <div class="wrapper"> 1514 1515 <h3> 1516 <button id="accordian-materials" aria-expanded="true" aria-controls="accordian-materials-panel" type="button" class="accordian__button" 1517 data-action-page="Product" 1518 data-action-type="Text block expand" 1519 data-action-label="Materials" 1520 data-action-value="@productNumber"> 1521 @GetString("Ecom:Product:Field.Material.Name") 1522 <span class="accordian__icon accordian__icon--close" aria-hidden="true"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 212 212" class="h24-icon h24-icon--minus"><path fill="currentColor" fill-rule="evenodd" d="M106 6c55.193 0 100 44.807 100 100s-44.807 100-100 100S6 161.193 6 106 50.807 6 106 6Zm0 5.333c-26.124 0-49.792 10.603-66.928 27.74C21.936 56.207 11.333 79.875 11.333 106c0 26.124 10.603 49.792 27.74 66.928 17.135 17.136 40.803 27.739 66.927 27.739 26.124 0 49.792-10.603 66.928-27.74 17.136-17.135 27.739-40.803 27.739-66.927 0-26.124-10.603-49.792-27.74-66.928C155.793 21.936 132.125 11.333 106 11.333Zm28.772 87.504a6.5 6.5 0 0 1 6.5 6.5v1a6.5 6.5 0 0 1-6.5 6.5h-57a6.5 6.5 0 0 1-6.5-6.5v-1a6.5 6.5 0 0 1 6.5-6.5h57Z"/></svg></span> 1523 <span class="accordian__icon accordian__icon--open" aria-hidden="true"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 212 212" class="h24-icon h24-icon--plus"><path fill="currentColor" fill-rule="evenodd" d="M106 6c55.193 0 100 44.807 100 100s-44.807 100-100 100S6 161.193 6 106 50.807 6 106 6Zm0 5.333c-26.124 0-49.792 10.603-66.928 27.74C21.936 56.207 11.333 79.875 11.333 106c0 26.124 10.603 49.792 27.74 66.928 17.135 17.136 40.803 27.739 66.927 27.739 26.124 0 49.792-10.603 66.928-27.74 17.136-17.135 27.739-40.803 27.739-66.927 0-26.124-10.603-49.792-27.74-66.928C155.793 21.936 132.125 11.333 106 11.333Zm.772 59.504a6.5 6.5 0 0 1 6.5 6.5v21.5h21.5a6.5 6.5 0 0 1 6.5 6.5v1a6.5 6.5 0 0 1-6.5 6.5h-21.5v21.5a6.5 6.5 0 0 1-6.5 6.5h-1a6.5 6.5 0 0 1-6.5-6.5v-21.5h-21.5a6.5 6.5 0 0 1-6.5-6.5v-1a6.5 6.5 0 0 1 6.5-6.5h21.5v-21.5a6.5 6.5 0 0 1 6.5-6.5h1Z"/></svg></span> 1524 </button> 1525 </h3> 1526 1527 <div class="accordian__panel" id="accordian-materials-panel"> 1528 <div class="accordian__content"> 1529 1530 @{ 1531 // Get Material data from a Field on the Product data from Jeeves 1532 string materialData = GetString("Ecom:Product:Field.Material"); 1533 @materialsTable(materialData) 1534 1535 } 1536 1537 </div> 1538 </div> 1539 </div> 1540 </section> 1541 } 1542 @if (imagesCount + brochCount < assets.Count()) 1543 { 1544 1545 1546 } 1547 1548 @helper renderAccordianPanel(List<ProductAsset> assetList, string assetType, string translationTitle, string fallbackTitle, string extraContent = "", string productNumber = "") 1549 { 1550 1551 <section class="accordian print-hide"> 1552 <div class="wrapper"> 1553 <h3> 1554 <button id="accordian-downloads-@assetType" 1555 aria-expanded="true" aria-controls="accordian-panel-downloads-@assetType" type="button" class="accordian__button" 1556 data-action-page="Product" 1557 data-action-type="Text block expand" 1558 data-action-label="@translationTitle" 1559 data-action-value="@productNumber"> 1560 @Translate(translationTitle, fallbackTitle) 1561 <span class="accordian__icon accordian__icon--close" aria-hidden="true"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 212 212" class="h24-icon h24-icon--minus"><path fill="currentColor" fill-rule="evenodd" d="M106 6c55.193 0 100 44.807 100 100s-44.807 100-100 100S6 161.193 6 106 50.807 6 106 6Zm0 5.333c-26.124 0-49.792 10.603-66.928 27.74C21.936 56.207 11.333 79.875 11.333 106c0 26.124 10.603 49.792 27.74 66.928 17.135 17.136 40.803 27.739 66.927 27.739 26.124 0 49.792-10.603 66.928-27.74 17.136-17.135 27.739-40.803 27.739-66.927 0-26.124-10.603-49.792-27.74-66.928C155.793 21.936 132.125 11.333 106 11.333Zm28.772 87.504a6.5 6.5 0 0 1 6.5 6.5v1a6.5 6.5 0 0 1-6.5 6.5h-57a6.5 6.5 0 0 1-6.5-6.5v-1a6.5 6.5 0 0 1 6.5-6.5h57Z"/></svg></span> 1562 <span class="accordian__icon accordian__icon--open" aria-hidden="true"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 212 212" class="h24-icon h24-icon--plus"><path fill="currentColor" fill-rule="evenodd" d="M106 6c55.193 0 100 44.807 100 100s-44.807 100-100 100S6 161.193 6 106 50.807 6 106 6Zm0 5.333c-26.124 0-49.792 10.603-66.928 27.74C21.936 56.207 11.333 79.875 11.333 106c0 26.124 10.603 49.792 27.74 66.928 17.135 17.136 40.803 27.739 66.927 27.739 26.124 0 49.792-10.603 66.928-27.74 17.136-17.135 27.739-40.803 27.739-66.927 0-26.124-10.603-49.792-27.74-66.928C155.793 21.936 132.125 11.333 106 11.333Zm.772 59.504a6.5 6.5 0 0 1 6.5 6.5v21.5h21.5a6.5 6.5 0 0 1 6.5 6.5v1a6.5 6.5 0 0 1-6.5 6.5h-21.5v21.5a6.5 6.5 0 0 1-6.5 6.5h-1a6.5 6.5 0 0 1-6.5-6.5v-21.5h-21.5a6.5 6.5 0 0 1-6.5-6.5v-1a6.5 6.5 0 0 1 6.5-6.5h21.5v-21.5a6.5 6.5 0 0 1 6.5-6.5h1Z"/></svg></span> 1563 </button> 1564 </h3> 1565 1566 1567 <div class="accordian__panel" id="accordian-panel-downloads-@assetType"> 1568 <div class="accordian__content"> 1569 <ul class="downloads__list"> 1570 @foreach (ProductAsset asset in assetList) 1571 { 1572 <li> 1573 <a href="@asset.uri" download="@asset.FileName"> 1574 <span>@asset.FileName</span> 1575 </a> 1576 </li> 1577 } 1578 </ul> 1579 1580 @extraContent 1581 </div> 1582 </div> 1583 1584 </div> 1585 </section> 1586 1587 } 1588 1589 @* Certificates *@ 1590 1591 @{ 1592 1593 List<ProductAsset> certAssets = assets.Where(n => n.Index == AssetTypeEnum.ToFriendlyAssetName(AssetType.Certificates)).ToList(); 1594 1595 // Test if we have a filename like "GB_UniMini_1_A-F_1137_Cert_T�V". If so move it to the top of the subset so it shows first in the list. 1596 int index = certAssets.FindIndex(n => n.FileName.Contains("_Cert_T")); 1597 if(index > -1) 1598 { 1599 ProductAsset aTuv = certAssets[index]; 1600 certAssets[index] = certAssets[0]; 1601 certAssets[0] = aTuv; 1602 } 1603 } 1604 1605 @if (certAssets.Count > 0) 1606 { 1607 @renderAccordianPanel(certAssets, "certificates", "Certificates", "Certificates", "", productNumber) 1608 } 1609 1610 @* Assembly Instructions *@ 1611 1612 @{ 1613 List<ProductAsset> assemblyAssets = new List<ProductAsset>(); 1614 assemblyAssets = assets.Where(n => n.Index == AssetTypeEnum.ToFriendlyAssetName(AssetType.AssemblyInstructions)).ToList(); 1615 } 1616 1617 @if (assemblyAssets.Count > 0) 1618 { 1619 string extraContent = "<button class=\"productDownloadButton download btn btn--outline\" name=\"download\" data-parent=\"Monteringsanvisningar\""; 1620 extraContent += " data-productnumber=\"" + productNumber + "\" data-productname=\"" + GetString("Ecom:Product.Name") + "\">"; 1621 extraContent += Translate("DownloadInstallationGuides", "Installation Guides") + "</button>"; 1622 1623 @renderAccordianPanel(assemblyAssets, "install-guides", "InstallationGuides", "Installation Guides", extraContent, productNumber) 1624 } 1625 1626 @{ 1627 // add relatedProductsAssemblyInstructions to product assemblyAssets and store to session. Used in UsersProductCollection.GetAssets for the product 1628 assemblyAssets.AddRange(relatedProductsAssemblyInstructions); 1629 SessionManager.SetSession(productNumber + "_" + AssetType.AssemblyInstructions.ToFriendlyAssetName(), new List<ProductAsset>(assemblyAssets)); 1630 } 1631 1632 @* Detailed Assembly Instructions *@ 1633 1634 @{ 1635 // add relatedProductsAssemblyInstructions to product assemblyAssets and store to session. Used in UsersProductCollection.GetAssets for the product 1636 assemblyAssets.AddRange(relatedProductsAssemblyInstructions); 1637 SessionManager.SetSession(productNumber + "_" + AssetType.AssemblyInstructions.ToFriendlyAssetName(), new List<ProductAsset>(assemblyAssets)); 1638 } 1639 1640 @if (relatedProductsAssemblyInstructions.Count > 0) 1641 { 1642 1643 @renderAccordianPanel(relatedProductsAssemblyInstructions, "detail-guides", "DetailedInstallationGuides", "Detailed Installation Guides", "", productNumber) 1644 } 1645 1646 1647 @{ 1648 List<ProductAsset> inspAssets = new List<ProductAsset>(); 1649 //inspAssets = FileSystem.GetPdfFilesFromDirectoryBySiteCulture("/Files/System/ProductCollectionDownloads/InspectionMaintenance", "_" + currentlanguage.ToUpper()); 1650 inspAssets = FileSystem.GetAllPdfFilesFromDirectory("/Files/System/ProductCollectionDownloads/InspectionMaintenance"); 1651 } 1652 1653 @if (inspAssets != null && inspAssets.Count > 0) 1654 { 1655 @renderAccordianPanel(inspAssets, "insp-maintenance", "InspectionMaintenance", "Inspection & Maintenance", "", productNumber) 1656 } 1657 else 1658 { 1659 <section class="accordian print-hide"> 1660 <div class="wrapper"> 1661 <h3> 1662 <button id="accordian-downloads-insp-maintenance" 1663 aria-expanded="true" aria-controls="accordian-panel-downloads-insp-maintenance" 1664 type="button" class="accordian__button" 1665 data-action-page="Product" 1666 data-action-type="Text block expand" 1667 data-action-label="InspectionMaintenance" 1668 data-action-value="@productNumber"> 1669 @Translate("InspectionMaintenance", "Inspection & Maintenance") 1670 <span class="accordian__icon accordian__icon--close" aria-hidden="true"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 212 212" class="h24-icon h24-icon--minus"><path fill="currentColor" fill-rule="evenodd" d="M106 6c55.193 0 100 44.807 100 100s-44.807 100-100 100S6 161.193 6 106 50.807 6 106 6Zm0 5.333c-26.124 0-49.792 10.603-66.928 27.74C21.936 56.207 11.333 79.875 11.333 106c0 26.124 10.603 49.792 27.74 66.928 17.135 17.136 40.803 27.739 66.927 27.739 26.124 0 49.792-10.603 66.928-27.74 17.136-17.135 27.739-40.803 27.739-66.927 0-26.124-10.603-49.792-27.74-66.928C155.793 21.936 132.125 11.333 106 11.333Zm28.772 87.504a6.5 6.5 0 0 1 6.5 6.5v1a6.5 6.5 0 0 1-6.5 6.5h-57a6.5 6.5 0 0 1-6.5-6.5v-1a6.5 6.5 0 0 1 6.5-6.5h57Z"/></svg></span> 1671 <span class="accordian__icon accordian__icon--open" aria-hidden="true"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 212 212" class="h24-icon h24-icon--plus"><path fill="currentColor" fill-rule="evenodd" d="M106 6c55.193 0 100 44.807 100 100s-44.807 100-100 100S6 161.193 6 106 50.807 6 106 6Zm0 5.333c-26.124 0-49.792 10.603-66.928 27.74C21.936 56.207 11.333 79.875 11.333 106c0 26.124 10.603 49.792 27.74 66.928 17.135 17.136 40.803 27.739 66.927 27.739 26.124 0 49.792-10.603 66.928-27.74 17.136-17.135 27.739-40.803 27.739-66.927 0-26.124-10.603-49.792-27.74-66.928C155.793 21.936 132.125 11.333 106 11.333Zm.772 59.504a6.5 6.5 0 0 1 6.5 6.5v21.5h21.5a6.5 6.5 0 0 1 6.5 6.5v1a6.5 6.5 0 0 1-6.5 6.5h-21.5v21.5a6.5 6.5 0 0 1-6.5 6.5h-1a6.5 6.5 0 0 1-6.5-6.5v-21.5h-21.5a6.5 6.5 0 0 1-6.5-6.5v-1a6.5 6.5 0 0 1 6.5-6.5h21.5v-21.5a6.5 6.5 0 0 1 6.5-6.5h1Z"/></svg></span> 1672 </button> 1673 </h3> 1674 1675 1676 <div class="accordian__panel" id="accordian-panel-downloads-insp-maintenance"> 1677 <div class="accordian__content"> 1678 <ul class="downloads__list"> 1679 <li> 1680 <a href="/Files/System/ProductCollectionDownloads/InspectionMaintenance/Playground Equipment I&M guide_EN.pdf" download="Playground Equipment I&M Guide"> 1681 <span>Playground Equipment I&M Guide</span> 1682 </a> 1683 </li> 1684 <li> 1685 <a href="/Files/System/ProductCollectionDownloads/InspectionMaintenance/Sports and fitness I&M guide_EN.pdf" download="Sports and Fitness I&M Guide"> 1686 <span>Sports and Fitness I&M Guide</span> 1687 </a> 1688 </li> 1689 </ul> 1690 </div> 1691 </div> 1692 1693 </div> 1694 </section> 1695 } 1696 1697 @{ 1698 List<ProductAsset> dwgAssets = new List<ProductAsset>(); 1699 dwgAssets = assets.Where(n => n.Index == AssetTypeEnum.ToFriendlyAssetName(AssetType.Drawings)).ToList(); 1700 } 1701 1702 @if (dwgAssets.Count > 0) 1703 { 1704 @renderAccordianPanel(dwgAssets, "dwgs", "DWGFiles", "DWG Files", "", productNumber) 1705 } 1706 1707 1708 <section class="accordian print-hide"> 1709 <div class="wrapper"> 1710 <h3> 1711 <button id="accordian-downloads-general-info" 1712 aria-expanded="true" aria-controls="accordian-panel-downloads-general-info" 1713 type="button" class="accordian__button" 1714 data-action-page="Product" 1715 data-action-type="Text block expand" 1716 data-action-label="GeneralDownloads" 1717 data-action-value="@productNumber"> 1718 @Translate("GeneralInformation", "General Information") 1719 <span class="accordian__icon accordian__icon--close" aria-hidden="true"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 212 212" class="h24-icon h24-icon--minus"><path fill="currentColor" fill-rule="evenodd" d="M106 6c55.193 0 100 44.807 100 100s-44.807 100-100 100S6 161.193 6 106 50.807 6 106 6Zm0 5.333c-26.124 0-49.792 10.603-66.928 27.74C21.936 56.207 11.333 79.875 11.333 106c0 26.124 10.603 49.792 27.74 66.928 17.135 17.136 40.803 27.739 66.927 27.739 26.124 0 49.792-10.603 66.928-27.74 17.136-17.135 27.739-40.803 27.739-66.927 0-26.124-10.603-49.792-27.74-66.928C155.793 21.936 132.125 11.333 106 11.333Zm28.772 87.504a6.5 6.5 0 0 1 6.5 6.5v1a6.5 6.5 0 0 1-6.5 6.5h-57a6.5 6.5 0 0 1-6.5-6.5v-1a6.5 6.5 0 0 1 6.5-6.5h57Z"/></svg></span> 1720 <span class="accordian__icon accordian__icon--open" aria-hidden="true"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 212 212" class="h24-icon h24-icon--plus"><path fill="currentColor" fill-rule="evenodd" d="M106 6c55.193 0 100 44.807 100 100s-44.807 100-100 100S6 161.193 6 106 50.807 6 106 6Zm0 5.333c-26.124 0-49.792 10.603-66.928 27.74C21.936 56.207 11.333 79.875 11.333 106c0 26.124 10.603 49.792 27.74 66.928 17.135 17.136 40.803 27.739 66.927 27.739 26.124 0 49.792-10.603 66.928-27.74 17.136-17.135 27.739-40.803 27.739-66.927 0-26.124-10.603-49.792-27.74-66.928C155.793 21.936 132.125 11.333 106 11.333Zm.772 59.504a6.5 6.5 0 0 1 6.5 6.5v21.5h21.5a6.5 6.5 0 0 1 6.5 6.5v1a6.5 6.5 0 0 1-6.5 6.5h-21.5v21.5a6.5 6.5 0 0 1-6.5 6.5h-1a6.5 6.5 0 0 1-6.5-6.5v-21.5h-21.5a6.5 6.5 0 0 1-6.5-6.5v-1a6.5 6.5 0 0 1 6.5-6.5h21.5v-21.5a6.5 6.5 0 0 1 6.5-6.5h1Z"/></svg></span> 1721 </button> 1722 </h3> 1723 1724 1725 <div class="accordian__panel" id="accordian-panel-downloads-general-info"> 1726 1727 <div class="accordian__content"> 1728 1729 <ul class="downloads__list"> 1730 @*@if (thisPage.AreaID == 2) 1731 {*@ 1732 <li> 1733 <a href="Files/System/ProductCollectionDownloads/General Information/hags-general-info_SE.pdf" download="" target="_blank"> 1734 <span>@Translate("GeneralInformation", "General Information") (SE)</span> 1735 </a> 1736 </li> 1737 <li> 1738 <a href="Files/System/ProductCollectionDownloads/General Information/hags-technical-specs_SE.pdf" download="" target="_blank"> 1739 <span>@Translate("TechnicalInformation", "Technical Information") (SE)</span> 1740 </a> 1741 </li> 1742 @*} 1743 else 1744 {*@ 1745 <li> 1746 <a href="Files/System/ProductCollectionDownloads/General Information/hags-general-info_EN.pdf" download="" target="_blank"> 1747 <span>@Translate("GeneralInformation", "General Information") (EN)</span> 1748 </a> 1749 </li> 1750 <li> 1751 <a href="Files/System/ProductCollectionDownloads/General Information/hags-technical-specs_EN.pdf" download="" target="_blank"> 1752 <span>@Translate("TechnicalInformation", "Technical Information") (EN)</span> 1753 </a> 1754 </li> 1755 @*}*@ 1756 </ul> 1757 1758 </div> 1759 </div> 1760 1761 </div> 1762 </section> 1763 1764 1765 1766 1767 1768 1769 1770 1771 1772 1773 1774 <section class="accordian de"> 1775 <div class="wrapper"> 1776 <h3> 1777 <button id="accordian-materials" aria-expanded="true" aria-controls="accordian-materials-panel" type="button" class="accordian__button"> 1778 Tender Text Request Form 1779 <span class="accordian__icon accordian__icon--close" aria-hidden="true"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 212 212" class="h24-icon h24-icon--minus"><path fill="currentColor" fill-rule="evenodd" d="M106 6c55.193 0 100 44.807 100 100s-44.807 100-100 100S6 161.193 6 106 50.807 6 106 6Zm0 5.333c-26.124 0-49.792 10.603-66.928 27.74C21.936 56.207 11.333 79.875 11.333 106c0 26.124 10.603 49.792 27.74 66.928 17.135 17.136 40.803 27.739 66.927 27.739 26.124 0 49.792-10.603 66.928-27.74 17.136-17.135 27.739-40.803 27.739-66.927 0-26.124-10.603-49.792-27.74-66.928C155.793 21.936 132.125 11.333 106 11.333Zm28.772 87.504a6.5 6.5 0 0 1 6.5 6.5v1a6.5 6.5 0 0 1-6.5 6.5h-57a6.5 6.5 0 0 1-6.5-6.5v-1a6.5 6.5 0 0 1 6.5-6.5h57Z"/></svg></span> 1780 <span class="accordian__icon accordian__icon--open" aria-hidden="true"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 212 212" class="h24-icon h24-icon--plus"><path fill="currentColor" fill-rule="evenodd" d="M106 6c55.193 0 100 44.807 100 100s-44.807 100-100 100S6 161.193 6 106 50.807 6 106 6Zm0 5.333c-26.124 0-49.792 10.603-66.928 27.74C21.936 56.207 11.333 79.875 11.333 106c0 26.124 10.603 49.792 27.74 66.928 17.135 17.136 40.803 27.739 66.927 27.739 26.124 0 49.792-10.603 66.928-27.74 17.136-17.135 27.739-40.803 27.739-66.927 0-26.124-10.603-49.792-27.74-66.928C155.793 21.936 132.125 11.333 106 11.333Zm.772 59.504a6.5 6.5 0 0 1 6.5 6.5v21.5h21.5a6.5 6.5 0 0 1 6.5 6.5v1a6.5 6.5 0 0 1-6.5 6.5h-21.5v21.5a6.5 6.5 0 0 1-6.5 6.5h-1a6.5 6.5 0 0 1-6.5-6.5v-21.5h-21.5a6.5 6.5 0 0 1-6.5-6.5v-1a6.5 6.5 0 0 1 6.5-6.5h21.5v-21.5a6.5 6.5 0 0 1 6.5-6.5h1Z"/></svg></span> 1781 </button> 1782 </h3> 1783 <div class="accordian__panel" id="accordian-materials-panel"> 1784 <div class="accordian__content tender-request" style="padding-top: 16px;"> 1785 <form method="post" action="/de/contact/tender-text-thank-you" enctype="multipart/form-data" class="m-form-contact col-sm-8 col-sm-push-2" id="dw-form-48" onsubmit="s=function(e){e.elements['FormCH1_h'].value='0e3ca2f4f76893915d0d24ec4bc71d08';e.elements['_sys_to_email'].value='';e.setAttribute('action', '/Default.aspx?ID=20062&PID=139268');return true};return s(this);"> 1786 <input type="hidden" name="FormPID" value="139268"> 1787 <input type="hidden" name="FormID" value="48"> 1788 <input type="hidden" name="cmd" value="save"> 1789 <input type="hidden" name="_sys_to_email" value="info@hags.de" autocomplete="off"> 1790 <input type="hidden" name="FormCH1_h" value="" autocomplete="off"> 1791 <input type="hidden" name="FormCH1_f" value="64fcc853b5c7478097280b67d065e694" autocomplete="off"> 1792 <input type="hidden" name="FormCH1_s" value="ac65472af0eb2581e97b947e60408928" autocomplete="off"> 1793 <input type="hidden" name="FormCH1_i" value="3a190d1966f97696309b9461697e097b" autocomplete="off"> 1794 <input type="hidden" name="0e3ca2f4f76893915d0d24ec4bc71d08ts" value="wBhHOlLaouZU87nvwuTxWu29X6MBr7WK" style="display:none!important" autocomplete="off"> 1795 <input type="text" name="0e3ca2f4f76893915d0d24ec4bc71d08description" value="" style="display:none!important" autocomplete="off"> 1796 <input type="text" name="0e3ca2f4f76893915d0d24ec4bc71d08email" value="mrssmith@dynamicweb.com" style="display:none!important" autocomplete="off"> 1797 <table class="formtable"> 1798 <tbody> 1799 <tr class="labelRow" style="padding-bottom:12px;display:block;"> 1800 <td class="labelCell"> 1801 <p>Complete form form below to request the the relevant product tender text</p> 1802 </td> 1803 </tr> 1804 <tr class="labelRow"> 1805 <td class="labelCell"> 1806 <label for="ArticleNumber"><h6>Article Number: @productNumber</h6></label> 1807 </td> 1808 </tr> 1809 <tr class="labelRow"> 1810 <td class="labelCell"> 1811 <label for="FirstName">First Name </label> 1812 </td> 1813 </tr> 1814 <tr class="fieldRow"> 1815 <td> 1816 <input type="text" id="FirstName" name="FirstName" required="" /></td> 1817 </tr> 1818 <tr class="descriptionRow"> 1819 <td class="descriptionCell"><small></small></td> 1820 </tr> 1821 <tr class="labelRow"> 1822 <td class="labelCell"> 1823 <label for="LastName">Last Name </label> 1824 </td> 1825 </tr> 1826 <tr class="fieldRow"> 1827 <td><input type="text" id="LastName" name="LastName" required="" /></td> 1828 </tr> 1829 <tr class="descriptionRow"> 1830 <td class="descriptionCell"><small></small></td> 1831 </tr> 1832 <tr class="labelRow"> 1833 <td class="labelCell"> 1834 <label for="Email">Email </label> 1835 </td> 1836 </tr> 1837 <tr class="fieldRow"> 1838 <td><input type="email" id="Email" name="Email" required="" /></td> 1839 </tr> 1840 <tr class="descriptionRow"> 1841 <td class="descriptionCell"><small></small></td> 1842 </tr> 1843 <tr class="labelRow"> 1844 <td class="labelCell"> 1845 <label for="Company">Company </label> 1846 </td> 1847 </tr> 1848 <tr class="fieldRow"> 1849 <td><input type="text" id="Company" name="Company" required="" /></td> 1850 </tr> 1851 <tr class="descriptionRow"> 1852 <td class="descriptionCell"><small></small></td> 1853 </tr> 1854 <tr class="labelRow"> 1855 <td class="labelCell"> 1856 <label for="Adress">Adress </label> 1857 </td> 1858 </tr> 1859 <tr class="fieldRow"> 1860 <td><input type="text" id="Adress" name="Adress" required="" /></td> 1861 </tr> 1862 <tr class="descriptionRow"> 1863 <td class="descriptionCell"><small></small></td> 1864 </tr> 1865 <tr class="labelRow"> 1866 <td class="labelCell"> 1867 <label for="Postcode">Postcode</label> 1868 </td> 1869 </tr> 1870 <tr class="fieldRow"> 1871 <td><input type="text" id="Postcode" name="Postcode" required="" /></td> 1872 </tr> 1873 <tr class="descriptionRow"> 1874 <td class="descriptionCell"><small></small></td> 1875 </tr> 1876 <tr class="labelRow"> 1877 <td class="labelCell"> 1878 <label for="ArticleNumber">Article Number </label> 1879 </td> 1880 </tr> 1881 <tr class="fieldRow"> 1882 <td style="width:100%;display:block;"><input type="text" id="ArticleNumber" name="ArticleNumber" value="@productNumber" style="width:100%;display:block;"></td> 1883 </tr> 1884 <tr class="descriptionRow"> 1885 <td class="descriptionCell"><small></small></td> 1886 </tr> 1887 <tr class="fieldRow"> 1888 <td><input type="submit" id="SendRequest" name="SendRequest" value="Submit" class="submit" /></td> 1889 </tr> 1890 <tr class="descriptionRow"> 1891 <td class="descriptionCell"><small></small></td> 1892 </tr> 1893 </tbody> 1894 </table> 1895 <input type="hidden" name="SendRequest" value="Submit" /> 1896 </form> 1897 </div> 1898 </div> 1899 </div> 1900 </section> 1901 @*IncludeFile("partials/add-to-collection.cshtml")*@ 1902 </div> 1903 1904 </div> 1905 </div> 1906 </section> 1907 1908 <script type="text/javascript"> 1909 var __ss_noform = __ss_noform || []; 1910 __ss_noform.push(['baseURI', 'https://app-3QNUK2ISME.marketingautomation.services/webforms/receivePostback/MzawMLE0MzQ3BgA/']); 1911 __ss_noform.push(['endpoint', 'f1f4eefa-cc8e-4621-a197-e153223a10a6']); 1912 </script><script type="text/javascript" src="https://koi-3QNUK2ISME.marketingautomation.services/client/noform.js?ver=1.24" ></script> 1913 1914 <div class="center-copy contact"> 1915 1916 @if (!String.IsNullOrEmpty(salesPhoneNumber)) 1917 { 1918 string contactUsLink = DWUtilities.GetPageByNavigationTag("ContactUs", thisPage.AreaID); 1919 <p class="print-hide call-out"><span>@Translate("ContactUs", "Contact Us") <a href="@contactUsLink">@Translate("ContactForm", "Contact Form")</a></span></p> 1920 } 1921 </div> 1922 1923 1924 1925 <form id="product-hidden-fields"> 1926 <input type="hidden" id="productVariantId" value="@GetString("Ecom:Product.VariantID")"> 1927 <input type="hidden" id="productCollectionData" value="@collectionData"> 1928 </form> 1929 1930 1931 <section class="print-hide flow section-bg-light products-variants"> 1932 1933 @if (GetLoop("VariantCombinations").Count() > 0) 1934 { 1935 <div class="wrapper flow"> 1936 <h5>@Translate("ProductOptions", "Product Options") (<span id="resultCount">@GetLoop("VariantCombinations").Count()</span>)</h5> 1937 1938 1939 <form class="form-inline"> 1940 <div id="filter-variants" class="cluster"> 1941 1942 @if (anchoringOptions.Results.Count() > 0) 1943 { 1944 <div class="form-group"> 1945 <label for="anchoring" class="control-label">@Translate("Anchoring", "Anchoring")</label> 1946 <select class="form-control variant-filter" id="filter-anchoring" name="anchoring" 1947 data-action-page="product" data-action-type="Variant filter" 1948 data-action-label="Anchoring" data-action-value="@productNumber"> 1949 1950 @if (anchoringOptions.Results.Count() > 1) 1951 { 1952 <option value="any">@Translate("Any", "Any")</option> 1953 foreach (var anchor in anchoringOptions.Results.OrderBy(n => n.Sort)) 1954 { 1955 <option value="@anchor.Value">@anchor.Name</option> 1956 } 1957 } 1958 else 1959 { 1960 ResultField result = anchoringOptions.Results.FirstOrDefault(); 1961 <option value="any">@Translate("Any", "Any")</option> 1962 <option value="@result.Value">@result.Name</option> 1963 } 1964 1965 </select> 1966 </div> 1967 } 1968 1969 @if (colourOptions.Results.Count() > 0) 1970 { 1971 <div class="form-group"> 1972 <label for="colour" class="control-label">@Translate("Colour", "Colour")</label> 1973 <select class="form-control variant-filter" id="filter-colour" name="colour" 1974 data-action-page="product" data-action-type="Variant filter" 1975 data-action-label="Colour" data-action-value="@productNumber"> 1976 1977 @if (colourOptions.Results.Count() > 1) 1978 { 1979 <option value="any">@Translate("Any", "Any")</option> 1980 foreach (var colour in colourOptions.Results.OrderBy(n => n.Sort)) 1981 { 1982 <option value="@colour.Value">@colour.Name</option> 1983 } 1984 } 1985 else 1986 { 1987 ResultField result = colourOptions.Results.FirstOrDefault(); 1988 <option value="@result.Value">@result.Name</option> 1989 } 1990 </select> 1991 </div> 1992 } 1993 1994 @if (optionOptions.Results.Count() > 0) 1995 { 1996 <div class="form-group"> 1997 <label for="options" class="control-label">@Translate("ProductOptions", "Product Options")</label> 1998 <select class="form-control variant-filter" id="filter-options" name="options" 1999 data-action-page="product" data-action-type="Variant filter" 2000 data-action-label="Options" data-action-value="@productNumber"> 2001 2002 @if (optionOptions.Results.Count() > 1) 2003 { 2004 <option value="any">@Translate("Any", "Any")</option> 2005 foreach (var option in optionOptions.Results.OrderBy(n => n.Sort)) 2006 { 2007 <option value="@option.Value">@option.Name</option> 2008 } 2009 } 2010 else 2011 { 2012 ResultField result = optionOptions.Results.FirstOrDefault(); 2013 <option value="@result.Value">@result.Name</option> 2014 } 2015 </select> 2016 </div> 2017 } 2018 2019 </div> 2020 </form> 2021 2022 2023 </div> 2024 2025 <div class="wrapper"> 2026 <div class="grid" id="variants-list"> 2027 2028 @foreach (LoopItem variantCombinations in GetLoop("VariantCombinations")) 2029 { 2030 var colourOption = string.Empty; 2031 var optionOption = string.Empty; 2032 var anchorOption = string.Empty; 2033 var materialOption = string.Empty; 2034 var colourId = string.Empty; 2035 var optionId = string.Empty; 2036 var anchorId = string.Empty; 2037 var materialId = string.Empty; 2038 var selectedVariant = string.Empty; 2039 List<ProductAsset> productImages = AssetManager_Repository.GetAssets(variantCombinations.GetString("Ecom:VariantCombination.Product.Number"), AssetType.Images, false); 2040 ProductAsset image = productImages.Where(n => n.Index == AssetTypeEnum.ToFriendlyAssetName(AssetType.Images) && n.FileName.StartsWith("medium_")).FirstOrDefault(); 2041 2042 foreach (var group in GetLoop("VariantGroups").Where(n => n.GetString("Ecom:VariantGroup.ID") != "D")) 2043 { 2044 foreach (var availableOption in group.GetLoop("VariantAvailableOptions")) 2045 { 2046 if (group.GetString("Ecom:VariantGroup.ID") == "S55") 2047 { 2048 2049 if (variantCombinations.GetString("Ecom:VariantCombination.VariantID").Contains(availableOption.GetString("Ecom:VariantOption.ID")) && availableOption.GetString("Ecom:VariantOption.Name") != "Not applicable") 2050 { 2051 colourOption = availableOption.GetString("Ecom:VariantOption.Name"); 2052 colourId = availableOption.GetString("Ecom:VariantOption.ID"); 2053 } 2054 2055 } 2056 if (group.GetString("Ecom:VariantGroup.ID") == "ATP1") 2057 { 2058 if (variantCombinations.GetString("Ecom:VariantCombination.VariantID").Contains(availableOption.GetString("Ecom:VariantOption.ID")) && availableOption.GetString("Ecom:VariantOption.Name") != "Not applicable") 2059 { 2060 materialOption = availableOption.GetString("Ecom:VariantOption.Name"); 2061 materialId = availableOption.GetString("Ecom:VariantOption.ID"); 2062 } 2063 } 2064 if (group.GetString("Ecom:VariantGroup.ID") == "ATP3") 2065 { 2066 if (variantCombinations.GetString("Ecom:VariantCombination.VariantID").Contains(availableOption.GetString("Ecom:VariantOption.ID")) && availableOption.GetString("Ecom:VariantOption.Name") != "Not applicable") 2067 { 2068 anchorOption = availableOption.GetString("Ecom:VariantOption.Name"); 2069 anchorId = availableOption.GetString("Ecom:VariantOption.ID"); 2070 } 2071 } 2072 if (group.GetString("Ecom:VariantGroup.ID") == "ATP4") 2073 { 2074 if (variantCombinations.GetString("Ecom:VariantCombination.VariantID").Contains(availableOption.GetString("Ecom:VariantOption.ID")) && availableOption.GetString("Ecom:VariantOption.Name") != "Not applicable") 2075 { 2076 optionOption = availableOption.GetString("Ecom:VariantOption.Name"); 2077 optionId = availableOption.GetString("Ecom:VariantOption.ID"); 2078 } 2079 } 2080 if (variantCombinations.GetBoolean("Ecom:VariantCombination.Selected")) 2081 { 2082 selectedVariant = "selected-variant"; 2083 } 2084 } 2085 2086 } 2087 2088 <div class="product-card @selectedVariant" data-filter-colour="@colourId" data-filter-anchoring="@anchorId" data-filter-options="@optionId"> 2089 2090 <div class="product-card__img-silo"> 2091 @if (image != null && !String.IsNullOrEmpty(image.uri)) 2092 { 2093 <a href="@variantCombinations.GetString("Ecom:VariantCombination.Link.Clean")"><img src="@image.uri" class="product-card__img" /></a> 2094 } 2095 else 2096 { 2097 <img src="/Files/Templates/Designs/HagsCore/res/img/image-not-found.png" class="product-card__img" /> 2098 } 2099 </div> 2100 2101 2102 <div class="product-card__copy"> 2103 2104 @if (thisPage.AreaID == 7) /*UK*/ 2105 { 2106 string ukId = ProductFieldValues.GetUkProductNumber(variantCombinations.GetString("Ecom:VariantCombination.Product.Number"), thisPage.Area.EcomLanguageId); 2107 <h5 class="product-card__heading"><a href="@variantCombinations.GetString("Ecom:VariantCombination.Link.Clean")">@ukId.ToString()</a></h5> 2108 } 2109 else 2110 { 2111 <h5 class="product-card__heading"><a href="@variantCombinations.GetString("Ecom:VariantCombination.Link.Clean")">@variantCombinations.GetString("Ecom:VariantCombination.Product.Number")</a></h5> 2112 } 2113 2114 <p>@optionOption @colourOption - @anchorOption</p> 2115 2116 <!--<a class="" href="@variantCombinations.GetString("Ecom:VariantCombination.Link.Clean")" role="button">@Translate("ProductDetails", "Product Details")</a>--> 2117 </div> 2118 </div> 2119 2120 } 2121 </div> 2122 2123 <div class="m-message" style="display:none;padding-bottom:20px;padding-left:6px;"> 2124 <p style="font-size: 1.2em;color:red;"><b>@Translate("VariantFilterMessage", "There were no options available for selection.")</b></p> 2125 </div> 2126 </div> 2127 2128 } 2129 </section> 2130 2131 @*IncludeFile("partials/related-products.cshtml")*@ 2132 2133 2134 2135 2136 2137 @inherits Dynamicweb.Rendering.RazorTemplateBase<Dynamicweb.Rendering.RazorTemplateModel<Dynamicweb.Rendering.Template>> 2138 @using System.Collections.Generic 2139 @using HagsWeb.Library.BusinessObjects.UsersLists 2140 2141 @{ 2142 Layout = null; 2143 } 2144 <dialog id="CreateProductPdf" class="modal modal--full"> 2145 2146 <div class="modal__body"> 2147 2148 <div class="modal__header"> 2149 2150 <div class="modal__close"> 2151 <button type="button" class="action-btn js-modal-close-target" data-target-id="CreateProductPdf"> 2152 <span class="visually-hidden">Close</span> 2153 <svg viewBox="0 0 212 212" xmlns="http://www.w3.org/2000/svg" class="h24-icon h24-icon--close"><path d="M100 0c55.193 0 100 44.807 100 100s-44.807 100-100 100S0 155.193 0 100 44.807 0 100 0Zm0 5.333c-26.124 0-49.792 10.603-66.928 27.74C15.936 50.207 5.333 73.875 5.333 100c0 26.124 10.603 49.792 27.74 66.928 17.135 17.136 40.803 27.739 66.927 27.739 26.124 0 49.792-10.603 66.928-27.74 17.136-17.135 27.739-40.803 27.739-66.927 0-26.124-10.603-49.792-27.74-66.928C149.793 15.936 126.125 5.333 100 5.333Zm25.105 78.865L110.17 99.664l15.466 14.935a6.5 6.5 0 0 1 .16 9.191l-.694.72a6.5 6.5 0 0 1-9.191.16l-15.466-14.935-14.935 15.466a6.5 6.5 0 0 1-9.191.16l-.72-.694a6.5 6.5 0 0 1-.16-9.191l14.935-15.466-15.466-14.935a6.5 6.5 0 0 1-.16-9.191l.694-.72a6.5 6.5 0 0 1 9.191-.16L100.1 89.939l14.935-15.466a6.5 6.5 0 0 1 9.191-.16l.72.694a6.5 6.5 0 0 1 .16 9.191Z" fill="currentColor" fill-rule="evenodd"/></svg> 2154 </button> 2155 </div> 2156 2157 2158 <h4 class="modal-title" id="CreateCatalogModalLabel"> 2159 @Translate("YourProductSheet", "Your Product Sheet") 2160 </h4> 2161 2162 </div> 2163 2164 <div class="modal__main"> 2165 2166 <div id="div_CreateCatalog" class="modal__product-pdf"> 2167 2168 <div id="pdfwaiting" style="display:block;text-align:center"> 2169 <span id="CreateProductPdfLabel" style="display: inline-block;margin: 10px 10px 0 0;padding: 5px 10px"></span> 2170 <img src="Files/Templates/Designs/HagsCore/res/img/loader/ajax-loader.gif" style="margin:auto;display:block;" /> 2171 </div> 2172 2173 <div id="productPdfViewerloader" class="modal__embed-silo"> 2174 </div> 2175 2176 <div id="CreatePdfMessage"></div> 2177 </div> 2178 2179 2180 </div> 2181 2182 <div class="modal__footer"> 2183 2184 <div class="m-search-advanced-buttons cluster cluster--dialog"> 2185 <a href="" class="btn btn--outline" id="pdfPrintSheet" target="_blank" type="button">@Translate("Print", "Print")</a> 2186 <a href="" class="btn btn--outline" id="pdfDownloadSheet" download type="button">@Translate("Download", "Download")</a> 2187 <button class="btn btn--outline js-modal-close-target" data-target-id="CreateProductPdf" type="button">@Translate("Close", "Close")</button> 2188 </div> 2189 2190 </div> 2191 2192 </div> 2193 2194 </dialog> 2195 @*ProductPdfHelper(productCollectionItems, GetString("Ecom:Product.LanguageID"))*@ 2196 2197
Warranties
Find out what you are covered for.
Maintenance guide
How to look after your products.
Color & Anchoring Options
Explore your options.