Handlekurv
Henter ordrelinjer...
Tomt billede
Varenummer: Antall: 1 Pris: 1.050.00 DKK NOK
NOK
Pris ekskl. moms 1.239,20 DKK NOK Pris i alt NOK
Exception in template (Designs\IBH\eCom/Product/PDP.cshtml): System.Exception: Error Running ExecuteReader: Execution Timeout Expired.  The timeout period elapsed prior to completion of the operation or the server is not responding., Sql: "SELECT
	                    -- Object columns
	                    O.DefinitionKey
	                    ,O.LastModified AS OjectLastModified
	                    ,O.ObjectId
	                    ,O.XmlObjectId
	                    ,O.ShopId
	                    ,O.LanguageId

	                    -- Value columns
	                    ,V.LastModified AS ValueLastModified
	                    ,V.XmlReferenceObjectId
	                    ,V.XmlReferenceObjectKey
	                    ,V.ValueId
	                    ,V.[Text]
                        ,V.FieldKey
                        ,V.SortOrder

                    FROM [LWI_Spec_Objects] AS O
                    JOIN [LWI_Spec_Values] AS V ON
	                    V.ShopId = O.ShopId
	                    AND V.LanguageId = O.LanguageId
	                    AND V.XmlObjectKey = O.DefinitionKey
	                    AND V.XmlObjectId = O.XmlObjectId
                    WHERE
                        O.DefinitionKey IN ('Product')
                        AND O.XmlObjectId IN ('239690','3720')
                        AND O.ShopId IN ('SHOP3')
                        AND O.LanguageId IN ('LANG5')
                    ORDER BY O.DefinitionKey, O.LanguageId, O.ShopId, O.XmlObjectId
                    ", Params: '' ---> System.Data.SqlClient.SqlException: Execution Timeout Expired.  The timeout period elapsed prior to completion of the operation or the server is not responding. ---> System.ComponentModel.Win32Exception: The wait operation timed out
   --- End of inner exception stack trace ---
   at System.Data.SqlClient.SqlConnection.OnError(SqlException exception, Boolean breakConnection, Action`1 wrapCloseInAction)
   at System.Data.SqlClient.TdsParser.ThrowExceptionAndWarning(TdsParserStateObject stateObj, Boolean callerHasConnectionLock, Boolean asyncClose)
   at System.Data.SqlClient.TdsParser.TryRun(RunBehavior runBehavior, SqlCommand cmdHandler, SqlDataReader dataStream, BulkCopySimpleResultSet bulkCopyHandler, TdsParserStateObject stateObj, Boolean& dataReady)
   at System.Data.SqlClient.SqlDataReader.TryConsumeMetaData()
   at System.Data.SqlClient.SqlDataReader.get_MetaData()
   at System.Data.SqlClient.SqlCommand.FinishExecuteReader(SqlDataReader ds, RunBehavior runBehavior, String resetOptionsString, Boolean isInternal, Boolean forDescribeParameterEncryption, Boolean shouldCacheForAlwaysEncrypted)
   at System.Data.SqlClient.SqlCommand.RunExecuteReaderTds(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, Boolean async, Int32 timeout, Task& task, Boolean asyncWrite, Boolean inRetry, SqlDataReader ds, Boolean describeParameterEncryptionRequest)
   at System.Data.SqlClient.SqlCommand.RunExecuteReader(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, String method, TaskCompletionSource`1 completion, Int32 timeout, Task& task, Boolean& usedCache, Boolean asyncWrite, Boolean inRetry)
   at System.Data.SqlClient.SqlCommand.RunExecuteReader(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, String method)
   at System.Data.SqlClient.SqlCommand.ExecuteReader(CommandBehavior behavior, String method)
   at Glimpse.Ado.AlternateType.GlimpseDbCommand.ExecuteDbDataReader(CommandBehavior behavior)
   at NLWI.Platforms.Dynamicweb9.Database.ADatabaseRepository.ExecuteReader(String query, Object[] ps)
   --- End of inner exception stack trace ---
   at NLWI.Platforms.Dynamicweb9.Database.ADatabaseRepository.ExecuteReader(String query, Object[] ps)
   at NLWI.Platforms.Dynamicweb9.Specs.Repositories.SpecificationRepository.GetSpecificationObjects(HashSet`1 keys) in D:\VSO Agents\00TFS01-norriq-ip\_work\3\s\src\NLWI.Platforms.Dynamicweb9.Specs\Repositories\SpecificationRepository.cs:line 265
   at NLWI.Platforms.Dynamicweb9.Specs.Services.CachedSpecificationService.b__12_1(HashSet`1 k) in D:\VSO Agents\00TFS01-norriq-ip\_work\3\s\src\NLWI.Platforms.Dynamicweb9.Specs\Services\CachedSpecificationService.cs:line 91
   at NLWI.Core.Platform.Caching.DictionaryCaching.GetOrInsert[TKey,TVal](HashSet`1 keys, Func`2 buildCacheKey, Func`2 lookupMethod, CacheOptions cacheOptions) in D:\VSO Agents\00TFS01-norriq-ip\_work\3\s\src\NLWI.Core\Platform\Caching\DictionaryCaching.cs:line 102
   at NLWI.Platforms.Dynamicweb9.Specs.Services.CachedSpecificationService.GetSpecificationObjects(HashSet`1 specificationObjectIdentifiers) in D:\VSO Agents\00TFS01-norriq-ip\_work\3\s\src\NLWI.Platforms.Dynamicweb9.Specs\Services\CachedSpecificationService.cs:line 88
   at NLWI.Platforms.Dynamicweb9.Specs.Services.CachedProductSpecificationService.GetProductSpecifications(Dictionary`2 autoIdMappings) in D:\VSO Agents\00TFS01-norriq-ip\_work\3\s\src\NLWI.Platforms.Dynamicweb9.Specs\Services\CachedProductSpecificationService.cs:line 64
   at NLWI.Platforms.Dynamicweb9.Specs.Services.CachedProductSpecificationService.GetProductSpecifications(HashSet`1 productAutoIds) in D:\VSO Agents\00TFS01-norriq-ip\_work\3\s\src\NLWI.Platforms.Dynamicweb9.Specs\Services\CachedProductSpecificationService.cs:line 59
   at CompiledRazorTemplates.Dynamic.bdfcdafcf.Execute()
   at RazorEngine.Templating.TemplateBase.RazorEngine.Templating.ITemplate.Run(ExecuteContext context)
   at RazorEngine.Templating.TemplateService.Run(ITemplate template, DynamicViewBag viewBag)
   at RazorEngine.Templating.TemplateService.Parse(String razorTemplate, Object model, DynamicViewBag viewBag, String cacheName)
   at RazorEngine.Razor.Parse[T](String razorTemplate, T model, String cacheName)
   at Dynamicweb.Rendering.Template.RenderRazorTemplate()
