Error executing template "Designs/Hags2024/eCom/Product/Product.cshtml" System.TypeInitializationException: The type initializer for '<>c' threw an exception. ---> System.OutOfMemoryException: Exception of type 'System.OutOfMemoryException' was thrown. at Microsoft.CodeAnalysis.CSharp.UsingStatementBinder.<>c..cctor() --- End of inner exception stack trace --- at Microsoft.CodeAnalysis.CSharp.LocalScopeBinder.LookupSymbolsInSingleBinder(LookupResult result, String name, Int32 arity, ConsList`1 basesBeingResolved, LookupOptions options, Binder originalBinder, Boolean diagnose, HashSet`1& useSiteDiagnostics) at Microsoft.CodeAnalysis.CSharp.Binder.LookupSymbolsInternal(LookupResult result, String name, Int32 arity, ConsList`1 basesBeingResolved, LookupOptions options, Boolean diagnose, HashSet`1& useSiteDiagnostics) at Microsoft.CodeAnalysis.CSharp.Binder.BindTypeOrAliasOrKeyword(SyntaxToken identifier, SyntaxNode syntax, DiagnosticBag diagnostics, Boolean& isKeyword) at Microsoft.CodeAnalysis.CSharp.Binder.BindTypeOrAliasOrVarKeyword(TypeSyntax syntax, DiagnosticBag diagnostics, Boolean& isVar) at Microsoft.CodeAnalysis.CSharp.Binder.BindTypeWithAnnotationsOrVarKeyword(TypeSyntax syntax, DiagnosticBag diagnostics, Boolean& isVar, AliasSymbol& alias) at Microsoft.CodeAnalysis.CSharp.Binder.BindForOrUsingOrFixedDeclarations(VariableDeclarationSyntax nodeOpt, LocalDeclarationKind localKind, DiagnosticBag diagnostics, ImmutableArray`1& declarations) at Microsoft.CodeAnalysis.CSharp.UsingStatementBinder.BindUsingStatementOrDeclarationFromParts(SyntaxNode syntax, SyntaxToken usingKeyword, SyntaxToken awaitKeyword, Binder originalBinder, UsingStatementBinder usingBinderOpt, DiagnosticBag diagnostics) at Microsoft.CodeAnalysis.CSharp.UsingStatementBinder.BindUsingStatementParts(DiagnosticBag diagnostics, Binder originalBinder) at Microsoft.CodeAnalysis.CSharp.Binder.BindStatement(StatementSyntax node, DiagnosticBag diagnostics) at Microsoft.CodeAnalysis.CSharp.Binder.BindBlockParts(BlockSyntax node, DiagnosticBag diagnostics) at Microsoft.CodeAnalysis.CSharp.Binder.BindEmbeddedBlock(BlockSyntax node, DiagnosticBag diagnostics) at Microsoft.CodeAnalysis.CSharp.Binder.BindTryStatement(TryStatementSyntax node, DiagnosticBag diagnostics) at Microsoft.CodeAnalysis.CSharp.Binder.BindStatement(StatementSyntax node, DiagnosticBag diagnostics) at Microsoft.CodeAnalysis.CSharp.Binder.BindBlockParts(BlockSyntax node, DiagnosticBag diagnostics) at Microsoft.CodeAnalysis.CSharp.Binder.BindStatement(StatementSyntax node, DiagnosticBag diagnostics) at Microsoft.CodeAnalysis.CSharp.Binder.BindPossibleEmbeddedStatement(StatementSyntax node, DiagnosticBag diagnostics) at Microsoft.CodeAnalysis.CSharp.Binder.BindIfStatement(IfStatementSyntax node, DiagnosticBag diagnostics) at Microsoft.CodeAnalysis.CSharp.Binder.BindStatement(StatementSyntax node, DiagnosticBag diagnostics) at Microsoft.CodeAnalysis.CSharp.Binder.BindBlockParts(BlockSyntax node, DiagnosticBag diagnostics) at Microsoft.CodeAnalysis.CSharp.Binder.BindStatement(StatementSyntax node, DiagnosticBag diagnostics) at Microsoft.CodeAnalysis.CSharp.Binder.BindPossibleEmbeddedStatement(StatementSyntax node, DiagnosticBag diagnostics) at Microsoft.CodeAnalysis.CSharp.Binder.BindIfStatement(IfStatementSyntax node, DiagnosticBag diagnostics) at Microsoft.CodeAnalysis.CSharp.Binder.BindStatement(StatementSyntax node, DiagnosticBag diagnostics) at Microsoft.CodeAnalysis.CSharp.Binder.BindBlockParts(BlockSyntax node, DiagnosticBag diagnostics) at Microsoft.CodeAnalysis.CSharp.Binder.BindEmbeddedBlock(BlockSyntax node, DiagnosticBag diagnostics) at Microsoft.CodeAnalysis.CSharp.PlainUnboundLambdaState.BindLambdaBody(LambdaSymbol lambdaSymbol, Binder lambdaBodyBinder, DiagnosticBag diagnostics) at Microsoft.CodeAnalysis.CSharp.UnboundLambdaState.ReallyBind(NamedTypeSymbol delegateType) at Microsoft.CodeAnalysis.CSharp.UnboundLambdaState.Bind(NamedTypeSymbol delegateType) at Microsoft.CodeAnalysis.CSharp.UnboundLambda.Bind(NamedTypeSymbol delegateType) at Microsoft.CodeAnalysis.CSharp.ConversionsBase.IsAnonymousFunctionCompatibleWithDelegate(UnboundLambda anonymousFunction, TypeSymbol type) at Microsoft.CodeAnalysis.CSharp.ConversionsBase.IsAnonymousFunctionCompatibleWithType(UnboundLambda anonymousFunction, TypeSymbol type) at Microsoft.CodeAnalysis.CSharp.ConversionsBase.HasAnonymousFunctionConversion(BoundExpression source, TypeSymbol destination) at Microsoft.CodeAnalysis.CSharp.ConversionsBase.ClassifyImplicitBuiltInConversionFromExpression(BoundExpression sourceExpression, TypeSymbol source, TypeSymbol destination, HashSet`1& useSiteDiagnostics) at Microsoft.CodeAnalysis.CSharp.ConversionsBase.ClassifyImplicitConversionFromExpression(BoundExpression sourceExpression, TypeSymbol destination, HashSet`1& useSiteDiagnostics) at Microsoft.CodeAnalysis.CSharp.OverloadResolution.CheckArgumentForApplicability(Symbol candidate, BoundExpression argument, RefKind argRefKind, TypeSymbol parameterType, RefKind parRefKind, Boolean ignoreOpenTypes, HashSet`1& useSiteDiagnostics, Boolean forExtensionMethodThisArg) at Microsoft.CodeAnalysis.CSharp.OverloadResolution.IsApplicable(Symbol candidate, EffectiveParameters parameters, AnalyzedArguments arguments, ImmutableArray`1 argsToParameters, Boolean isVararg, Boolean hasAnyRefOmittedArgument, Boolean ignoreOpenTypes, Boolean completeResults, HashSet`1& useSiteDiagnostics) at Microsoft.CodeAnalysis.CSharp.OverloadResolution.IsConstructorApplicableInNormalForm(MethodSymbol constructor, AnalyzedArguments arguments, Boolean completeResults, HashSet`1& useSiteDiagnostics) at Microsoft.CodeAnalysis.CSharp.OverloadResolution.AddConstructorToCandidateSet(MethodSymbol constructor, ArrayBuilder`1 results, AnalyzedArguments arguments, Boolean completeResults, HashSet`1& useSiteDiagnostics) at Microsoft.CodeAnalysis.CSharp.OverloadResolution.ObjectCreationOverloadResolution(ImmutableArray`1 constructors, AnalyzedArguments arguments, OverloadResolutionResult`1 result, HashSet`1& useSiteDiagnostics) at Microsoft.CodeAnalysis.CSharp.Binder.TryPerformConstructorOverloadResolution(NamedTypeSymbol typeContainingConstructors, AnalyzedArguments analyzedArguments, String errorName, Location errorLocation, Boolean suppressResultDiagnostics, DiagnosticBag diagnostics, MemberResolutionResult`1& memberResolutionResult, ImmutableArray`1& candidateConstructors, Boolean allowProtectedConstructorsOfBaseType) at Microsoft.CodeAnalysis.CSharp.Binder.BindClassCreationExpression(CSharpSyntaxNode node, String typeName, CSharpSyntaxNode typeNode, NamedTypeSymbol type, AnalyzedArguments analyzedArguments, DiagnosticBag diagnostics, InitializerExpressionSyntax initializerSyntaxOpt, TypeSymbol initializerTypeOpt) at Microsoft.CodeAnalysis.CSharp.Binder.BindClassCreationExpression(ObjectCreationExpressionSyntax node, NamedTypeSymbol type, String typeName, DiagnosticBag diagnostics, TypeSymbol initializerType) at Microsoft.CodeAnalysis.CSharp.Binder.BindObjectCreationExpression(ObjectCreationExpressionSyntax node, DiagnosticBag diagnostics) at Microsoft.CodeAnalysis.CSharp.Binder.BindExpressionInternal(ExpressionSyntax node, DiagnosticBag diagnostics, Boolean invoked, Boolean indexed) at Microsoft.CodeAnalysis.CSharp.Binder.BindExpression(ExpressionSyntax node, DiagnosticBag diagnostics, Boolean invoked, Boolean indexed) at Microsoft.CodeAnalysis.CSharp.Binder.BindReturn(ReturnStatementSyntax syntax, DiagnosticBag diagnostics) --- End of stack trace from previous location where exception was thrown --- at Microsoft.CodeAnalysis.CSharp.Binder.BindStatement(StatementSyntax node, DiagnosticBag diagnostics) at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) at Microsoft.CodeAnalysis.CSharp.Binder.BindStatement(StatementSyntax node, DiagnosticBag diagnostics) at Microsoft.CodeAnalysis.CSharp.Binder.BindMethodBody(CSharpSyntaxNode declaration, BlockSyntax blockBody, ArrowExpressionClauseSyntax expressionBody, DiagnosticBag diagnostics) at Microsoft.CodeAnalysis.CSharp.Binder.BindMethodBody(CSharpSyntaxNode syntax, DiagnosticBag diagnostics) at Microsoft.CodeAnalysis.CSharp.MethodCompiler.BindMethodBody(MethodSymbol method, TypeCompilationState compilationState, DiagnosticBag diagnostics, ImportChain& importChain, Boolean& originalBodyNested, InitialState& forSemanticModel) at Microsoft.CodeAnalysis.CSharp.MethodCompiler.CompileMethod(MethodSymbol methodSymbol, Int32 methodOrdinal, ProcessedFieldInitializers& processedInitializers, SynthesizedSubmissionFields previousSubmissionFields, TypeCompilationState compilationState) at Microsoft.CodeAnalysis.CSharp.MethodCompiler.CompileNamedType(NamedTypeSymbol containingType) at Microsoft.CodeAnalysis.CSharp.MethodCompiler.<>c__DisplayClass22_0.<CompileNamedTypeAsTask>b__0() at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at Microsoft.CodeAnalysis.CSharp.MethodCompiler.WaitForWorkers() at Microsoft.CodeAnalysis.CSharp.MethodCompiler.CompileMethodBodies(CSharpCompilation compilation, PEModuleBuilder moduleBeingBuiltOpt, Boolean emittingPdb, Boolean emitTestCoverageData, Boolean hasDeclarationErrors, DiagnosticBag diagnostics, Predicate`1 filterOpt, CancellationToken cancellationToken) at Microsoft.CodeAnalysis.CSharp.CSharpCompilation.CompileMethods(CommonPEModuleBuilder moduleBuilder, Boolean emittingPdb, Boolean emitMetadataOnly, Boolean emitTestCoverageData, DiagnosticBag diagnostics, Predicate`1 filterOpt, CancellationToken cancellationToken) at Microsoft.CodeAnalysis.Compilation.Emit(Stream peStream, Stream metadataPEStream, Stream pdbStream, Stream xmlDocumentationStream, Stream win32Resources, IEnumerable`1 manifestResources, EmitOptions options, IMethodSymbol debugEntryPoint, Stream sourceLinkStream, IEnumerable`1 embeddedTexts, CompilationTestData testData, CancellationToken cancellationToken) at Microsoft.CodeAnalysis.Compilation.Emit(Stream peStream, Stream pdbStream, Stream xmlDocumentationStream, Stream win32Resources, IEnumerable`1 manifestResources, EmitOptions options, IMethodSymbol debugEntryPoint, Stream sourceLinkStream, IEnumerable`1 embeddedTexts, Stream metadataPEStream, CancellationToken cancellationToken) at Microsoft.CodeAnalysis.Compilation.Emit(Stream peStream, Stream pdbStream, Stream xmlDocumentationStream, Stream win32Resources, IEnumerable`1 manifestResources, EmitOptions options, CancellationToken cancellationToken) at RazorEngine.Roslyn.CSharp.RoslynCompilerServiceBase.CompileType(TypeContext context) at RazorEngine.Templating.RazorEngineCore.CreateTemplateType(ITemplateSource razorTemplate, Type modelType) at RazorEngine.Templating.RazorEngineCore.Compile(ITemplateKey key, Type modelType) at RazorEngine.Templating.RazorEngineService.CompileAndCacheInternal(ITemplateKey key, Type modelType) at RazorEngine.Templating.RazorEngineService.GetCompiledTemplate(ITemplateKey key, Type modelType, Boolean compileOnCacheMiss) 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() at Roslyn.Utilities.UICultureUtilities.<>c__DisplayClass5_0.<WithCurrentUICulture>b__0() at System.Threading.Tasks.Task.InnerInvoke() at System.Threading.Tasks.Task.Execute() --- End of stack trace from previous location where exception was thrown --- at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at Microsoft.CodeAnalysis.CSharp.MethodCompiler.WaitForWorkers() at Microsoft.CodeAnalysis.CSharp.MethodCompiler.CompileMethodBodies(CSharpCompilation compilation, PEModuleBuilder moduleBeingBuiltOpt, Boolean emittingPdb, Boolean emitTestCoverageData, Boolean hasDeclarationErrors, DiagnosticBag diagnostics, Predicate`1 filterOpt, CancellationToken cancellationToken) at Microsoft.CodeAnalysis.CSharp.CSharpCompilation.CompileMethods(CommonPEModuleBuilder moduleBuilder, Boolean emittingPdb, Boolean emitMetadataOnly, Boolean emitTestCoverageData, DiagnosticBag diagnostics, Predicate`1 filterOpt, CancellationToken cancellationToken) at Microsoft.CodeAnalysis.Compilation.Emit(Stream peStream, Stream metadataPEStream, Stream pdbStream, Stream xmlDocumentationStream, Stream win32Resources, IEnumerable`1 manifestResources, EmitOptions options, IMethodSymbol debugEntryPoint, Stream sourceLinkStream, IEnumerable`1 embeddedTexts, CompilationTestData testData, CancellationToken cancellationToken) at Microsoft.CodeAnalysis.Compilation.Emit(Stream peStream, Stream pdbStream, Stream xmlDocumentationStream, Stream win32Resources, IEnumerable`1 manifestResources, EmitOptions options, IMethodSymbol debugEntryPoint, Stream sourceLinkStream, IEnumerable`1 embeddedTexts, Stream metadataPEStream, CancellationToken cancellationToken) at Microsoft.CodeAnalysis.Compilation.Emit(Stream peStream, Stream pdbStream, Stream xmlDocumentationStream, Stream win32Resources, IEnumerable`1 manifestResources, EmitOptions options, CancellationToken cancellationToken) at RazorEngine.Roslyn.CSharp.RoslynCompilerServiceBase.CompileType(TypeContext context) at RazorEngine.Templating.RazorEngineCore.CreateTemplateType(ITemplateSource razorTemplate, Type modelType) at RazorEngine.Templating.RazorEngineCore.Compile(ITemplateKey key, Type modelType) at RazorEngine.Templating.RazorEngineService.CompileAndCacheInternal(ITemplateKey key, Type modelType) at RazorEngine.Templating.RazorEngineService.GetCompiledTemplate(ITemplateKey key, Type modelType, Boolean compileOnCacheMiss) 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 <article class="flow"> 479 480 <nav class="breadcrumb"> 481 <div class="wrapper"> 482 @renderPageBreadcrumb(pageUrl, GetGlobalValue("Global:Area.LongLang"), @GetString("Ecom:Product.Name"), variantOptions) 483 </div> 484 </nav> 485 486 487 <section class="product-header"> 488 489 <div class="wrapper flow"> 490 <h1>@GetString("Ecom:Product.Name")</h1> 491 @using System.Web; 492 @using System.Globalization; 493 494 @{ 495 bool centralStock = GetBoolean("Ecom:Product:Field.CentralStock"); 496 bool swedishStock = GetBoolean("Ecom:Product:Field.SwedishStock"); 497 string ipAddress = HttpContext.Current.Request.ServerVariables["remote_addr"]; 498 string weglotLang = System.Web.HttpContext.Current.Request.Headers["weglot-language"]; 499 string productNumberDisplay = productNumber; 500 string formattedCurrency = GetInteger("Ecom:Product.DBPrice").ToString("C", new CultureInfo("sv-SE")); 501 } 502 @if ( weglotLang == "se" || weglotLang == "da" ) 503 { 504 if ( swedishStock ) 505 { 506 productNumberDisplay = productNumber + "-1"; 507 } 508 } 509 else 510 { 511 if (centralStock) 512 { 513 productNumberDisplay = productNumberDisplay + "-2"; 514 } 515 } 516 517 518 <p class="product-number">@productNumberDisplay</p> 519 520 @* 521 <!-- central: @centralStock swedish: @swedishStock --> 522 <!-- Integer DB price: @GetInteger("Ecom:Product.DBPrice") --> 523 <!-- String Price Formatted: @GetString("Ecom:Product.Price.PriceFormatted") --> 524 <!-- String Price: @GetString("Ecom:Product.Price") --> 525 <!-- IP address: @ipAddress --> 526 <!-- Weglot language: @weglotLang --> 527 <!-- formatted currency: @formattedCurrency --> 528 *@ 529 530 </div> 531 532 <div class="wrapper"> 533 534 <div class="fc-zoom"> 535 @*Zoom Product Images*@ 536 @if (zoomList.Count > 0) 537 538 { 539 <div class="fc-zoom__view"> 540 <div class="fc-zoom__target" id="zoom-target-1"> 541 @{ 542 var i = 0; 543 string resizeUrl = "/Admin/Public/GetImage.ashx?Image="; 544 string resizeOptions = "&Crop=0&Format=jpg&Height=350&Compression=75"; 545 } 546 @foreach (var zoomSet in zoomList) 547 { 548 string[,] imgSet = zoomSet.Value; 549 string imgId = string.Format("img_0{0}", zoomSet.Key); 550 string imageUrl = resizeUrl + imgSet[0, 2] + resizeOptions; 551 552 553 if (i == 0) 554 { 555 556 <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")"> 557 } 558 else 559 { 560 <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")"> 561 } 562 i++; 563 } 564 </div> 565 566 <button class="fc-zoom__button fc-zoom__button--in reel-cards__btn" id="zoom-toggle"> 567 <span class="visually-hidden">Toggle Zoom</span> 568 <span class="fc-zoom__icon fc-zoom__icon--in"> 569 <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> 570 </span> 571 <span class="fc-zoom__icon fc-zoom__icon--out"> 572 <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> 573 </span> 574 </button> 575 </div> 576 577 <div class="reel-thumbs fc-zoom__thumbs" id="zoom-gallery"> 578 579 <button 580 class="reel-cards__btn reel-cards__btn--prev" 581 data-action-page="Product" 582 data-action-type="Button" 583 data-action-label="Gallery prev" 584 data-action-value="@productNumber"> 585 <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> 586 <span class="visually-hidden">@Translate("page_Previous", "Previous")</span> 587 </button> 588 589 <div class="reel-thumbs__viewport"> 590 591 <div class="fc-zoom__thumbs-list reel-thumbs__container"> 592 @{ i = 0; } 593 @foreach (var zoomSet in zoomList) 594 { 595 string[,] imgSet = zoomSet.Value; 596 string imgId = string.Format("img_0{0}", zoomSet.Key); 597 <div class="reel-thumbs__frame"> 598 <a class="fc-zoom__link" href="@imgSet[0, 1]" data-image-target="zoom-full-image-@i" data-image="" data-zoom-image="@imgSet[0, 2]"> 599 <img class="fc-zoom__thumb" src="@imgSet[0, 0]" alt="@GetString("Ecom:Product.Name")"> 600 </a> 601 </div> 602 i++; 603 604 } 605 </div> 606 607 </div> 608 609 <button 610 class="reel-cards__btn reel-cards__btn--next" 611 data-action-page="Product" 612 data-action-type="Button" 613 data-action-label="Gallery next" 614 data-action-value="@productNumber"> 615 <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> 616 <span class="visually-hidden">@Translate("page_Next", "Next")</span> 617 </button> 618 619 620 621 </div> 622 } 623 </div> 624 625 626 </section> 627 628 629 <div class="page-intro wrapper"> 630 631 <div class="page-intro__copy flow"> 632 633 <div class="cluster"> 634 @* add to collection button *@ 635 @if (isProductCollection) 636 { 637 <button type="button" class="btn btn--outline print-hide" data-removeproductlist="@productNumber" data-addproductlist=""> 638 @Translate("RemoveFromCollection", "Remove from my Collection") 639 </button> 640 } 641 else 642 { 643 <button 644 type="button" 645 class="btn btn--outline print-hide" 646 data-removeproductlist="" 647 data-addproductlist="@collectionData" 648 data-action-page="Product" data-action-type="button" data-action-label="Add to collection" data-action-value="@productNumber"> 649 @Translate("AddToCollection", "Add to my collection") 650 </button> 651 } 652 653 @* download images button *@ 654 @if (hiResDownloads.Count() > 0) 655 { 656 List <string> fileList = new List<string>(); 657 foreach (var file in hiResDownloads) 658 { 659 fileList.Add(file.FullPath); 660 } 661 <form method="post" id="downloadImagesForm"> 662 <input type="hidden" name="ProductNumber" value="@productNumber" /> 663 <input type="hidden" name="ProductName" value="@GetString("Ecom:Product.Name")" /> 664 @GetButton(fileList, "Product", productNumber) 665 </form> 666 } 667 668 @* PDF Product sheet button *@ 669 @{ 670 string printShout = Translate("SaveOrPrint", "Save or Print your Product PDF "); 671 string productId = @GetString("Ecom:Product.ID"); 672 string productVariantId = @GetString("Ecom:Product.VariantID"); 673 } 674 <button type="button" id="productSheetButton" data-target="#CreateProductPdf" 675 name="productPublishing" data-productid="@productId" data-productnumber="@productNumber" 676 data-variantid="@productVariantId" data-open-modal="#CreateProductPdf" data-request="technicalsheet" data-shout="@printShout" 677 class="btn btn--outline" 678 data-action-page="Product" data-action-type="button" data-action-label="Create product PDF" data-action-value="@productNumber"> 679 @Translate("ProductSheet", "PDF Product Sheet") 680 </button> 681 682 683 </div> 684 685 @*if (!string.IsNullOrWhiteSpace(GetString("Ecom:Product.ShortDescription"))) 686 { 687 <p>@GetString("Ecom:Product.ShortDescription")</p> 688 } 689 *@ 690 691 @if (!string.IsNullOrWhiteSpace(GetString("Ecom:Product.LongDescription"))) 692 { 693 @* 694 string paragraph = GetString("Ecom:Product.LongDescription"); 695 string[] paragraphs = paragraph.Split(new[] { '.' }, StringSplitOptions.RemoveEmptyEntries); 696 foreach (var p in paragraphs) 697 { 698 <p>@p.Trim().</p> 699 } 700 *@ 701 <p>@GetString("Ecom:Product.LongDescription")</p> 702 703 } 704 705 <div class="cluster" title="@Translate(" Anchoring", "Anchoring"): @selectedAnchoringVariant"> 706 707 @if ( GetBoolean("Ecom:Product:Field.CentralStock") && (weglotLang != "se" && weglotLang != "da") ) 708 { 709 <div class="product-icon" title="Leverans ex lager från Sverige"> 710 <img class="product-icon__icon" src="/Files/Images/Other/Playground box/Lorry.jpg" alt="Leverans ex lager från Sverige" /> 711 <p>Fast Delivery</p> 712 </div> 713 } 714 715 @if ( (weglotLang == "se" || weglotLang == "da") && swedishStock ) 716 { 717 <div class="product-icon" title="Leverans ex lager från Sverige"> 718 <img class="product-icon__icon" src="/Files/Images/Other/Playground box/Lorry.jpg" alt="Leverans ex lager från Sverige" /> 719 <p>Fast Delivery</p> 720 </div> 721 } 722 723 724 725 @if (!string.IsNullOrWhiteSpace(selectedAnchoringIcon ?? selectedAnchoringVariant)) 726 { 727 728 <div class="product-icon"> 729 <img class="product-icon__icon" src="Files/Templates/Designs/HagsCore/res/img/icons/anchoring/@selectedAnchoringIcon" alt="@selectedAnchoringVariant" /> 730 @selectedAnchoringVariant 731 </div> 732 } 733 734 </div> 735 736 <p> 737 @(selectedMaterialVariant != "" ? selectedMaterialVariant + " - " : "") 738 @(selectedOptionVariant != "" ? selectedOptionVariant + " - " : "") 739 @(@selectedColourVariant != "" ? selectedColourVariant : "") 740 </p> 741 742 @using System.Web; 743 @using System.Globalization; 744 @using System.IO; 745 @using System.Linq; 746 @using System.Net; 747 @using System.Configuration; 748 749 @{ 750 //string ipAddress = HttpContext.Current.Request.ServerVariables["remote_addr"]; 751 //string weglotLang = System.Web.HttpContext.Current.Request.Headers["weglot-language"]; 752 //string formattedCurrency = GetInteger("Ecom:Product.DBPrice").ToString("C", new CultureInfo("sv-SE")); 753 bool showPrice = false; 754 string ipCountryCode = ""; 755 756 if ( (weglotLang == "se") ) 757 { 758 string ipLookupKey = ConfigurationManager.AppSettings["ExtremeIpLookupApiKey"].ToString(); 759 string ipLookupUrl = "http://extreme-ip-lookup.com/json/" + ipAddress + "?key=" + ipLookupKey; 760 string ipLookupError = ""; 761 762 763 HttpWebRequest ipLookupRequest = (HttpWebRequest)WebRequest.Create(ipLookupUrl); 764 ipLookupRequest.Method = "GET"; // Set method to GET 765 ipLookupRequest.ContentType = "application/json"; 766 767 try 768 { 769 // Get the response from the API 770 using (HttpWebResponse ipLookupResponse = (HttpWebResponse)ipLookupRequest.GetResponse()) 771 { 772 // Check if the response is OK 773 if (ipLookupResponse.StatusCode == HttpStatusCode.OK) 774 { 775 // Read the response stream 776 using (StreamReader reader = new StreamReader(ipLookupResponse.GetResponseStream())) 777 { 778 // Parse the JSON response 779 string jsonResponse = reader.ReadToEnd(); 780 781 // Parse JSON using JObject (from Newtonsoft.Json.Linq) 782 Newtonsoft.Json.Linq.JObject jsonObject = Newtonsoft.Json.Linq.JObject.Parse(jsonResponse); 783 784 // Extract a specific value (assuming the JSON has a field named "desiredField") 785 ipCountryCode = (string)jsonObject["countryCode"]; 786 ipCountryCode = ipCountryCode.ToLower(); 787 } 788 } 789 } 790 } 791 792 catch (Exception ex) 793 { 794 // Handle any errors 795 //set default to au 796 ipCountryCode = ""; 797 ipLookupError = ex.Message; 798 } 799 800 if ( ipCountryCode == "se" ) { 801 showPrice = true; 802 } 803 } 804 805 } 806 807 808 @if ( showPrice ) { 809 810 <p> 811 <span class="ts-3">@formattedCurrency</span> <span>(Excluding VAT)</span> 812 </p> 813 814 } 815 816 <!-- @formattedCurrency --> 817 818 @* 819 <!-- IP address: @ipAddress --> 820 <!-- Weglot language: @weglotLang --> 821 <!-- formatted currency: @formattedCurrency --> 822 *@ 823 824 </div> 825 </div> 826 827 828 829 <section> 830 <div class="wrapper"> 831 832 <div class="center-copy"> 833 834 @{ 835 string[] badges = GetString("Ecom:Product:Field.EnvironmentalBadge.Value").Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries).ToArray(); 836 } 837 <div> 838 <ul class="badges"> 839 @foreach (var badge in badges) 840 { 841 string altText = ""; 842 843 if (badge == "NSEL") 844 { 845 altText = Translate("CertifiedNordicSwan", "Certified by Nordic Swan"); 846 } 847 848 if ( badge == "BVB8" ) { 849 altText = Translate("BVBGradeAccepted", "Assessed by Byggvarubedömningen, Grade: Accepted"); 850 } 851 852 if ( badge == "BVB7" ) { 853 altText = Translate("BVBGradeRecommended", "Assessed by Byggvarubedömningen, Grade: Recommended"); 854 } 855 856 if ( badge == "SH1" ) { 857 altText = Translate("SundaHusGradeB", "Assessed by SundaHus, Grade: B"); 858 } 859 860 if ( badge == "SH2" ) { 861 altText = Translate("SundaHusGradeA", "Assessed by SundaHus, Grade: A"); 862 } 863 <li class="badges__item"><img src="@(designBaseUrl)assets/img/badges/@(badge).png" alt="@altText" title="@altText" /></li> 864 } 865 </ul> 866 </div> 867 868 <div class="accordians"> 869 870 <section class="accordian"> 871 <div class="wrapper"> 872 873 <h3><button 874 id="accordian-spec" 875 aria-expanded="true" aria-controls="accordian-spec-panel" type="button" 876 class="accordian__button" 877 data-action-page="Product" 878 data-action-type="Text block expand" 879 data-action-label="Specifications" 880 data-action-value="@productNumber"> 881 @Translate("ProductSpecifications", "Product Specifications") 882 <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> 883 <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> 884 </button> 885 </h3> 886 887 <div class="accordian__panel" id="accordian-spec-panel"> 888 <div class="accordian__content flow"> 889 890 @if (!String.IsNullOrWhiteSpace(@GetString("Ecom:Product:Field.IPEMA_Specification"))) 891 { 892 string ipemaData = GetString("Ecom:Product:Field.IPEMA_Specification"); 893 // Get IPEMA Product Specification data from a Field on the Product data from Jeeves 894 //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")); 895 System.Xml.Linq.XDocument dataXML = System.Xml.Linq.XDocument.Parse(ipemaData); 896 897 if (dataXML != null) 898 { 899 @*<h1> @GetString("Ecom:Product.Name") </h1>*@ 900 @*<p>@dataXML</p>*@ 901 System.Globalization.NumberFormatInfo format = new System.Globalization.NumberFormatInfo(); 902 903 var details = from dat in dataXML.Descendants("Item") 904 select new 905 { 906 name = dat.Element("name").Value, 907 enValue = dat.Element("EN_value").Value, 908 astmValue = dat.Element("ASTM_value").Value, 909 csaValue = dat.Element("CSA_value").Value 910 }; 911 912 <table class="table"> 913 <thead> 914 <tr> 915 <th scope="col"></th> 916 <th scope="col">@Translate("Europe","Europe")<br>EN1176</th> 917 <th scope="col">@Translate("USA", "USA")<br>ASTM F1487</th> 918 <th scope="col">@Translate("Canada", "Canada")<br>CSA Z614</th> 919 </tr> 920 </thead> 921 922 <tbody> 923 @foreach (var item in details) 924 { 925 <tr> 926 <td>@item.name</td> 927 <td>@item.enValue</td> 928 <td>@item.astmValue</td> 929 <td>@item.csaValue</td> 930 </tr> 931 } 932 </tbody> 933 </table> 934 935 @*#table-IPEMA Product Spec*@ 936 } 937 938 } else { 939 <table class="table"> 940 <thead> 941 <tr> 942 <th scope="col"></th> 943 <th scope="col"></th> 944 </tr> 945 </thead> 946 <tbody> 947 948 @if (!String.IsNullOrWhiteSpace(GetString("Ecom:Product:Field.NumberOfChildren"))) 949 { 950 <tr> 951 <td>@GetString("Ecom:Product:Field.NumberOfChildren.Name")</td> 952 <td>@GetString("Ecom:Product:Field.NumberOfChildren.Value")</td> 953 </tr> 954 } 955 @if (!String.IsNullOrWhiteSpace(GetString("Ecom:Product:Field.AgeRange")) && ageRanges.Any()) 956 { 957 <tr> 958 <td>@GetString("Ecom:Product:Field.AgeRange.Name")</td> 959 <td>@string.Join(", ", ageRanges)</td> 960 </tr> 961 } 962 @if (GetDouble("Ecom:Product:Field.AssemblyTime.Value.Raw") > 0) 963 { 964 <tr> 965 <td>@GetString("Ecom:Product:Field.AssemblyTime.Name")</td> 966 <td>@GetDouble("Ecom:Product:Field.AssemblyTime.Value.Raw") @Translate("Hours", "hours")</td> 967 </tr> 968 } 969 @if (GetDouble("Ecom:Product:Field.Length.Value.Raw") > 0) 970 { 971 <tr> 972 <td>@GetString("Ecom:Product:Field.Length.Name").Replace(" (mm)", "")</td> 973 <td>@GetString("Ecom:Product:Field.Length.Value.Raw") mm</td> 974 </tr> 975 } 976 @if (GetDouble("Ecom:Product:Field.Width.Value.Raw") > 0) 977 { 978 <tr> 979 <td>@GetString("Ecom:Product:Field.Width.Name").Replace(" (mm)", "")</td> 980 <td>@GetString("Ecom:Product:Field.Width.Value.Raw") mm</td> 981 </tr> 982 } 983 @if (GetDouble("Ecom:Product:Field.Height.Value.Raw") > 0) 984 { 985 <tr> 986 <td>@GetString("Ecom:Product:Field.Height.Name").Replace(" (mm)", "")</td> 987 <td>@GetString("Ecom:Product:Field.Height.Value.Raw") mm</td> 988 </tr> 989 } 990 @if (GetDouble("Ecom:Product:Field.NetWeight.Value.Raw") > 0) 991 { 992 <tr> 993 <td>@GetString("Ecom:Product:Field.NetWeight.Name")</td> 994 <td>@GetString("Ecom:Product:Field.NetWeight.Value") kg</td> 995 </tr> 996 } 997 @if (GetDouble("Ecom:Product:Field.Volume.Value.Raw") > 0) 998 { 999 <tr> 1000 <td>@GetString("Ecom:Product:Field.Volume.Name")</td> 1001 <td>@GetString("Ecom:Product:Field.Volume.Value.Raw") m³</td> 1002 </tr> 1003 } 1004 @if (GetDouble("Ecom:Product:Field.FallHeight.Value.Raw") > 0) 1005 { 1006 <tr> 1007 <td>@GetString("Ecom:Product:Field.FallHeight.Name").Replace(" (mm)", "")</td> 1008 <td>@GetString("Ecom:Product:Field.FallHeight.Value.Raw") mm</td> 1009 </tr> 1010 } 1011 @if (GetDouble("Ecom:Product:Field.SafetyAreaWidth.Value.Raw") > 0) 1012 { 1013 <tr> 1014 <td>@GetString("Ecom:Product:Field.SafetyAreaWidth.Name").Replace(" (mm)", "")</td> 1015 <td>@GetString("Ecom:Product:Field.SafetyAreaWidth.Value.Raw") mm</td> 1016 </tr> 1017 } 1018 @if (GetDouble("Ecom:Product:Field.SafetyAreaLength.Value.Raw") > 0) 1019 { 1020 <tr> 1021 <td>@GetString("Ecom:Product:Field.SafetyAreaLength.Name").Replace(" (mm)", "")</td> 1022 <td>@GetString("Ecom:Product:Field.SafetyAreaLength.Value.Raw") mm</td> 1023 </tr> 1024 } 1025 @if (GetDouble("Ecom:Product:Field.SafetyArea.Value.Raw") > 0) 1026 { 1027 <tr> 1028 <td>@GetString("Ecom:Product:Field.SafetyArea.Name")</td> 1029 <td>@GetDouble("Ecom:Product:Field.SafetyArea.Value") m²</td> 1030 </tr> 1031 } 1032 1033 </tbody> 1034 </table> 1035 1036 } 1037 1038 @*SafetyAreaDetails*@ 1039 @if (GetDouble("Ecom:Product:Field.SafetyArea.Value") > 0 && thisPage.AreaID == 1) 1040 { 1041 string safetyAreaPage = DWUtilities.GetPageByNavigationTag("SafetyArea", thisPage.AreaID); 1042 if (!string.IsNullOrEmpty(safetyAreaPage)) 1043 { 1044 <p><a href="@safetyAreaPage" class="print-hide">@Translate("ReadMoreSafetyArea", "Read more about safety areas")</a></p> 1045 } 1046 1047 } 1048 1049 @*Anchoring from Variant*@ 1050 @if (!string.IsNullOrEmpty(selectedAnchoringVariant)) 1051 { 1052 string anchoringPage = DWUtilities.GetPageByNavigationTag("AnchoringTypes", thisPage.AreaID) + "#" + GetGlobalValue("Global:HagsTheme"); 1053 1054 if (!string.IsNullOrEmpty(anchoringPage)) 1055 { 1056 <p><a href="@anchoringPage" class="btn btn--outline print-hide">@Translate("ReadMoreAnchoring", "Read more about anchoring")</a></p> 1057 } 1058 1059 } 1060 1061 @*Guarantee Page for Sweden*@ 1062 @if (thisPage.AreaID == 2) 1063 { 1064 <p><a href="/sv-se/om-hags/garantier" target="_blank" class="print-hide">Läs mer om produktgarantier</a></p> 1065 } 1066 </div> 1067 </div> 1068 </section> 1069 @if (!string.IsNullOrWhiteSpace(GetString("Ecom:Product:Field.Material"))) 1070 { 1071 <section class="accordian"> 1072 <div class="wrapper"> 1073 1074 <h3> 1075 <button id="accordian-materials" aria-expanded="true" aria-controls="accordian-materials-panel" type="button" class="accordian__button" 1076 data-action-page="Product" 1077 data-action-type="Text block expand" 1078 data-action-label="Materials" 1079 data-action-value="@productNumber"> 1080 @GetString("Ecom:Product:Field.Material.Name") 1081 <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> 1082 <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> 1083 </button> 1084 </h3> 1085 1086 <div class="accordian__panel" id="accordian-materials-panel"> 1087 <div class="accordian__content"> 1088 1089 @{ 1090 1091 string materialData = GetString("Ecom:Product:Field.Material");// Get Material data from a Field on the Product data from Jeeves (not implemented yet) GetString("Ecom:Product:Field.MaterialData"); 1092 if (!string.IsNullOrEmpty(materialData)) 1093 { 1094 //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")); 1095 System.Xml.Linq.XDocument dataXML = System.Xml.Linq.XDocument.Parse(materialData); 1096 1097 if (dataXML != null) 1098 { 1099 System.Globalization.NumberFormatInfo format = new System.Globalization.NumberFormatInfo(); 1100 //format.NumberGroupSeparator = ","; //for thousands 1101 //format.NumberDecimalSeparator = "."; //the decimal seperator 1102 1103 var totalweight = Math.Round((from nd in dataXML.Descendants("kg") 1104 select Double.Parse(nd.Value, format)).Sum(), 0).ToString(); 1105 1106 var totalpercent = Math.Round((from nd in dataXML.Descendants("percent") 1107 select Double.Parse(nd.Value, format)).Sum(), 0).ToString(); 1108 1109 var details = from dat in dataXML.Descendants("Item") 1110 select new 1111 { 1112 material = dat.Element("material").Value, 1113 //weight = dat.Element("kg").Value,// string.Format("{0:0.00}", Double.Parse(dat.Element("kg").Value)), Occasionally throwing format errors 1114 weight = Math.Round(Double.Parse(dat.Element("kg").Value, format), 1).ToString(),// string.Format("{0:0.00}", Double.Parse(dat.Element("kg").Value)), Occasionally throwing format errors 1115 percent = Math.Round(Double.Parse(dat.Element("percent").Value, format), 1).ToString() // string.Format("{0:0.00}", Double.Parse(dat.Element("percent").Value)) 1116 }; 1117 1118 <table class="table"> 1119 <thead> 1120 <tr> 1121 <th scope="col">@GetString("Ecom:Product:Field.Material.Name")</th> 1122 <th scope="col">kg</th> 1123 <th scope="col">%</th> 1124 </tr> 1125 </thead> 1126 1127 <tbody> 1128 1129 @foreach (var item in details) 1130 { 1131 <tr> 1132 <td>@item.material</td> 1133 <td>@item.weight</td> 1134 <td>@item.percent</td> 1135 </tr> 1136 } 1137 1138 1139 1140 </tbody> 1141 1142 <tfoot> 1143 <tr> 1144 <td> </td> 1145 <td><strong>@totalweight kg</strong></td> 1146 <td><strong>@totalpercent%</strong></td> 1147 </tr> 1148 </tfoot> 1149 </table> <!--! #table-materials --> 1150 } 1151 } 1152 1153 } 1154 </div> 1155 </div> 1156 </div> 1157 </section> 1158 } 1159 @if (imagesCount + brochCount < assets.Count()) 1160 { 1161 1162 1163 } 1164 1165 @helper renderAccordianPanel(List<ProductAsset> assetList, string assetType, string translationTitle, string fallbackTitle, string extraContent = "", string productNumber = "" ) { 1166 1167 <section class="accordian print-hide"> 1168 <div class="wrapper"> 1169 <h3> 1170 <button id="accordian-downloads-@assetType" 1171 aria-expanded="true" aria-controls="accordian-panel-downloads-@assetType" type="button" class="accordian__button" 1172 data-action-page="Product" 1173 data-action-type="Text block expand" 1174 data-action-label="@translationTitle" 1175 data-action-value="@productNumber"> 1176 @Translate(translationTitle, fallbackTitle) 1177 <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> 1178 <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> 1179 </button> 1180 </h3> 1181 1182 1183 <div class="accordian__panel" id="accordian-panel-downloads-@assetType"> 1184 <div class="accordian__content"> 1185 <ul class="downloads__list"> 1186 @foreach (ProductAsset asset in assetList) 1187 { 1188 1189 <li> 1190 <a href="@asset.uri" download="@asset.FileName"> 1191 <span>@asset.FileName</span> 1192 </a> 1193 </li> 1194 } 1195 </ul> 1196 1197 @extraContent 1198 </div> 1199 </div> 1200 1201 </div> 1202 </section> 1203 1204 } 1205 1206 @* Certificates *@ 1207 1208 @{ 1209 List<ProductAsset> certAssets = new List<ProductAsset>(); 1210 1211 if (thisPage.AreaID == 1) // For Global get all certificates 1212 { 1213 certAssets = assets.Where(n => n.Index == AssetTypeEnum.ToFriendlyAssetName(AssetType.Certificates)).ToList(); 1214 } 1215 else 1216 { 1217 certAssets = assets.Where(n => n.Index == AssetTypeEnum.ToFriendlyAssetName(AssetType.Certificates) && n.FileName.StartsWith(currentCountry + "_")).ToList(); 1218 } 1219 1220 if (certAssets.Count() == 0) // if none are found try to get EN certificates 1221 { 1222 certAssets = assets.Where(n => n.Index == AssetTypeEnum.ToFriendlyAssetName(AssetType.Certificates) && n.FileName.StartsWith("EN_")).ToList(); 1223 } 1224 if (certAssets.Count() == 0) // if none are found try to get GB certificates 1225 { 1226 certAssets = assets.Where(n => n.Index == AssetTypeEnum.ToFriendlyAssetName(AssetType.Certificates) && n.FileName.StartsWith("GB_")).ToList(); 1227 } 1228 } 1229 1230 1231 @if (certAssets.Count > 0) 1232 { 1233 @renderAccordianPanel(certAssets, "certificates", "Certificates", "Certificates","",productNumber) 1234 } 1235 1236 1237 @* Assembly Instructions *@ 1238 1239 @{ 1240 List<ProductAsset> assemblyAssets = new List<ProductAsset>(); 1241 assemblyAssets = assets.Where(n => n.Index == AssetTypeEnum.ToFriendlyAssetName(AssetType.AssemblyInstructions)).ToList(); 1242 } 1243 1244 @if (assemblyAssets.Count > 0) 1245 { 1246 string extraContent = "<button class=\"productDownloadButton download btn btn--outline\" name=\"download\" data-parent=\"Monteringsanvisningar\""; 1247 extraContent += " data-productnumber=\"" + productNumber + "\" data-productname=\"" + GetString("Ecom:Product.Name") +"\">"; 1248 extraContent += Translate("DownloadInstallationGuides", "Installation Guides") + "</button>"; 1249 1250 @renderAccordianPanel(assemblyAssets, "install-guides", "InstallationGuides", "Installation Guides", extraContent, productNumber) 1251 } 1252 1253 @{ 1254 // add relatedProductsAssemblyInstructions to product assemblyAssets and store to session. Used in UsersProductCollection.GetAssets for the product 1255 assemblyAssets.AddRange(relatedProductsAssemblyInstructions); 1256 SessionManager.SetSession(productNumber + "_" + AssetType.AssemblyInstructions.ToFriendlyAssetName(), new List<ProductAsset>(assemblyAssets)); 1257 } 1258 1259 @* Detailed Assembly Instructions *@ 1260 1261 @{ 1262 // add relatedProductsAssemblyInstructions to product assemblyAssets and store to session. Used in UsersProductCollection.GetAssets for the product 1263 assemblyAssets.AddRange(relatedProductsAssemblyInstructions); 1264 SessionManager.SetSession(productNumber + "_" + AssetType.AssemblyInstructions.ToFriendlyAssetName(), new List<ProductAsset>(assemblyAssets)); 1265 } 1266 1267 @if (relatedProductsAssemblyInstructions.Count > 0) 1268 { 1269 1270 @renderAccordianPanel(relatedProductsAssemblyInstructions, "detail-guides", "DetailedInstallationGuides", "Detailed Installation Guides","",productNumber) 1271 } 1272 1273 1274 @{ 1275 List<ProductAsset> inspAssets = new List<ProductAsset>(); 1276 //inspAssets = FileSystem.GetPdfFilesFromDirectoryBySiteCulture("/Files/System/ProductCollectionDownloads/InspectionMaintenance", "_" + currentlanguage.ToUpper()); 1277 inspAssets = FileSystem.GetAllPdfFilesFromDirectory("/Files/System/ProductCollectionDownloads/InspectionMaintenance"); 1278 } 1279 1280 @if (inspAssets != null && inspAssets.Count > 0) 1281 { 1282 @renderAccordianPanel(inspAssets, "insp-maintenance", "InspectionMaintenance", "Inspection & Maintenance","",productNumber) 1283 } 1284 else 1285 { 1286 <section class="accordian print-hide"> 1287 <div class="wrapper"> 1288 <h3> 1289 <button id="accordian-downloads-insp-maintenance" 1290 aria-expanded="true" aria-controls="accordian-panel-downloads-insp-maintenance" 1291 type="button" class="accordian__button" 1292 data-action-page="Product" 1293 data-action-type="Text block expand" 1294 data-action-label="InspectionMaintenance" 1295 data-action-value="@productNumber"> 1296 @Translate("InspectionMaintenance", "Inspection & Maintenance") 1297 <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> 1298 <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> 1299 </button> 1300 </h3> 1301 1302 1303 <div class="accordian__panel" id="accordian-panel-downloads-insp-maintenance"> 1304 <div class="accordian__content"> 1305 <ul class="downloads__list"> 1306 <li> 1307 <a href="/Files/System/ProductCollectionDownloads/InspectionMaintenance/Playground Equipment I&M guide_EN.pdf" download="Playground Equipment I&M Guide"> 1308 <span>Playground Equipment I&M Guide</span> 1309 </a> 1310 </li> 1311 <li> 1312 <a href="/Files/System/ProductCollectionDownloads/InspectionMaintenance/Sports and fitness I&M guide_EN.pdf" download="Sports and Fitness I&M Guide"> 1313 <span>Sports and Fitness I&M Guide</span> 1314 </a> 1315 </li> 1316 </ul> 1317 </div> 1318 </div> 1319 1320 </div> 1321 </section> 1322 } 1323 1324 @{ 1325 List<ProductAsset> dwgAssets = new List<ProductAsset>(); 1326 dwgAssets = assets.Where(n => n.Index == AssetTypeEnum.ToFriendlyAssetName(AssetType.Drawings)).ToList(); 1327 } 1328 1329 @if (dwgAssets.Count > 0) 1330 { 1331 @renderAccordianPanel(dwgAssets, "dwgs", "DWGFiles", "DWG Files","",productNumber) 1332 } 1333 1334 1335 <section class="accordian print-hide"> 1336 <div class="wrapper"> 1337 <h3> 1338 <button id="accordian-downloads-general-info" 1339 aria-expanded="true" aria-controls="accordian-panel-downloads-general-info" 1340 type="button" class="accordian__button" 1341 data-action-page="Product" 1342 data-action-type="Text block expand" 1343 data-action-label="GeneralDownloads" 1344 data-action-value="@productNumber"> 1345 @Translate("GeneralInformation", "General Information") 1346 <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> 1347 <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> 1348 </button> 1349 </h3> 1350 1351 1352 <div class="accordian__panel" id="accordian-panel-downloads-general-info"> 1353 1354 <div class="accordian__content"> 1355 1356 <ul class="downloads__list"> 1357 @*@if (thisPage.AreaID == 2) 1358 {*@ 1359 <li> 1360 <a href="Files/System/ProductCollectionDownloads/General Information/hags-general-info_SE.pdf" download="" target="_blank"> 1361 <span>@Translate("GeneralInformation", "General Information") (SE)</span> 1362 </a> 1363 </li> 1364 <li> 1365 <a href="Files/System/ProductCollectionDownloads/General Information/hags-technical-specs_SE.pdf" download="" target="_blank"> 1366 <span>@Translate("TechnicalInformation", "Technical Information") (SE)</span> 1367 </a> 1368 </li> 1369 @*} 1370 else 1371 {*@ 1372 <li> 1373 <a href="Files/System/ProductCollectionDownloads/General Information/hags-general-info_EN.pdf" download="" target="_blank"> 1374 <span>@Translate("GeneralInformation", "General Information") (EN)</span> 1375 </a> 1376 </li> 1377 <li> 1378 <a href="Files/System/ProductCollectionDownloads/General Information/hags-technical-specs_EN.pdf" download="" target="_blank"> 1379 <span>@Translate("TechnicalInformation", "Technical Information") (EN)</span> 1380 </a> 1381 </li> 1382 @*}*@ 1383 </ul> 1384 1385 </div> 1386 </div> 1387 1388 </div> 1389 </section> 1390 1391 1392 1393 1394 1395 1396 1397 1398 1399 1400 1401 <section class="accordian de"> 1402 <div class="wrapper"> 1403 <h3> 1404 <button id="accordian-materials" aria-expanded="true" aria-controls="accordian-materials-panel" type="button" class="accordian__button"> 1405 Tender Text Request Form 1406 <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> 1407 <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> 1408 </button> 1409 </h3> 1410 <div class="accordian__panel" id="accordian-materials-panel"> 1411 <div class="accordian__content tender-request"> 1412 <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='a4157f9c59bad4b59c0d66f8b9308194';e.elements['_sys_to_email'].value='';e.setAttribute('action', '/Default.aspx?ID=20057&PID=139114');return true};return s(this);"> 1413 <input type="hidden" name="FormPID" value="139114"> 1414 <input type="hidden" name="FormID" value="48"> 1415 <input type="hidden" name="cmd" value="save"> 1416 <input type="hidden" name="_sys_to_email" value="info@hags.de" autocomplete="off"> 1417 <input type="hidden" name="FormCH1_h" value="" autocomplete="off"> 1418 <input type="hidden" name="FormCH1_f" value="64fcc853b5c7478097280b67d065e694" autocomplete="off"> 1419 <input type="hidden" name="FormCH1_s" value="c4c181d67b4102728a5096ecf8c1929c" autocomplete="off"> 1420 <input type="hidden" name="FormCH1_i" value="6aa5213c54c120933c90ee6f0b7dd4dc" autocomplete="off"> 1421 <input type="hidden" name="a4157f9c59bad4b59c0d66f8b9308194ts" value="E1WX2koSJVNXmGFR8goSJnCuchPB6aG0" style="display:none!important" autocomplete="off"> 1422 <input type="text" name="a4157f9c59bad4b59c0d66f8b9308194description" value="" style="display:none!important" autocomplete="off"> 1423 <input type="text" name="a4157f9c59bad4b59c0d66f8b9308194email" value="mrssmith@dynamicweb.com" style="display:none!important" autocomplete="off"> 1424 <table class="formtable"> 1425 <tbody> 1426 <tr class="labelRow" style="padding-bottom:12px;display:block;"> 1427 <td class="labelCell"> 1428 <p>Complete form form below to request the the relevant product tender text</p> 1429 </td> 1430 </tr> 1431 <tr class="labelRow"> 1432 <td class="labelCell"> 1433 <label for="ArticleNumber"><h6>Article Number: @productNumber</h6></label> 1434 </td> 1435 </tr> 1436 <tr class="labelRow"> 1437 <td class="labelCell"> 1438 <label for="FirstName">First Name </label> 1439 </td> 1440 </tr> 1441 <tr class="fieldRow"> 1442 <td> 1443 <input type="text" id="FirstName" name="FirstName" required="" /></td> 1444 </tr> 1445 <tr class="descriptionRow"> 1446 <td class="descriptionCell"><small></small></td> 1447 </tr> 1448 <tr class="labelRow"> 1449 <td class="labelCell"> 1450 <label for="LastName">Last Name </label> 1451 </td> 1452 </tr> 1453 <tr class="fieldRow"> 1454 <td><input type="text" id="LastName" name="LastName" required="" /></td> 1455 </tr> 1456 <tr class="descriptionRow"> 1457 <td class="descriptionCell"><small></small></td> 1458 </tr> 1459 <tr class="labelRow"> 1460 <td class="labelCell"> 1461 <label for="Email">Email </label> 1462 </td> 1463 </tr> 1464 <tr class="fieldRow"> 1465 <td><input type="email" id="Email" name="Email" required="" /></td> 1466 </tr> 1467 <tr class="descriptionRow"> 1468 <td class="descriptionCell"><small></small></td> 1469 </tr> 1470 <tr class="labelRow"> 1471 <td class="labelCell"> 1472 <label for="Company">Company </label> 1473 </td> 1474 </tr> 1475 <tr class="fieldRow"> 1476 <td><input type="text" id="Company" name="Company" required="" /></td> 1477 </tr> 1478 <tr class="descriptionRow"> 1479 <td class="descriptionCell"><small></small></td> 1480 </tr> 1481 <tr class="labelRow"> 1482 <td class="labelCell"> 1483 <label for="ArticleNumber">Article Number </label> 1484 </td> 1485 </tr> 1486 <tr class="fieldRow"> 1487 <td style="width:100%;display:block;"><input type="text" id="ArticleNumber" name="ArticleNumber" value="@productNumber" style="width:100%;display:block;"></td> 1488 </tr> 1489 <tr class="descriptionRow"> 1490 <td class="descriptionCell"><small></small></td> 1491 </tr> 1492 <tr class="fieldRow"> 1493 <td><input type="submit" id="SendRequest" name="SendRequest" value="Submit" class="submit" /></td> 1494 </tr> 1495 <tr class="descriptionRow"> 1496 <td class="descriptionCell"><small></small></td> 1497 </tr> 1498 </tbody> 1499 </table> 1500 <input type="hidden" name="SendRequest" value="Submit" /> 1501 </form> 1502 </div> 1503 </div> 1504 </div> 1505 </section> 1506 @*IncludeFile("partials/add-to-collection.cshtml")*@ 1507 </div> 1508 1509 </div> 1510 </div> 1511 </section> 1512 1513 <script type="text/javascript"> 1514 var __ss_noform = __ss_noform || []; 1515 __ss_noform.push(['baseURI', 'https://app-3QNUK2ISME.marketingautomation.services/webforms/receivePostback/MzawMLE0MzQ3BgA/']); 1516 __ss_noform.push(['endpoint', 'f1f4eefa-cc8e-4621-a197-e153223a10a6']); 1517 </script><script type="text/javascript" src="https://koi-3QNUK2ISME.marketingautomation.services/client/noform.js?ver=1.24" ></script> 1518 1519 <div class="center-copy contact"> 1520 1521 @if (!String.IsNullOrEmpty(salesPhoneNumber)) 1522 { 1523 string contactUsLink = DWUtilities.GetPageByNavigationTag("ContactUs", thisPage.AreaID); 1524 <p class="print-hide call-out"><span>@Translate("ContactUs", "Contact Us") <a href="@contactUsLink">@Translate("ContactForm", "Contact Form")</a></span></p> 1525 } 1526 </div> 1527 1528 1529 1530 <form id="product-hidden-fields"> 1531 <input type="hidden" id="productVariantId" value="@GetString("Ecom:Product.VariantID")"> 1532 <input type="hidden" id="productCollectionData" value="@collectionData"> 1533 </form> 1534 1535 1536 <section class="print-hide flow section-bg-light products-variants"> 1537 1538 @if (GetLoop("VariantCombinations").Count() > 0) 1539 { 1540 <div class="wrapper flow"> 1541 <h5>@Translate("ProductOptions", "Product Options") (<span id="resultCount">@GetLoop("VariantCombinations").Count()</span>)</h5> 1542 1543 1544 <form class="form-inline"> 1545 <div id="filter-variants" class="cluster"> 1546 1547 @if (anchoringOptions.Results.Count() > 0) 1548 { 1549 <div class="form-group"> 1550 <label for="anchoring" class="control-label">@Translate("Anchoring", "Anchoring")</label> 1551 <select class="form-control variant-filter" id="filter-anchoring" name="anchoring" 1552 data-action-page="product" data-action-type="Variant filter" 1553 data-action-label="Anchoring" data-action-value="@productNumber"> 1554 1555 @if (anchoringOptions.Results.Count() > 1) 1556 { 1557 <option value="any">@Translate("Any", "Any")</option> 1558 foreach (var anchor in anchoringOptions.Results.OrderBy(n => n.Sort)) 1559 { 1560 <option value="@anchor.Value">@anchor.Name</option> 1561 } 1562 } 1563 else 1564 { 1565 ResultField result = anchoringOptions.Results.FirstOrDefault(); 1566 <option value="any">@Translate("Any", "Any")</option> 1567 <option value="@result.Value">@result.Name</option> 1568 } 1569 1570 </select> 1571 </div> 1572 } 1573 1574 @if (colourOptions.Results.Count() > 0) 1575 { 1576 <div class="form-group"> 1577 <label for="colour" class="control-label">@Translate("Colour", "Colour")</label> 1578 <select class="form-control variant-filter" id="filter-colour" name="colour" 1579 data-action-page="product" data-action-type="Variant filter" 1580 data-action-label="Colour" data-action-value="@productNumber"> 1581 1582 @if (colourOptions.Results.Count() > 1) 1583 { 1584 <option value="any">@Translate("Any", "Any")</option> 1585 foreach (var colour in colourOptions.Results.OrderBy(n => n.Sort)) 1586 { 1587 <option value="@colour.Value">@colour.Name</option> 1588 } 1589 } 1590 else 1591 { 1592 ResultField result = colourOptions.Results.FirstOrDefault(); 1593 <option value="@result.Value">@result.Name</option> 1594 } 1595 </select> 1596 </div> 1597 } 1598 1599 @if (optionOptions.Results.Count() > 0) 1600 { 1601 <div class="form-group"> 1602 <label for="options" class="control-label">@Translate("ProductOptions", "Product Options")</label> 1603 <select class="form-control variant-filter" id="filter-options" name="options" 1604 data-action-page="product" data-action-type="Variant filter" 1605 data-action-label="Options" data-action-value="@productNumber"> 1606 1607 @if (optionOptions.Results.Count() > 1) 1608 { 1609 <option value="any">@Translate("Any", "Any")</option> 1610 foreach (var option in optionOptions.Results.OrderBy(n => n.Sort)) 1611 { 1612 <option value="@option.Value">@option.Name</option> 1613 } 1614 } 1615 else 1616 { 1617 ResultField result = optionOptions.Results.FirstOrDefault(); 1618 <option value="@result.Value">@result.Name</option> 1619 } 1620 </select> 1621 </div> 1622 } 1623 1624 </div> 1625 </form> 1626 1627 1628 </div> 1629 1630 <div class="wrapper"> 1631 <div class="grid" id="variants-list"> 1632 1633 @foreach (LoopItem variantCombinations in GetLoop("VariantCombinations")) 1634 { 1635 var colourOption = string.Empty; 1636 var optionOption = string.Empty; 1637 var anchorOption = string.Empty; 1638 var materialOption = string.Empty; 1639 var colourId = string.Empty; 1640 var optionId = string.Empty; 1641 var anchorId = string.Empty; 1642 var materialId = string.Empty; 1643 var selectedVariant = string.Empty; 1644 List<ProductAsset> productImages = AssetManager_Repository.GetAssets(variantCombinations.GetString("Ecom:VariantCombination.Product.Number"), AssetType.Images, false); 1645 ProductAsset image = productImages.Where(n => n.Index == AssetTypeEnum.ToFriendlyAssetName(AssetType.Images) && n.FileName.StartsWith("medium_")).FirstOrDefault(); 1646 1647 foreach (var group in GetLoop("VariantGroups").Where(n => n.GetString("Ecom:VariantGroup.ID") != "D")) 1648 { 1649 foreach (var availableOption in group.GetLoop("VariantAvailableOptions")) 1650 { 1651 if (group.GetString("Ecom:VariantGroup.ID") == "S55") 1652 { 1653 1654 if (variantCombinations.GetString("Ecom:VariantCombination.VariantID").Contains(availableOption.GetString("Ecom:VariantOption.ID")) && availableOption.GetString("Ecom:VariantOption.Name") != "Not applicable") 1655 { 1656 colourOption = availableOption.GetString("Ecom:VariantOption.Name"); 1657 colourId = availableOption.GetString("Ecom:VariantOption.ID"); 1658 } 1659 1660 } 1661 if (group.GetString("Ecom:VariantGroup.ID") == "ATP1") 1662 { 1663 if (variantCombinations.GetString("Ecom:VariantCombination.VariantID").Contains(availableOption.GetString("Ecom:VariantOption.ID")) && availableOption.GetString("Ecom:VariantOption.Name") != "Not applicable") 1664 { 1665 materialOption = availableOption.GetString("Ecom:VariantOption.Name"); 1666 materialId = availableOption.GetString("Ecom:VariantOption.ID"); 1667 } 1668 } 1669 if (group.GetString("Ecom:VariantGroup.ID") == "ATP3") 1670 { 1671 if (variantCombinations.GetString("Ecom:VariantCombination.VariantID").Contains(availableOption.GetString("Ecom:VariantOption.ID")) && availableOption.GetString("Ecom:VariantOption.Name") != "Not applicable") 1672 { 1673 anchorOption = availableOption.GetString("Ecom:VariantOption.Name"); 1674 anchorId = availableOption.GetString("Ecom:VariantOption.ID"); 1675 } 1676 } 1677 if (group.GetString("Ecom:VariantGroup.ID") == "ATP4") 1678 { 1679 if (variantCombinations.GetString("Ecom:VariantCombination.VariantID").Contains(availableOption.GetString("Ecom:VariantOption.ID")) && availableOption.GetString("Ecom:VariantOption.Name") != "Not applicable") 1680 { 1681 optionOption = availableOption.GetString("Ecom:VariantOption.Name"); 1682 optionId = availableOption.GetString("Ecom:VariantOption.ID"); 1683 } 1684 } 1685 if (variantCombinations.GetBoolean("Ecom:VariantCombination.Selected")) 1686 { 1687 selectedVariant = "selected-variant"; 1688 } 1689 } 1690 1691 } 1692 1693 <div class="product-card @selectedVariant" data-filter-colour="@colourId" data-filter-anchoring="@anchorId" data-filter-options="@optionId"> 1694 1695 <div class="product-card__img-silo"> 1696 @if (image != null && !String.IsNullOrEmpty(image.uri)) 1697 { 1698 <a href="@variantCombinations.GetString("Ecom:VariantCombination.Link.Clean")"><img src="@image.uri" class="product-card__img" /></a> 1699 } 1700 else 1701 { 1702 <img src="/Files/Templates/Designs/HagsCore/res/img/image-not-found.png" class="product-card__img" /> 1703 } 1704 </div> 1705 1706 1707 <div class="product-card__copy"> 1708 1709 @if (thisPage.AreaID == 7) /*UK*/ 1710 { 1711 string ukId = ProductFieldValues.GetUkProductNumber(variantCombinations.GetString("Ecom:VariantCombination.Product.Number"), thisPage.Area.EcomLanguageId); 1712 <h5 class="product-card__heading"><a href="@variantCombinations.GetString("Ecom:VariantCombination.Link.Clean")">@ukId.ToString()</a></h5> 1713 } 1714 else 1715 { 1716 <h5 class="product-card__heading"><a href="@variantCombinations.GetString("Ecom:VariantCombination.Link.Clean")">@variantCombinations.GetString("Ecom:VariantCombination.Product.Number")</a></h5> 1717 } 1718 1719 <p>@optionOption @colourOption - @anchorOption</p> 1720 1721 <!--<a class="" href="@variantCombinations.GetString("Ecom:VariantCombination.Link.Clean")" role="button">@Translate("ProductDetails", "Product Details")</a>--> 1722 </div> 1723 </div> 1724 1725 } 1726 </div> 1727 1728 <div class="m-message" style="display:none;padding-bottom:20px;padding-left:6px;"> 1729 <p style="font-size: 1.2em;color:red;"><b>@Translate("VariantFilterMessage", "There were no options available for selection.")</b></p> 1730 </div> 1731 </div> 1732 1733 } 1734 </section> 1735 1736 @* Play Functions*@ 1737 @if (relatedProducts.Any()) 1738 { 1739 int count = relatedProducts.Count(); 1740 @* set up this so we can use it's title case method *@ 1741 TextInfo thisTextInfo = new CultureInfo(currentCulture,false).TextInfo; 1742 <section class="related-products"> 1743 <div class="wrapper flow"> 1744 1745 <h5 class="m-panel-title">@Translate("PlayFunctions", "Play Functions")</h5> 1746 1747 1748 <div class="products-listing__grid"> 1749 @foreach (Product relatedProduct in relatedProducts) 1750 { 1751 List<ProductAsset> productImages = AssetManager_Repository.GetAssets(relatedProduct.Number, AssetType.Images, false); 1752 ProductAsset image = productImages.Where(n => n.Index == AssetTypeEnum.ToFriendlyAssetName(AssetType.Images) && n.FileName.StartsWith("medium_")).FirstOrDefault(); 1753 1754 <div class="product-card"> 1755 1756 <div class="product-card_img"> 1757 @if (image != null && !String.IsNullOrEmpty(image.uri)) 1758 { 1759 <a href=""><img src="@image.uri" class="img-responsive m-product-thumb" /></a> 1760 } 1761 else 1762 { 1763 <a href=""><img src="/Files/Templates/Designs/HagsCore/res/img/image-not-found.png" class="img-responsive m-product-thumb" /></a> 1764 } 1765 </div> 1766 <div class="product-card__copy"> 1767 <h5 class="m-theme-after-yellow m-theme-border-yellow product-card__heading">@thisTextInfo.ToTitleCase(relatedProduct.Name.ToLower())</h5> 1768 1769 @if (!string.IsNullOrWhiteSpace(relatedProduct.LongDescription)) 1770 { 1771 <div class="show-read-more" data-charlength="60" data-txtreadmore="@Translate("ReadMore","Read More")" data-txtreadless="@Translate("ReadLess","Read Less")">@relatedProduct.LongDescription</div> 1772 } 1773 </div> 1774 </div> 1775 } 1776 1777 </div> 1778 </div> 1779 </section> 1780 } 1781 1782 1783 1784 1785 1786 @inherits Dynamicweb.Rendering.RazorTemplateBase<Dynamicweb.Rendering.RazorTemplateModel<Dynamicweb.Rendering.Template>> 1787 @using System.Collections.Generic 1788 @using HagsWeb.Library.BusinessObjects.UsersLists 1789 1790 @{ 1791 Layout = null; 1792 } 1793 <dialog id="CreateProductPdf" class="modal modal--full"> 1794 1795 <div class="modal__body"> 1796 1797 <div class="modal__header"> 1798 1799 <div class="modal__close"> 1800 <button type="button" class="action-btn js-modal-close-target" data-target-id="CreateProductPdf"> 1801 <span class="visually-hidden">Close</span> 1802 <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> 1803 </button> 1804 </div> 1805 1806 1807 <h4 class="modal-title" id="CreateCatalogModalLabel"> 1808 @Translate("YourProductSheet", "Your Product Sheet") 1809 </h4> 1810 1811 </div> 1812 1813 <div class="modal__main"> 1814 1815 <div id="div_CreateCatalog" class="modal__product-pdf"> 1816 1817 <div id="pdfwaiting" style="display:block;text-align:center"> 1818 <span id="CreateProductPdfLabel" style="display: inline-block;margin: 10px 10px 0 0;padding: 5px 10px"></span> 1819 <img src="Files/Templates/Designs/HagsCore/res/img/loader/ajax-loader.gif" style="margin:auto;display:block;" /> 1820 </div> 1821 1822 <div id="productPdfViewerloader" class="modal__embed-silo"> 1823 </div> 1824 1825 <div id="CreatePdfMessage"></div> 1826 </div> 1827 1828 1829 </div> 1830 1831 <div class="modal__footer"> 1832 1833 <div class="m-search-advanced-buttons cluster cluster--dialog"> 1834 <a href="" class="btn btn--outline" id="pdfPrintSheet" target="_blank" type="button">@Translate("Print", "Print")</a> 1835 <a href="" class="btn btn--outline" id="pdfDownloadSheet" download type="button">@Translate("Download", "Download")</a> 1836 <button class="btn btn--outline js-modal-close-target" data-target-id="CreateProductPdf" type="button">@Translate("Close", "Close")</button> 1837 </div> 1838 1839 </div> 1840 1841 </div> 1842 1843 </dialog> 1844 @*ProductPdfHelper(productCollectionItems, GetString("Ecom:Product.LanguageID"))*@ 1845 1846
Warranties
Find out what you are covered for.
Maintenance guide
How to look after your products.
Color & Anchoring Options
Explore your options.