@using System.Globalization @using NORRIQ.Common8.Razor; @using System.Linq @using Dynamicweb.Core @using Dynamicweb.Ecommerce.Products @using NORRIQ.Common8.Factory @using NLWI.Platforms.Dynamicweb9.Specs; @using StandardWebshop.CustomCode.Razor; @using StandardWebshop.CustomCode.CustomLogin.Branding.Service; @using StandardWebshop.CustomCode.Ecom.Stock @using NORRIQ.Common8.Caching @inherits Dynamicweb.Rendering.RazorTemplateBase<Dynamicweb.Rendering.RazorTemplateModel<Dynamicweb.Rendering.Template>> @{ // The following line will prepare specs for both WhatAboutTheeseProducts and current product combining 5 sql to 1 ObjectFactory.GetInstance<NLWI.Platforms.Dynamicweb9.Specs.Services.IProductSpecificationService>().GetProductSpecifications(new HashSet<long>( GetLoop("eCom:Related.WhatAboutTheseProducts").Take(4).Select(a => a.GetLong("NIQ:ProductAutoId")).Concat(new[] { GetLong("NIQ:ProductAutoId") }) )); var specs = this.GetProductSpecifications(); var images = specs.GetAllByKey("Billeder"); var imageAlt = specs.GetByKey("ProductName").Value + ", " + specs.GetByKey("Brand").Value + ", " + specs.GetByKey("Designer").Value; var priceForContent = GetString("NIQ:PriceForGoogle"); var currency = GetString("Ecom:Product.Price.Currency.Code"); // Soldout / Limited supply // The point here is to provide IBH with a way of quickly managing the state of a product // without doing a full import from XPI. The stockNumber, soldOut and limitedSupply variables are used as follows: // 1) If stockNumber is less and 1, or the soldOut flag is true, the product cannot be bought. // 2) If the limitedSupply flag is set, the user will be notified of a limited supply, but the product can still be bought. // These 3 variables are all reset when doing a full import from XPI (Done via NLWI sync activities). var deliveryTimeValue = specs.GetByKey("LeveringsTid").GetReferenceSpecification().GetByKey("Id").Value; var isOrderingProduct = deliveryTimeValue.IndexOf("bestil", StringComparison.CurrentCultureIgnoreCase) > -1; var stockState = this.GetStockState(); var soldOut = (this.IsSoldOut() || stockState == StockState.OutOfStock || stockState == StockState.NoStockLocation); //var soldOut = (string.Equals(GetString("Ecom:Product:Field.Soldout.Value"), "true", StringComparison.OrdinalIgnoreCase) || stockNumber < 1) && !isOrderingProduct; var limitedSupply = this.IsLimitedSupply() || stockState == StockState.FewInStock; // CAS-25416-T2M8Z7: Projekt: Lagerstyring IBH online // NAV has the ability to override the stocklevel from XPI. As such, if the custom field "" on a product contains // data, that data should be displayed, and stock messages from XPI should be hidden. var stockFromNav = string.Equals(GetString("Ecom:Product:Field.StockPhase"), "L", StringComparison.OrdinalIgnoreCase); var stockPhaseDescription = GetString("Ecom:Product:Field.StockPhaseDesc"); var doNotIncludeSpecsList = new List<string> { "BrandLink", "BrandText", "BrandBanner" }; var giftlistLink = Navigation.GetUrlByNavigationTag("edit-giftlist"); var productService = ObjectFactory.GetInstance<ProductService>(); } <div class="container"> @DwCaching.CacheByPage("breadcrumb.xslt" + GetLong("NIQ:ProductAutoId"), () => RenderNavigation(new { Template = "Breadcrumb.xslt", Expandmode = "all", StartLevel = 1, EndLevel = 5 })) <section class="pdp" itemscope="" itemtype="https://schema.org/Product"> <div class="pdp-images"> <div class="pdp-images-inner"> @if (!isOrderingProduct || specs.GetByKey("LeveringsTid").GetReferenceSpecification().GetByKey("Id").Value == "Udsolgt" || !string.IsNullOrWhiteSpace(specs.GetByKey("BobbelTekst").Value)) { <span class="pdp-bobbeltekst"> @if (!isOrderingProduct) { if (soldOut) { <span class="pdp-label">@Translate("Soldtout", "Udsolgt")</span> } else if (limitedSupply) { <span class="pdp-label">@Translate("LImitedSupply", "Begrænset antal")</span> } else if (!string.IsNullOrEmpty(stockPhaseDescription)) { @* Do not show anything as the XPI stock status should not be displayed when the stock is controlled by NAV. *@ } } @if (specs.GetByKey("LeveringsTid").GetReferenceSpecification().GetByKey("Id").Value == "Udsolgt") { <span class="pdp-label">@specs.GetByKey("Leveringstid").Value</span> } else if (string.Equals(specs.GetByKey("BobbelTekst").Value, "#")) { @* Do not show anything because "#" means that nothing should be showed (This is an XPI fix because it is not possible to delete values from XPI via the Excel import) *@ } else if (!string.IsNullOrWhiteSpace(specs.GetByKey("BobbelTekst").Value)) { <span class="pdp-label">@specs.GetByKey("BobbelTekst").Value</span> } </span> } @if (images.Any()) { var firstImage = images.First().Value; if (images.Count() > 1) { <div class="pdp-images-thumbs" id="pdp-thumbs"> <div class="pdp-thumb"> <img src="@Pageview.CdnWrap(string.Format("/Admin/Public/GetImage.ashx?Image=/Files/Images/XPI/{0}&amp;Width=90&amp;Height=90&amp;Crop=5&amp;Compression=90", firstImage))" class="img-fluid" alt="@imageAlt" /> </div> @foreach (var image in images.Skip(1)) { <div class="pdp-thumb"> <img src="@Pageview.CdnWrap(string.Format("/Admin/Public/GetImage.ashx?Image=/Files/Images/XPI/{0}&amp;Width=90&amp;Height=90&amp;Crop=5&amp;Compression=90",image.Value))" class="img-fluid" alt="@imageAlt" /> </div> } </div> <div class="pdp-images-view" id="pdp-images"> <a href="@Pageview.CdnWrap(string.Format("/Admin/Public/GetImage.ashx?Image=/Files/Images/XPI/{0}&amp;Width=1200&amp;Crompression=90", firstImage))" class="pdp-image" data-fancybox="images" data-caption="@imageAlt" data-options='{"infobar": false, "animationEffect": false, "buttons":["zoom","close"]}'> <img src="@Pageview.CdnWrap(string.Format("/Admin/Public/GetImage.ashx?Image=/Files/Images/XPI/{0}&amp;Width=500&amp;Height=500&amp;Crop=5&amp;Compression=90", firstImage))" class="img-fluid" itemprop="image" alt="@imageAlt" /> </a> @foreach (var image in images.Skip(1)) { <a href="@Pageview.CdnWrap(string.Format("/Admin/Public/GetImage.ashx?Image=/Files/Images/XPI/{0}&amp;Width=1200&amp;Crompression=90", image.Value))" class="pdp-image" data-fancybox="images" data-caption="@imageAlt" data-options='{"infobar": false, "animationEffect": false, "buttons":["zoom","close"]}'> <img src="@Pageview.CdnWrap(string.Format("/Admin/Public/GetImage.ashx?Image=/Files/Images/XPI/{0}&amp;Width=500&amp;Height=500&amp;Crop=5&amp;Compression=90", image.Value))" class="img-fluid" alt="@imageAlt" /> </a> } </div> } else { <a href="@Pageview.CdnWrap(string.Format("/Admin/Public/GetImage.ashx?Image=/Files/Images/XPI/{0}&amp;Width=1200&amp;Crompression=90",images.First().Value))" class="pdp-image-lg" data-fancybox data-caption="@imageAlt" data-options='{"infobar": false, "animationEffect": false, "buttons":["zoom","close"]}'> <img src="@Pageview.CdnWrap(string.Format("/Admin/Public/GetImage.ashx?Image=/Files/Images/XPI/{0}&amp;Width=500&amp;Height=500&amp;Crop=5&amp;Compression=90", images.First().Value))" class="img-fluid" itemprop="image" alt="@imageAlt" /> </a> } } </div> </div> <div class="pdp-details"> <div class="pdp-details-main"> <p class="pdp-brand" itemprop="brand"> @GetString("Ecom:Product:Field.Brand") </p> <h1 class="pdp-name" itemprop="name"> @GetString("Ecom:Product.Name") </h1> <div class="pdp-prices" itemprop="offers" itemscope itemtype="https://schema.org/Offer"> @{ var currencyCode = Pageview.Area.EcomCurrencyId; var price = GetDouble("Ecom:Product.Discount.Price." + "PriceWithVAT" + ".Value"); var priceWithVat = GetDouble("Ecom:Product.Price.PriceWithVAT.Value"); var beforePrice = GetString("Ecom:Product:Field.Beforeprice.Value"); var isDiscount = priceWithVat != price; } @if (isDiscount || beforePrice.IsNotNullOrEmpty()) { <span class="pdp-org-price"> <span>@Translate("Before price", "Før ")</span> @if (isDiscount) { <span> @priceWithVat.ToString("N2") </span> } else { <span> @beforePrice </span> } <span>@currencyCode</span> </span> <span class="pdp-list-price"> <span>@Translate("After price", "Nu")</span> <span itemprop="price" content="@priceForContent">@price.ToString("N2")</span> <span itemprop="priceCurrency">@currencyCode</span> </span> } else { <span class="pdp-list-price"> <span itemprop="price" content="@priceForContent">@price.ToString("N2")</span> <span itemprop="priceCurrency" content="@currencyCode">@currencyCode</span> </span> } </div> <div class="pdp-buying"> @{ var canBuy = (!soldOut && deliveryTimeValue != "FremtidigKoeb") || isOrderingProduct; } @if (stockState != StockState.NotTracked) { if (limitedSupply) { <span class="pdp-stock-status"> @Translate("Få på lager") </span> } else if (stockState == StockState.InStock) { <span class="pdp-stock-status"> @Translate("På lager") </span> } } <form class="form" data-action="addToCart" id="[email protected]("Ecom:Product:Page.ID")" name="[email protected]("Ecom:Product:Page.ID")" method="post" action="@GetGlobalValue("Global:Pageview.Url.Raw")"> @GetString("Ecom:Product.Form.Clean") <input type="hidden" name="custom_ProductNo" value="@GetString("Ecom:Product.Number")" /> <input type="hidden" name="custom_ProductName" value="@GetString("Ecom:Product.Name")" /> <input type="hidden" name="custom_ProductPrice" value="@GetDouble("Ecom:Product.Price.PriceWithVAT.Value").ToString("F2", new CultureInfo("en-US"))" /> <input type="hidden" name="custom_ProductCurrency" value="@currency" /> @if (!canBuy) { if (soldOut) { <p class="pdp-stock-status mb-0">@Translate("TemporaryUnavailable", "Varen er midlertidigt udsolgt.")</p> } else if (!string.IsNullOrEmpty(stockPhaseDescription)) { <p class="pdp-stock-status mb-0">@stockPhaseDescription</p> } else { <p class="pdp-stock-status mb-0">@specs.GetByKey("Leveringstid").Value</p> } } <div class="pdp-select"> @if (canBuy) { <div class="pdp-qty"> <label for="quantity" class="sr-only">@Translate("Number", "Antal")</label> <div class="pdp-qty-control"> <input type="number" name="quantity" id="quantity" min="1" step="1" value="1" class="form-control" autocomplete="off" /> <button type="button" class="pdp-qty-decrease"> - </button> <button type="button" class="pdp-qty-increase"> + </button> </div> </div> } else { <input type="hidden" name="quantity" id="quantity" value="1" /> } @inherits Dynamicweb.Rendering.RazorTemplateBase<Dynamicweb.Rendering.RazorTemplateModel<Dynamicweb.Rendering.Template>> @using StandardWebshop.CustomCode.ViewModels.Variants; @{ var variants = GetLoop("VariantGroups").GetVariants(); // In IBH, the Product Number can be used as a unique product identifier. var currentProductNumber = GetString("Ecom:Product.Number"); // All variant products and their associated variant groups/options. var variantProducts = GetLoop("VariantCombinations").GetVariantProducts(variants, currentProductNumber); var productsDictionary = VariantViewModelBuilder.GetProductsInDimensionOrder(variants, variantProducts); var selectedVariant = VariantViewModelBuilder.GetSelectedOrEmpty(variantProducts); } @{ @* These lines are required because lazy load's its data. GetString("Ecom:VariantGroup.Label") GetString("Ecom:VariantGroup.Name") GetLoop("VariantAvailableOptions") GetString("Ecom:VariantOption.ID") GetString("Ecom:VariantOption.Name") *@ } @* // This will display all the different variants, and highlight the one currently being viewed. <h1>Test</h1> <ul> @foreach (var v1 in productsDictionary) { <li>@v1.Key.GroupName || @v1.Key.OptionId</li> <li> <ul> @foreach (var v2 in v1.Value) { <li @(v2.Value.IsSelected ? "style='font-weight:bold'" : "")>@v2.Key.GroupName || @v2.Key.OptionId ## <a href="@v2.Value.LinkToGroup">@v2.Value.Name</a></li> } </ul> </li> } </ul>*@ @if (variants.Count == 0) { @* No variants *@ } else if (variants.Count == 1) { var variantSelected = System.Web.HttpContext.Current.Request["Selected"] != null; <div class="pdp-variants pdp-variants-single"> <div class="form-group"> <label for="variant1Selector" class="sr-only">@Translate("Choose", "Vælg") <span class="text-lowercase">@selectedVariant.Variant1.GroupLabel</span></label> <select class="form-control" id="variant1Selector" data-enable-target="#buy-button"> <option value="0" @(!variantSelected ? "selected='selected'" : "")> @Translate("Choose", "Vælg") @selectedVariant.Variant1.GroupLabel </option> @foreach (var v1 in productsDictionary.Where(a => !string.IsNullOrEmpty(a.Key.OptionId))) { var isSelected = selectedVariant.Variant1.Equals(v1.Key); var product = v1.Value.First(); var linkToGroup = product.Value.LinkToGroup+ "&Selected=ready"; <option value="@(isSelected? "0" : v1.Key.OptionId)" @(isSelected && variantSelected ? "selected='selected'" : "") data-linktogroup="@linkToGroup">@v1.Key.OptionName</option> } </select> </div> </div> } else { <div class="pdp-variants pdp-variants-double"> <div class="form-group"> <label for="variant1Selector">@Translate("Choose", "Vælg") <span class="text-lowercase">@selectedVariant.Variant1.GroupLabel</span></label> <select class="form-control" id="variant1Selector"> @foreach (var v1 in productsDictionary.Where(a => !string.IsNullOrEmpty(a.Key.OptionId))) { var isSelected = selectedVariant.Variant1.Equals(v1.Key); <option value="@v1.Key.OptionId" @(isSelected ? "selected='selected'" : "")>@v1.Key.OptionName</option> } </select> </div> <div class="form-group"> <label for="variant2Selector">@Translate("Choose", "Vælg") <span class="text-lowercase">@selectedVariant.Variant2.GroupLabel</span></label> <select class="form-control" id="variant2Selector"> @foreach (var v1 in productsDictionary.Where(pde => pde.Key.Equals(selectedVariant.Variant1))) { foreach (var v2 in v1.Value.Where(a => !string.IsNullOrEmpty(a.Key.OptionId))) { var isSelected = selectedVariant.Variant2.Equals(v2.Key); <option value="@v2.Key.OptionId" @(isSelected ? "selected='selected'" : "") data-linktogroup="@v2.Value.LinkToGroup">@v2.Key.OptionName</option> } } </select> </div> </div> } <script type="text/x-jsrender" id="emptyVariant2OptionTemplate"> <option value="0"> @Translate("Choose", "Vælg") @selectedVariant.Variant1.GroupLabel </option> </script> <script type="text/x-jsrender" id="variant2OptionTemplate"> <option value="0"> @Translate("Choose", "Vælg") @selectedVariant.Variant2.GroupLabel </option> {{for Products}} <option value="{{:OptionId}}" data-linktogroup="{{:LinkToGroup}}">{{:OptionName}}</option> {{/for}} </script> <script append="true"> var variantData = [ @for (int i = 0; i < productsDictionary.Count; i++) { var v1 = productsDictionary.ElementAt(i); <text> { "GroupLabel": "@v1.Key.GroupLabel", "GroupName": "@v1.Key.GroupName", "OptionId": "@v1.Key.OptionId", "OptionName": "@v1.Key.OptionName", "Products": [ @for (int j = 0; j < v1.Value.Count; j++) { var v2 = v1.Value.ElementAt(j); <text> { "GroupLabel": "@v2.Key.GroupLabel", "GroupName": "@v2.Key.GroupName", "OptionId": "@v2.Key.OptionId", "OptionName": "@v2.Key.OptionName", "LinkToGroup": "@v2.Value.LinkToGroup" },@(j + 1 == v1.Value.Count ? "" : ",") </text> } ] },@(i + 1 == productsDictionary.Count ? "" : ",") </text> } ]; var variantMode = '@variants.Count'; var variantSelector = new AppStart.VariantSelector({ $emptyVariant2OptionTemplate: $('#emptyVariant2OptionTemplate'), $variant2OptionTemplate: $('#variant2OptionTemplate'), $v1Selector: $('#variant1Selector'), $v2Selector: $('#variant2Selector'), // 0 == no variants, 1 == single variant, 2 == 2 variants. variantMode: variantMode, variantData: variantData }); variantSelector.init(); @*require(['jquery', 'standardwebshop/areas/ecom/product/variantselection'], function($, variantSelection) { // 0 == no variants, 1 == single variant, 2 == 2 variants. var variantMode = @variants.Count; if (variantMode == 0) return; variantSelection.init({ $emptyVariant2OptionTemplate: $('#emptyVariant2OptionTemplate'), $variant2OptionTemplate: $('#variant2OptionTemplate'), $v1Selector: $('#variant1Selector'), $v2Selector: $('#variant2Selector'), // 0 == no variants, 1 == single variant, 2 == 2 variants. variantMode: variantMode, variantData: variantData }); });*@ </script> </div> @if (canBuy) { var variantSelected = !GetLoop("VariantGroups").Any() || System.Web.HttpContext.Current.Request["Selected"] != null; <div class="pdp-button"> <button class="btn btn-primary btn-buying" id="buy-button" role="button" type="submit" @(!variantSelected ? "disabled=disabled" : @variantSelected.ToString())> <svg class="icon icon-xs"> <use xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="/Files/dist/icons/icons.svg#shopping"></use> </svg> <span class="loader loader-light loader-xs"></span> <span>@Translate("Add_to_cart", "Tilføj til kurv")</span> </button> <button class="btn btn-outline-dark" role="button" type="button" data-action="addToGiftList"> @Translate("Add to giftlist", "Tilføj til gaveliste") </button> </div> <p id="giftListSuccess" class="pdp-giftlist-added" style="display: none"> @Translate("Added to giftlist info", "Varen er tilføjet til din gaveliste") <a href="@giftlistLink"> @Translate("Show giftlist button", "Vis gaveliste") </a> </p> } else { <div class="pdp-button"> <a data-fancybox data-src="#nostockModal" href="javascript:;" data-options='{"infobar": false, "smallBtn": false, "toolbar": false, "buttons":["close"]' class="btn btn-outline-dark btn-buying"> @Translate("nostock_btn", "Giv mig besked") </a> </div> } </form> @if (!canBuy) { var usermail = Pageview.User != null ? Pageview.User.Email : string.Empty; <div class="pdp-backinstock" id="nostockModal" style="display:none;"> <h2 class="modal-title">@Translate("modal_nostock_heading", "Giv mig besked")</h2> <p>@Translate("modal_nostock_txt", "Vi sender dig en e-mail, når denne vare igen er på lager.")</p> <form name="@GetValue("Ecom:Product.ID")" method="post" class="form validation pdp-backinstock-form" role="form" action=""> <input type="hidden" name="ProductID" value="@GetValue("Ecom:Product.ID")" /> <input type="hidden" name="VariantID" value="@GetValue("Ecom:Product.VariantID")" /> <input type="hidden" name="LanguageID" value="@GetValue("Ecom:Product.LanguageID")" /> <input type="hidden" name="ProductName" value="@specs.GetByKey("ProductName").Value" /> <input type="hidden" name="CartCmd" value="createnotificationforthisproduct" /> <div class="form-group"> <label for="NotificationEmail">@Translate("ns_email", "E-mail adresse")</label> <div class="form-group-combined"> <input name="NotificationEmail" id="NotificationEmail" type="email" value="@usermail" class="required form-control"> <button type="submit" class="btn btn-primary btn-block">@Translate("nostocksend_btn", "Send")</button> </div> </div> </form> </div> } </div> <ul class="pdp-usp"> <li class="pdp-usp-item"> <a class="pdp-usp-link" data-fancybox data-src="#createNo1" href="javascript:;" data-options='{"infobar": false, "smallBtn": false, "toolbar": false, "buttons":["close"]'> <svg class="icon icon-xs"> <use xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="/Files/dist/icons/icons.svg#star"></use> </svg> <span> @Translate("Optjen bonuspoint") </span> </a> </li> <li class="pdp-usp-item"> <a class="pdp-usp-link" data-fancybox data-src="#returnID" href="javascript:;" data-options='{"infobar": false, "smallBtn": false, "toolbar": false, "buttons":["close"]'> <svg class="icon icon-xs"> <use xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="/Files/dist/icons/icons.svg#star"></use> </svg> <span> @Translate("30-dages returret") </span> </a> </li> @{ var usps = specs.GetByKey("ProductUSP"); } @if (!usps.Value.IsNullOrEmpty()) { <li class="pdp-usp-item"> <span class="pdp-usp-link"> <svg class="icon icon-xs"> <use xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="/Files/dist/icons/icons.svg#star"></use> </svg> <span> @usps.Value </span> </span> </li> } </ul> </div> <div class="pdp-details-data"> @if (specs.GetByGroup("Produkt detaljer").Any()) { var specsToSkipLabels = specs.GetByKey("SkjulLabelPaaWeb").Value.Split(';'); <div class="pdp-specs"> <h3>@Translate("Product details", "Detaljer")</h3> <ul class="pdp-specs-list"> @foreach (var spec in specs.GetByGroup("Produkt detaljer").GroupBy(a => a.Key).Where(i => i.Key != "Barcode" && !doNotIncludeSpecsList.Contains(i.Key) && !string.Equals(i.Key, "ProductUSP", StringComparison.InvariantCultureIgnoreCase))) { var showLabel = !specsToSkipLabels.Contains(spec.First().Key); if (spec.First().Key == "Link") { <li class="pdp-specs-item"> <a href="@spec.First().Value" target="_blank">@spec.First().Caption</a> </li> } else if (spec.First().Key == "Leveringstid" && !string.IsNullOrEmpty(stockPhaseDescription)) { <li class="pdp-specs-item"> @(showLabel ? spec.First().Caption + ": " : "")@stockPhaseDescription </li> } else { <li class="pdp-specs-item"> @(showLabel ? spec.First().Caption + ": " : "")@String.Join(", ", spec.Select(a => a.Value)) </li> } } </ul> </div> } @if (!string.IsNullOrEmpty(specs.GetByKey("Beskrivelse").Value)) { //How many chars before we attempt to split the text. var charCountBeforeSplit = 100; //Read the full text. var fullText = specs.GetByKey("Beskrivelse").Value;// + " " + specs.GetByKey("Beskrivelse").Value; //Split the text into sentences (by "."). var sentenceSplit = fullText.Select((b, i) => b.Equals('.') ? i : -1).Where(i => i != -1).ToList(); //Find closest split within the limit. var splitText = sentenceSplit.Where(s => s < charCountBeforeSplit).ToList(); //If non is found force it to the first sentence if (!splitText.Any() && sentenceSplit.Any()) { splitText.Add(sentenceSplit[0]); } //Split the text into teaser and full text. var splitPoint = splitText.Any() ? splitText.Max() + 1 : fullText.Length; var teaserText = fullText.Substring(0, splitPoint).Trim(); var remainingText = fullText.Substring(splitPoint).Trim(); //Safety check if we need to split at all. var doSplitText = !string.Equals(teaserText, remainingText) && splitText.Any(); <div class="pdp-description" itemprop="description"> <h3> @Translate("Produkt beskrivelse", "Produkt beskrivelse") </h3> <p>@teaserText</p> @if (doSplitText) { <div class="collapse" id="remainingText"><p>@remainingText</p></div> <a href="javascript.void()" data-toggle="collapse" data-target="#remainingText" aria-expanded="false" aria-controls="remainingText" class="pdp-collapse-button"> <svg class="icon icon-sm"> <use xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="/Files/dist/icons/icons.svg#angle-down"></use> </svg> </a> } </div> } </div> <div class="pdp-details-foot"> <p> @if (!string.IsNullOrEmpty(specs.GetByKey("Barcode").Value)) { <span> @specs.GetByKey("Barcode").Caption: @specs.GetByKey("Barcode").Value </span> } else { <text>&nbsp;</text> } </p> <p> <a data-fancybox data-src="#shoppingGuide" href="javascript:;" data-options='{"infobar": false, "smallBtn": false, "toolbar": false, "buttons":["close"]'>@Translate("Need help", "Brug for hjælp?")</a> </p> </div> </div> </section> @*@if (GetLoop("eCom:Related.WhatAboutTheseProducts").Any()) { <section class="pdp-related" id="partnerloop"> <h2 class="text-center">@Translate("other_favorites_heading", "Andre favoritter")</h2> <ul class="plp-list"> @foreach (var product in GetLoop("eCom:Related.WhatAboutTheseProducts").Take(4)) { var plpSpecs = product.GetProductSpecifications(); var plpImage = plpSpecs.HasKey("Billeder") ? "/Files/Images/XPI/" + plpSpecs.GetByKey("Billeder").Value : "/Files/Images/Ecom/default.jpg"; var url = "/Default.aspx?ID=" + NORRIQ.Common8.Razor.Navigation.GetPageIdByNavigationTag("webshop") + "&amp;ProductID=" + product.GetString("Ecom:Product.ID.UrlEncoded"); <li class="plp-list-item"> <article class="plp-list-product"> <a href="@url" itemprop="url" class="plp-list-url"> <figure class="plp-list-image"> <img src="@Pageview.CdnWrap(string.Format("/Admin/Public/GetImage.ashx?Image={0}&amp;Width=220&amp;Height=220&amp;Crop=5&amp;Compression=90", plpImage))" class="img-fluid" alt="@product.GetString("Ecom:Product.Name")" itemprop="image" /> </figure> <header class="plp-list-info"> <p class="plp-list-brand" itemprop="brand"> @plpSpecs.GetByKey("Brand").Value </p> <h2 class="plp-list-name" itemprop="name"> @product.GetString("Ecom:Product.Name") </h2> </header> </a> <footer class="plp-list-prices"> @{ var pdpPrice = product.GetDouble("Ecom:Product.Price.PriceWithVAT.Value"); var pdpBeforeprice = product.GetString("Ecom:Product:Field.Beforeprice.Value"); } @if (pdpBeforeprice != "") { <span class="plp-org-price"> <span>@Translate("Before price", "Før ")</span> <span>@pdpBeforeprice</span> <span>@currencyCode</span> </span> <span class="plp-list-price"> <span>@Translate("After price", "Nu")</span> <span itemprop="price">@pdpPrice.ToString("N2")</span> <span itemprop="price">@currencyCode</span> </span> } else { <span class="plp-list-price"> <span itemprop="price">@pdpPrice.ToString("N2")</span> <span itemprop="priceCurrency">@currencyCode</span> </span> } </footer> </article> </li> } </ul> </section> }*@ </div> @{ var No1Banner = 0; if (!string.IsNullOrEmpty(Pageview.Area.Item["No1Banner"] as string)) { Int32.TryParse(Pageview.Area.Item["No1Banner"].ToString().Split('#').Last(), out No1Banner); } } @{ var imageLocation = ""; var imageText = ""; var brandPageLink = ""; var fallback = false; var xpiLocation = specs.GetByKey("BrandBanner").Value; //If there is data in XPI, get everything from there if (!string.IsNullOrWhiteSpace(xpiLocation.Trim())) { imageLocation = "/Files/Images/XPI/" + xpiLocation; imageText = specs.GetByKey("BrandText").Value; brandPageLink = specs.GetByKey("BrandLink").Value; } else { var brandingService = ObjectFactory.GetInstance<BrandingService> (); var brandName = specs.GetByKey("brand").Value; var brandPageInfo = brandingService.GetDwBrandPageInfo(brandName); var dwImageLocation = brandPageInfo.ImageLocation; if (!string.IsNullOrWhiteSpace(dwImageLocation)) { imageLocation = dwImageLocation; imageText = brandPageInfo.ImageText; brandPageLink = "/Default.aspx?ID=" + brandPageInfo.BrandPageId; } else if (No1Banner > 0) { fallback = true; //Render No1Banner as hidden and display it only if the user is not signed in <div id="no1bannertest" style="display: none;"> @RenderParagraphContent(No1Banner) </div> <script append="true"> $(document).ready(function () { var branding = new AppStart.BrandBannerHandler(); branding.init(); }); </script> } } if (!fallback && imageLocation.IsNotNullOrEmpty()) { <section class="banner"> <picture> <img src="@Pageview.CdnWrap(string.Format("/Admin/Public/GetImage.ashx?Image={0}&amp;Width=2048&amp;Compression=90", imageLocation))" class="img-fluid" /> </picture> <div class="banner-content justify-content-center align-items-center"> <div class="banner-text text-center text-light bg-clear"> <h2 class="h1">@imageText</h2> <div class="btn-list"> <a href="@brandPageLink" class="btn btn-outline-light"> <span> @Translate("Læs mere", "Læs mere") </span> </a> </div> </div> </div> </section> } } <div id="addedModal" style="display:none;" class="fancybox-content"> @*<button class="btn-modal-close" data-fancybox-close> <svg class="icon"> <use xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="/Files/dist/icons/icons.svg#times"></use> </svg> </button>*@ <div class="fancybox-pdp-header"> <p class="h2"> <span data-bind="text: QuantityAdded"></span> @Translate("Products added to basket", "vare(r) tilføjet til kurven") </p> <p class="alert alert-warning" data-bind="visible: NoProductsAdded"> @Translate("Product not in stock", "Produktet er desværre ikke længere på lager og er derfor ikke tilføjet til kurven.") </p> <p class="alert alert-warning" data-bind="visible: QuantityAdjusted"> @Translate("Added product amount adjusted", "Obs. ikke tilstrækkelig på lager, antallet er nedjusteret.") </p> </div> <div class="fancybox-pdp-body"> <div class="fancybox-pdp-thumb"> <img data-bind="attr: { src: ProductImage}" src="" class="img-fluid" alt=""> </div> <div class="fancybox-pdp-product"> <div class="fancybox-pdp-name"> <span data-bind="text: Name"> </span> </div> <div class="fancybox-pdp-row"> <div class="fancybox-pdp-col"> <span class="fancybox-pdp-brand"> <span>@Translate("Brand", "Brand"):</span> <span data-bind="text: ProductBrand"></span> </span> <span class="fancybox-pdp-sku"> <span>@Translate("SKU", "Varenummer"):</span> <span data-bind="text: ProductNumber">12345678</span> </span> </div> <div class="fancybox-pdp-col"> <span class="fancybox-pdp-qty"> <span>@Translate("Quantity", "Antal"):</span> <span data-bind="text: QuantityAdded"></span> </span> <span class="fancybox-pdp-price"> <span><span data-bind="text: LinePrice"></span> @currency</span> </span> </div> </div> </div> </div> <div class="fancybox-pdp-navigation"> <a href="@NORRIQ.Common8.Razor.Navigation.GetUrlByNavigationTag(" cart")" class="btn btn-outline-dark"> @Translate("Show cart", "Vis kurv") </a> <a href="@NORRIQ.Common8.Razor.Navigation.GetUrlByNavigationTag(" checkout")" class="btn btn-secondary"> @Translate("Checkout", "Checkout") </a> </div> </div> <div id="giftlistLogin" data-action="submitLogin" style="display: none" class="fancybox-content loginFeedback"> <form method="post" id="testForm"> <h2>@Translate("giftlist", "Gaveliste")</h2> <span>@Translate("giftlist_not_loggedin", "Du bedes logge ind for at kunne tilføje til din gaveliste.")</span> <h3>@Translate("login_pop_header", "Log ind")</h3> <div class="form-group"> <label for="giftListUsername">@Translate("usernameLabel", "Brugernavn")</label> <input id="giftListUsername" name="Username" type="text" value="" class="form-control" required> </div> <div class="form-group"> <label for="giftListPassword">@Translate("password", "Adgangskode")</label> <input id="giftListPassword" name="Password" type="password" value="" class="form-control" required> </div> <div id="giftListloginFeedback"></div> <p class=""> <button type="submit" role="button" class="btn btn-primary btn-block" id="giftListloginBtn">@Translate("buttonLogin", "Log ind")</button> </p> @{ var giftListPasswordUrl = Navigation.GetUrlByNavigationTag("forgot-password"); var giftListNewUserUrl = Navigation.GetUrlByNavigationTag("new-user"); } <div class="loginFeedback" style="display: none;"> <p class="alert alert-warning"> @Translate("Cart Login Error", "Har du glemt dit brugernavn eller adgangskode?") <a href="@NORRIQ.Common8.Razor.Navigation.GetUriByNavigationTag("forgot-password")">@Translate("Cart Login Error Label", " Så klik her")</a> </p> </div> <ul class="list-unstyled"> <li> <a href="@giftListPasswordUrl" class="forgot-password">@Translate("label_forgotten_password", "Glemt adgangskode")</a> </li> <li> <a href="@giftListNewUserUrl">@Translate("label_create_new_user", "Opret ny bruger")</a> </li> </ul> </form> </div> @{ var shoppingGuide = 0; var createNo1 = 0; var infoNo1 = 0; var returnID = 0; if (!string.IsNullOrEmpty(Pageview.Area.Item["ShoppingGuide"] as string)) { Int32.TryParse(Pageview.Area.Item["ShoppingGuide"].ToString().Split('#').Last(), out shoppingGuide); } if (!string.IsNullOrEmpty(Pageview.Area.Item["No1CreateUser"] as string)) { Int32.TryParse(Pageview.Area.Item["No1CreateUser"].ToString().Split('#').Last(), out createNo1); } if (!string.IsNullOrEmpty(Pageview.Area.Item["No1Infotext"] as string)) { Int32.TryParse(Pageview.Area.Item["No1Infotext"].ToString().Split('#').Last(), out infoNo1); } if (!string.IsNullOrEmpty(Pageview.Area.Item["ShoppingTerms"] as string)) { Int32.TryParse(Pageview.Area.Item["ShoppingTerms"].ToString().Split('#').Last(), out returnID); } } @if (shoppingGuide > 0) { <div id="shoppingGuide" style="display:none;" class="fancybox-content"> @RenderParagraphContent(shoppingGuide) </div> } @if (createNo1 > 0 && infoNo1 > 0) { <div id="createNo1" style="display:none;" class="fancybox-content"> <h2 class="h1">@Translate("Opret dig som No1 kunde", "Opret dig som No1 kunde")</h2> @RenderParagraphContent(infoNo1) @RenderParagraphContent(createNo1) </div> } @if (returnID > 0) { <div id="returnID" style="display:none;" class="fancybox-content"> @RenderParagraphContent(returnID) </div> } @* Facebook Pixel tracking, CAS-25405-W5J7V5 *@ <script append="true"> if (typeof fbq !== "undefined") { fbq('track', 'ViewContent', { content_ids: ['@GetString("Ecom:Product.Number")'], content_type: 'product', content_name: '@specs.GetByKey("ProductName").Value', value: @GetDouble("Ecom:Product.Price.PriceWithVAT.Value").ToString("F2", new CultureInfo("en-US")), currency: '@currency' }); }; //TODO: Ulf tilføj dette til TS for PDP!!! $('.pdp-qty-increase').click(function() { var $input = $(this).parents('.pdp-qty-control').find('.form-control'); var val = parseInt($input.val(), 10); $input.val(val + 1); }); $('.pdp-qty-decrease').click(function() { var $input = $(this).parents('.pdp-qty-control').find('.form-control'); var val = parseInt($input.val(), 10); if (val > 1) { $input.val(val - 1); } }); </script> <script append="true"> $(document).ready(function () { var giftList = new AppStart.GiftList; giftList.init(); }); </script>