Trustpilot

ORDERS PLACED BEFORE 1PM WILL BE SHIPPED SAME WORKING DAY

EXCELLENT CUSTOMER SERVICE

ORDERS PLACED BEFORE 1PM WILL BE SHIPPED SAME WORKING DAY

14 DAYS RETURN POLICY

Exception in template (Designs\OutletCamping\eCom/Product/Product.cshtml): System.NullReferenceException: Object reference not set to an instance of an object.
   at CompiledRazorTemplates.Dynamic.ceaddbbfda.Execute()
   at RazorEngine.Templating.TemplateBase.RazorEngine.Templating.ITemplate.Run(ExecuteContext context) in c:\Users\abbottm\Documents\GitHub\RazorEngine\src\Core\RazorEngine.Core\Templating\TemplateBase.cs:line 126
   at RazorEngine.Templating.TemplateService.Run(ITemplate template, DynamicViewBag viewBag) in c:\Users\abbottm\Documents\GitHub\RazorEngine\src\Core\RazorEngine.Core\Templating\TemplateService.cs:line 608
   at RazorEngine.Templating.TemplateService.Parse(String razorTemplate, Object model, DynamicViewBag viewBag, String cacheName) in c:\Users\abbottm\Documents\GitHub\RazorEngine\src\Core\RazorEngine.Core\Templating\TemplateService.cs:line 439
   at RazorEngine.Razor.Parse[T](String razorTemplate, T model, DynamicViewBag viewBag, String cacheName) in c:\Users\abbottm\Documents\GitHub\RazorEngine\src\Core\RazorEngine.Core\Razor.cs:line 290
   at Dynamicweb.Rendering.Template.RenderRazorTemplate()
@inherits Dynamicweb.Rendering.RazorTemplateBase<Dynamicweb.Rendering.RazorTemplateModel<Dynamicweb.Rendering.Template>> @using System @using System.Globalization @using System.Collections @using System.Collections.Generic @using System.Linq @using System.Web @using System.Web.Script.Serialization @using System.Net @using Dynamicweb.Ecommerce.Products @using Dynamicweb.Extensibility @using Dynamicweb.Frontend @using Dynamicweb.Content @using Dynamicweb.Data @using OaseOutdoors.Components.Shared.Modules.Ecom.ModelBuilders @using OaseOutdoors.Components.Shared.Modules.Ecom.Models @using OaseOutdoors.Services.EcomUrlService.Initialization @using OaseOutdoors.Services.UrlParserService.Initialization @using OaseOutdoors.Services.ImageService.Enums @using OaseOutdoors.Services.StaticResourceService.Initialization @using OaseOutdoors.Services.UrlParserService.Initialization; @using OaseOutdoors.Services.UrlParserService.Interfaces; @{ var headStaticResourceService = ServiceLocator.Current.GetStaticResourceService(); string productId = GetString("Ecom:Product.ID"); string productNumber = GetString("Ecom:Product.Number"); string variantId = GetString("Ecom:Product.VariantID"); string languageId = GetString("Ecom:Product.LanguageID"); string groupId = GetString("Ecom:Group.ID"); var product = Product.GetProductById(productId, variantId, languageId); var viewModelService = new ProductViewModelBuilder(); var viewModel = viewModelService.GetViewModel(product); var staticResourceService = ServiceLocator.Current.GetStaticResourceService(); var urlService = ServiceLocator.Current.GetEcomUrlService(); var urlParserService = ServiceLocator.Current.GetUrlParserService(); int breadCrumbTotal = viewModel.Breadcrumb.Count; int breadCrumbIndex = 1; var valutaSelector = HttpContext.Current.Request.Cookies["currencySelector"]; var area = PageView.Current().Area; var areas = Dynamicweb.Services.Areas.GetAreas().Where(x => x.Active && x.Item["ShopPublished"] != null && (bool)x.Item["ShopPublished"] && x.Name.ToLower().Contains(area.Name.Split(':')[0].Trim().ToLower())).ToList(); var group = (Group.GetGroupById(groupId)) ?? Group.GetGroupById(viewModel.GroupId); string specBlackList = Pageview.Area.Item["ProductSpecBlacklist"] != null ? Pageview.Area.Item["ProductSpecBlacklist"].ToString() : ""; string productDeliveryUrl = Pageview.Area.Item["ProductDeliveryTermsPage"] != null ? Pageview.Area.Item["ProductDeliveryTermsPage"].ToString() : ""; //Pageview.Page.MetaTitle = viewModel.PageTitle; //Pageview.Page.Description = viewModel.PageMetaDescription; //Pageview.Page.MetaCanonical = viewModel.PageCanonical; // PageLog OasePageLog.SetPageLog(productNumber); } @SnippetStart("canonical") <link rel="canonical" href="@viewModel.Canonical" /> @foreach (var hrefLang in viewModel.HrefLangs) { if (!hrefLang.Href.ToLower().Contains("page-not-found")) { <link rel="alternate" hreflang="@hrefLang.HrefLang" href="@hrefLang.Href" /> } } @SnippetEnd("canonical") @SnippetStart("languageSelector") <ul> @foreach (var languageArea in areas) { var hrefLang = viewModel.HrefLangs.FirstOrDefault(x => x.HrefAreaId == languageArea.ID); if (hrefLang == null || hrefLang.Href.ToLower().Contains("page-not-found")) { hrefLang = new HrefLangViewModel(); hrefLang.HrefName = languageArea.Item["ShopLanguageName"].ToString() ?? string.Empty; hrefLang.HrefLang = languageArea.CultureInfo.Name; hrefLang.Href = "/Default.aspx?areaid=" + languageArea.ID; hrefLang.HrefAreaId = languageArea.ID; if (hrefLang.HrefAreaId == 12) { hrefLang.Href = "https://www.outletcamping.com/da-dk"; } if (hrefLang.HrefAreaId == 13) { hrefLang.Href = "https://www.outletcamping.com/de-de"; } if (hrefLang.HrefAreaId == 32) { hrefLang.Href = "https://www.outletcamping.com/fr-fr"; } if (hrefLang.HrefAreaId == 14) { hrefLang.Href = "https://www.outletcamping.com/en-gb-1"; } if (hrefLang.HrefAreaId == 9) { hrefLang.Href = "https://www.outletcamping.com/en-gb"; } } if (hrefLang != null && hrefLang.HrefLang != "x-default") { <li class="country-picker__item @(hrefLang.HrefAreaId == Pageview.AreaID ? "country-picker__item--current" : string.Empty)"> <a href="@hrefLang.Href"> <svg aria-hidden="true"> <use xlink:href="@staticResourceService.AddTimeStamp("/static/dist/svg/_bundle.svg")#outletcamping-arrow-right"></use> </svg> <span>@hrefLang.HrefName</span> </a> </li> } } </ul> @SnippetEnd("languageSelector") <section class="content content--breadcrumb container-ribbon"> <div class="container"> <ol class="breadcrumb" itemscope itemtype="https://schema.org/BreadcrumbList"> @foreach (var item in viewModel.Breadcrumb) { var itemLink = item.Link; <li class="breadcrumb__item @(item == viewModel.Breadcrumb.LastOrDefault() ? "breadcrumb__item--current" : "")" itemprop="itemListElement" itemscope itemtype="https://schema.org/ListItem"> @if (breadCrumbIndex == breadCrumbTotal - 1) { itemLink = "javascript:window.history.back();"; } @if (item == viewModel.Breadcrumb.LastOrDefault()) { <a itemprop="item"> <span itemprop="name"> @if (breadCrumbIndex == breadCrumbTotal - 1) { @* The second to last breadcrumb item is the only one visible on mobile devices and thus the only one with this SVG *@ <svg aria-hidden="true"><use xlink:href="@staticResourceService.AddTimeStamp("/static/dist/svg/_bundle.svg")#arrow-left"></use></svg> } @item.LinkTitle </span> </a> } else { <a itemprop="item" href="@itemLink"> <span itemprop="name"> @if (breadCrumbIndex == breadCrumbTotal - 1) { @* The second to last breadcrumb item is the only one visible on mobile devices and thus the only one with this SVG *@ <svg aria-hidden="true"><use xlink:href="@staticResourceService.AddTimeStamp("/static/dist/svg/_bundle.svg")#arrow-left"></use></svg> } @item.LinkTitle </span> </a> } <meta itemprop="position" content="@breadCrumbIndex"> </li> breadCrumbIndex++; } </ol> </div> </section> <section class="content content--body"> @* OVERLAY IMAGES Er ikke med i det godkendte design, og er derfor udkommenteret her Skal de med igen, skal vi lige vide, hvor og hvordan @if (viewModel.OverlayImages.Count > 0) { <ul> @foreach (var image in viewModel.OverlayImages) { <li><img src="@image" width="100"/></li> } </ul> } *@ <section class="container-fluid"> <article class="container product" itemscope itemtype="https://schema.org/Product" data-module="product"> <div class="product__essentials"> <div class="mobile-slider"> <div class="MagicSlideshow video-container"> <img src="@viewModel.MainImage.SetWidth(1230).SetCrop(CropType.KeepAspectRatio).SetCompression(80).SetImageFormat(ImageFormat.Jpg).GetCrop()" alt="Easycamp @viewModel.Name" /> @if (viewModel.FeatureVideos.Any()) { foreach (var featureVideo in viewModel.FeatureVideos) { <iframe src="@featureVideo.VideoUrl?rel=0&amp;showinfo=0&amp;controls=0" frameborder="0" allowfullscreen></iframe> } } @if (!string.IsNullOrEmpty(viewModel.Award001)) { <img data-image="@viewModel.Award001" alt="Camping award" />} @if (viewModel.ProductImages.Count > 0) { foreach (var image in viewModel.ProductImages) { <img src="@image.SetWidth(1230).SetCrop(CropType.KeepAspectRatio).SetCompression(80).SetImageFormat(ImageFormat.Jpg).GetCrop()" alt="Easycamp @viewModel.Name" /> } } </div> @if (!string.IsNullOrEmpty(viewModel.OutletcampingSplash) && !string.IsNullOrEmpty(viewModel.OutletcampingSplashColor)) { var splashTexts = viewModel.OutletcampingSplash.Split(' '); <div class="product__splash product__splash product__splash product__splash--image" style="background: @viewModel.OutletcampingSplashColor;"> <div class="product__splash-text"> <p> @for (var i = 0; i <= splashTexts.Length - 1; i++) { if (i == 1) { <span class="product__splash-text--bold"> @splashTexts[i]</span> } else { @splashTexts[i] } } </p> </div> </div> } <script> var MagicSlideshowOptions = { selectors: "bottom", bulletsPreview: "none", caption: false }; </script> </div> <div class="product__images"> <div class="product__images-options product__images-options--scrolled"> <button class="product__images-button product__images-button--previous"><svg aria-hidden="true"><use xlink:href="@staticResourceService.AddTimeStamp("/static/dist/svg/_bundle.svg")#arrow-up"></use></svg></button> <div class="product__images-options-items"> <div> <div class="product__images-option"> <div class="lazy" data-src-xxs="@viewModel.MainImage.SetWidth(69).SetHeight(69).SetCrop(CropType.KeepAspectRatio).SetImageFormat(ImageFormat.Jpg).SetCompression(80).GetCrop()" alt="@viewModel.Name"></div> </div> @if (viewModel.FeatureVideos.Any()) { foreach (var featureVideo in viewModel.FeatureVideos) { <div class="product__images-option product__images-option--video"> <div class="lazy" data-src-xxs="@featureVideo.ImageUrl"></div> <div> <svg aria-hidden="true"><use xlink:href="@staticResourceService.AddTimeStamp("/static/dist/svg/_bundle.svg")#youtube-play"></use></svg> </div> </div> } } @if (!string.IsNullOrEmpty(viewModel.Award001)) { <div class="product__images-option"><div class="lazy" data-src-xxs="@viewModel.Award001" alt="camping award"></div></div> } @if (viewModel.ProductImages.Count > 0) { foreach (var image in viewModel.ProductImages) { <div class="product__images-option"> <div class="lazy" data-src-xxs="@image.SetWidth(69).SetHeight(69).SetCrop(CropType.KeepAspectRatio).SetImageFormat(ImageFormat.Jpg).SetCompression(80).GetCrop()" alt="@viewModel.Name"></div> </div> } } </div> </div> <button class="product__images-button product__images-button--next product__images-button--hidden" disabled><svg aria-hidden="true"><use xlink:href="@staticResourceService.AddTimeStamp("/static/dist/svg/_bundle.svg")#arrow-down"></use></svg></button> </div> <div class="product__images-showcase"> <div class="product__image" data-src-xxs="@viewModel.MainImage.SetHeight(300).SetCrop(CropType.KeepAspectRatio).SetCompression(80).SetImageFormat(ImageFormat.Jpg).GetCrop()" alt="@viewModel.Name" data-src-sm="@viewModel.MainImage.SetHeight(640).SetCrop(CropType.KeepAspectRatio).SetCompression(80).SetImageFormat(ImageFormat.Jpg).GetCrop()" alt="@viewModel.Name" data-src-md="@viewModel.MainImage.SetWidth(630).SetCrop(CropType.KeepAspectRatio).SetCompression(80).SetImageFormat(ImageFormat.Jpg).GetCrop()" alt="@viewModel.Name" data-src-lg="@viewModel.MainImage.SetWidth(728).SetCrop(CropType.KeepAspectRatio).SetCompression(80).SetImageFormat(ImageFormat.Jpg).GetCrop()" alt="@viewModel.Name" data-gallery="@viewModel.MainImage.SetWidth(1230).SetCrop(CropType.KeepAspectRatio).SetCompression(80).SetImageFormat(ImageFormat.Jpg).GetCrop()" alt="@viewModel.Name"> </div> @if (viewModel.FeatureVideos.Any()) { foreach (var featureVideo in viewModel.FeatureVideos) { <div class="product__image product__image--video"> <div class="video-container"> <iframe src="@featureVideo.VideoUrl?rel=0&amp;showinfo=0&amp;controls=0" frameborder="0" allowfullscreen></iframe> </div> </div> } } @if (!string.IsNullOrEmpty(viewModel.Award001)) { <div class="product__image" data-src-xxs="@viewModel.Award001" data-src-sm="@viewModel.Award001" data-src-md="@viewModel.Award001" data-src-lg="@viewModel.Award001" data-gallery="@viewModel.Award001"> </div>} @if (viewModel.ProductImages.Count > 0) { foreach (var image in viewModel.ProductImages) { <div class="product__image" data-src-xxs="@image.SetHeight(300).SetCrop(CropType.KeepAspectRatio).SetCompression(80).SetImageFormat(ImageFormat.Jpg).GetCrop()" alt="@viewModel.Name" data-src-sm="@image.SetHeight(640).SetCrop(CropType.KeepAspectRatio).SetCompression(80).SetImageFormat(ImageFormat.Jpg).GetCrop()" alt="@viewModel.Name" data-src-md="@image.SetWidth(630).SetCrop(CropType.KeepAspectRatio).SetCompression(80).SetImageFormat(ImageFormat.Jpg).GetCrop()" alt="@viewModel.Name" data-src-lg="@image.SetWidth(728).SetCrop(CropType.KeepAspectRatio).SetCompression(80).SetImageFormat(ImageFormat.Jpg).GetCrop()" alt="@viewModel.Name" data-gallery="@image.SetWidth(1230).SetCrop(CropType.KeepAspectRatio).SetCompression(80).SetImageFormat(ImageFormat.Jpg).GetCrop()" alt="@viewModel.Name"> </div> } } </div> @if (!string.IsNullOrEmpty(viewModel.OutletcampingSplash) && !string.IsNullOrEmpty(viewModel.OutletcampingSplashColor)) { var splashTexts = viewModel.OutletcampingSplash.Split(' '); <div class="product__splash product__splash product__splash product__splash--image" style="background: @viewModel.OutletcampingSplashColor;"> <div class="product__splash-text"> <p> @for (var i = 0; i <= splashTexts.Length - 1; i++) { if (i == 1) { <span class="product__splash-text--bold"> @splashTexts[i]</span> } else { @splashTexts[i] } } </p> </div> </div> } </div> <div class="product__info"> <div class="product__info-top"> @if (!string.IsNullOrWhiteSpace(@viewModel.Name)) { <h1 class="product__name" itemprop="name">@viewModel.Name</h1> } @if (!string.IsNullOrWhiteSpace(@viewModel.ShortDescription)) { <div class="product__description"> @viewModel.ShortDescription </div> } @if (!string.IsNullOrWhiteSpace(@viewModel.BeforePrice)) { <div class="product__old-price"> @Translate("Before", "Used to be") @viewModel.CurrencySymbol @viewModel.BeforePrice </div> } <link itemprop="brand" content="Outletcamping" /> <link itemprop="image" href="@viewModel.MainImage.SetCrop(CropType.KeepAspectRatio).SetCompression(80).SetImageFormat(ImageFormat.Jpg).SetWidth(630).GetCrop()" /> <div class="product__price" itemprop="offers" itemscope itemtype="https://schema.org/Offer"> <span itemprop="priceCurrency" content="@viewModel.Currency">@viewModel.CurrencySymbol</span> <span itemprop="price" content="@viewModel.UnformatedPrice">@viewModel.Price</span> <link itemprop="availability" href="@(viewModel.Stock > 0 ? "https://schema.org/InStock" : "https://schema.org/OutOfStock")"> <link itemprop="url" href="@Pageview.SearchFriendlyUrl" /> @if (!string.IsNullOrEmpty(GetString("Ecom:Product:Field.OutletcampingSplash")) && !string.IsNullOrEmpty(GetString("Ecom:Product:Field.OutletcampingSplashColor"))) { var splashTexts = GetString("Ecom:Product:Field.OutletcampingSplash").Split(' '); <div class="product__splash product__splash" style="background: @GetString("Ecom:Product:Field.OutletcampingSplashColor");"> <div class="product__splash-text"> <p> @for (var i = 0; i <= splashTexts.Count() - 1; i++) { if (i == 1) { <span class="product__splash-text--bold"> @splashTexts[i]</span> } else { @splashTexts[i] } } </p> </div> </div> } </div> </div> <div class="product__info-bottom"> @if (!string.IsNullOrWhiteSpace(viewModel.CheckoutPageLink) && !string.IsNullOrWhiteSpace(viewModel.CartContext)) { if (valutaSelector == null || Pageview.AreaID != 1) { if (viewModel.Stock > 0) { <div class="product__button"> <form method="get" data-id="@viewModel.Id" data-number="@viewModel.ProductNumber" data-name="@viewModel.Name.Replace("\"", "\'")" data-quantity="1" data-price="@viewModel.UnformatedPrice" data-currency="@viewModel.Currency" data-brand="@GetString("Ecom:Product:Field.BrandName")"> <input type="hidden" name="CartCmd" id="CartCmd" value="@(viewModel.OrderLine != null ? "incorderline" : "add")" /> <input type="hidden" name="Key" id="Key" value="@(viewModel.OrderLine != null ? viewModel.OrderLine.Id : "")" @(viewModel.OrderLine != null ? "" : "disabled") /> <input type="hidden" name="OrderContext" id="OrderContext" value="@viewModel.CartContext" /> <input type="hidden" name="Redirect" id="Redirect" value="/WebServices/MiniCart.ashx?productId=@viewModel.Id&areaId=@Pageview.AreaID" disabled /> <div class="product__button-quantity-container"> <div class="product__button-dec">-</div> <input type="text" class="product__button-quantity" name="Quantity" value="1"><div class="product__button-inc">+</div> </div> <button type="submit" class="btn btn--big" @(viewModel.Stock > 0 ? "" : "disabled") data-added-msg="@(Translate("AddedToCart", "Added to cart"))"> <span class="btn__icon"> <img src="@staticResourceService.AddTimeStamp("/static/dist/media/cart-white-outletcamping.png")"> </span> <span class="btn__text">@Translate("AddToCart", "Add to cart")</span> </button> </form> </div> <div class="product__availability product__availability--instock"> @{ var stockStatusText = ""; switch (Convert.ToInt32(viewModel.Stock)) { case 1: stockStatusText = "<span>" + Translate("Only 1 left", "Only 1 left") + "</span>"; break; case 2: stockStatusText = "<span>" + Translate("Only 2 left", "Only 2 left") + "</span>"; break; case 3: stockStatusText = "<span>" + Translate("Only 3 left", "Only 3 left") + "</span>"; break; case 4: stockStatusText = "<span>" + Translate("Only few left", "Only few left") + "</span>"; break; case 5: stockStatusText = "<span>" + Translate("Only few left", "Only few left") + "</span>"; break; default: stockStatusText = "<span class=\"product__availability--many\">" + Translate("In stock now", "In stock now") + "</span>"; break; } } @Translate("Availability:", "Availability:") @stockStatusText </div> <script>(function () { var o = document.createElement('script'); o.type = 'text/javascript'; o.async = true; o.src = 'https://pricetag.viabill.com/script/5kjDlkPvm6I%3D'; var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(o, s); })();</script> <div class="viabill-pricetag" data-view="product" data-price="@viewModel.Price" data-currency="@viewModel.Currency"> </div> } else { @Translate("Availability:", "Availability:") @Translate("Sold out", " Sold out") } } } <div class="product__countdown-container"> @if (viewModel.PeriodEndDate >= DateTime.Now && viewModel.PeriodEndDate <= DateTime.Now.AddDays(14)) { <div data-module="countdown"> <div class="product__countdown" data-date="@viewModel.PeriodEndDate.ToString("MM/dd/yyyy HH:mm:ss")"> <div class="product__countdown-title">@Translate("Offer ends in"):</div> <div class="product__countdown-counter"></div> <div class="product__countdown-text"> <span>@Translate("Hours", "Hours")</span> <span>@Translate("Min", "Min")</span> <span>@Translate("Sec", "Sec")</span> </div> </div> </div> } <div class="product__brandname"> <p>@Translate("Brand", "Brand"):</p> @{ var brandName = GetString("Ecom:Product:Field.BrandName").ToLower(); if (brandName == "outwell") { <svg aria-hidden="true" class="product__brandname-outwell"> <use xlink:href="@staticResourceService.AddTimeStamp("/static/dist/svg/_bundle.svg")#outwell-logo"></use> </svg> } else if (brandName == "easycamp" || brandName == "easy camp") { <svg aria-hidden="true" class="product__brandname-easycamp"> <use xlink:href="@staticResourceService.AddTimeStamp("/static/dist/svg/_bundle.svg")#easycamp-logo"></use> </svg> } else if (brandName == "robens") { <img style="max-width:200px;width:200px;" src="/static/dist/img/robens_logo.svg?ts=638344303680000000" alt="Robens – pure outdoor passion"> } } </div> </div> <dl class="product__bullet-points product__bullet-points--desktop"> <dt><div class="product__bullet-points-image"><img src="@staticResourceService.AddTimeStamp("/static/dist/media/customer-service-outletcamping.png")"></div>@Translate("VP1Title", "Need help?")</dt> <dd> @if (!Translate("VP1Link").Equals("VP1Link")) { <a href="@Translate("VP1Link")">@Translate("VP1SubTitle", "Contact our customer service")</a> } else { @Translate("VP1SubTitle", "Contact our customer service") } </dd> <dt><div class="product__bullet-points-image"><img src="@staticResourceService.AddTimeStamp("/static/dist/media/delivery-outletcamping.png")"></div>@Translate("VP2Title", "Need help?")</dt> <dd> @if (!Translate("VP2Link").Equals("VP2Link")) { <a href="@Translate("VP2Link")">@Translate("VP2SubTitle", "Contact our customer service")</a> } else { @Translate("VP2SubTitle", "Contact our customer service") } <div data-module="bootstrap-modal"> <div class="bootstrap-modal__container" data-id="ProductDeliveryModal"> <div class="bootstrap-modal__text">@Translate("ProductDeliveryFrom", "Levering fra kr. 39,-")</div> <div class="bootstrap-modal__text"><a href="javascript:void(0);" class="bootstrap-modal__open">@Translate("ProductDeliverySeeMore", "Se mere om levering")</a></div> </div> @SnippetStart("productModal") <div data-module="bootstrap-modal"> <div class="bootstrap-modal__container" data-id="ProductDeliveryModal" data-url="@productDeliveryUrl"> <div id="ProductDeliveryModal_Background" class="bootstrap-modal__bg"></div> <div id="ProductDeliveryModal" class="bootstrap-modal"> <div class="bootstrap-modal__content"> <div class="bootstrap-modal__header"> <span class="bootstrap-modal__close" title="Close">&times;</span> </div> <div class="bootstrap-modal__body"> <iframe src="" class="bootstrap-modal__iframe" width="100%" height="100%" frameborder="0" hspace="0" vspace="0" marginheight="0" allowtransparency="true"></iframe> </div> <div class="bootstrap-modal__footer"> </div> </div> </div> </div> </div> @SnippetEnd("productModal") </div> </dd> <dt><div class="product__bullet-points-image"><img src="@staticResourceService.AddTimeStamp("/static/dist/media/oc_ikon2.png")"></div>@Translate("VP3Title", "Need help?")</dt> <dd> @if (!Translate("VP3Link").Equals("VP3Link")) { <a href="@Translate("VP3Link")">@Translate("VP3SubTitle", "Contact our customer service")</a> } else { @Translate("VP3SubTitle", "Contact our customer service") } </dd> </dl> </div> </div> </div> <section class="product__details"> <h2>@Translate("Details", "Details")</h2> <div class="product__details-list"> <div class="product__details-options"> <div class="product__details-options-line"></div> @if (viewModel.DimensionImages.Count > 0) { <div class="product__details-option"> <button> <svg aria-hidden="true"><use xlink:href="@staticResourceService.AddTimeStamp("/static/dist/svg/_bundle.svg")#arrow-right"></use></svg> <span>@Translate("Layout", "Layout")</span> </button> <div class="product__details-item-placeholder"><div></div></div> </div> } @if (viewModel.Features.Count > 0 || viewModel.TemperatureImages.Count > 0) { <div class="product__details-option"> <button> <svg aria-hidden="true"><use xlink:href="@staticResourceService.AddTimeStamp("/static/dist/svg/_bundle.svg")#arrow-right"></use></svg> <span>@Translate("Specifications", "Specifications")</span> </button> <div class="product__details-item-placeholder"><div></div></div> </div> } @if (!string.IsNullOrWhiteSpace(@viewModel.LongDescription)) { <div class="product__details-option"> <button> <svg aria-hidden="true"><use xlink:href="@staticResourceService.AddTimeStamp("/static/dist/svg/_bundle.svg")#arrow-right"></use></svg> <span>@Translate("Description", "Description")</span> </button> <div class="product__details-item-placeholder"><div></div></div> </div> } @if (!string.IsNullOrWhiteSpace(@viewModel.CareText) || !string.IsNullOrWhiteSpace(@viewModel.CareVideoUrl) || !string.IsNullOrWhiteSpace(@viewModel.CareVideo) || !string.IsNullOrWhiteSpace(@viewModel.CareFile) || !string.IsNullOrWhiteSpace(@viewModel.CareFileDescription) || !string.IsNullOrWhiteSpace(@viewModel.Image082) ) { <div class="product__details-option"> <button> <svg aria-hidden="true"><use xlink:href="@staticResourceService.AddTimeStamp("/static/dist/svg/_bundle.svg")#arrow-right"></use></svg> <span>@Translate("Care", "Care")</span> </button> <div class="product__details-item-placeholder"><div></div></div> </div> } @if (viewModel.PitchingImages.Count > 0 || !string.IsNullOrWhiteSpace(@viewModel.PitchingVideo) || !string.IsNullOrWhiteSpace(@viewModel.PitchingVideo2) || !string.IsNullOrWhiteSpace(@viewModel.PitchingVideo3)) { <div class="product__details-option"> <button> <svg aria-hidden="true"><use xlink:href="@staticResourceService.AddTimeStamp("/static/dist/svg/_bundle.svg")#arrow-right"></use></svg> <span>@Translate("Pitching", "Pitching")</span> </button> <div class="product__details-item-placeholder"><div></div></div> </div> } @if (viewModel.Icons.Count > 0) { <div class="product__details-option"> <button> <svg aria-hidden="true"><use xlink:href="@staticResourceService.AddTimeStamp("/static/dist/svg/_bundle.svg")#arrow-right"></use></svg> <span>@Translate("DetailIcons", "Detail icons")</span> </button> <div class="product__details-item-placeholder"><div></div></div> </div> } @if (viewModel.FeatureList.Count > 0) { <div class="product__details-option"> <button> <svg aria-hidden="true"><use xlink:href="@staticResourceService.AddTimeStamp("/static/dist/svg/_bundle.svg")#arrow-right"></use></svg> <span>@Translate("FeatureList", "Feature list")</span> </button> <div class="product__details-item-placeholder"><div></div></div> </div> } @*optional extra tab*@ @if (viewModel.RelatedProductsCount > 0) { <div class="product__details-option only-desktop"> <button> <svg aria-hidden="true"><use xlink:href="@staticResourceService.AddTimeStamp("/static/dist/svg/_bundle.svg")#arrow-right"></use></svg> <span>@Translate("Related products", "Related products")</span> </button> <div class="product__details-item-placeholder"><div></div></div> </div> } @*end optional extra tab*@ </div> <div class="product__details-items"> @if (viewModel.DimensionImages.Count > 0) { <div class="product__details-item"> <div class="product__details-images"> <article> @foreach (var image in viewModel.DimensionImages) { <div class="lazy" data-src-xxs="@image.SetWidth(470).SetCrop(CropType.KeepAspectRatio).SetCompression(80).SetImageFormat(ImageFormat.Jpg).GetCrop()" alt="@viewModel.Name" data-src-sm="@image.SetWidth(348).SetCrop(CropType.KeepAspectRatio).SetCompression(80).SetImageFormat(ImageFormat.Jpg).GetCrop()" alt="@viewModel.Name" data-src-md="@image.SetWidth(287).SetCrop(CropType.KeepAspectRatio).SetCompression(80).SetImageFormat(ImageFormat.Jpg).GetCrop()" alt="@viewModel.Name" data-src-lg="@image.SetWidth(370).SetCrop(CropType.KeepAspectRatio).SetCompression(80).SetImageFormat(ImageFormat.Jpg).GetCrop()" alt="@viewModel.Name" data-gallery="@image.SetWidth(1230).SetCrop(CropType.KeepAspectRatio).SetCompression(80).SetImageFormat(ImageFormat.Jpg).GetCrop()" alt="@viewModel.Name"> </div> } </article> </div> </div> } @if (viewModel.Features.Count > 0 || viewModel.TemperatureImages.Count > 0) { <div class="product__details-item"> <div class="product__details-specifications"> <article> @if (viewModel.Features.Count > 0) { List<string> featureBlacklist = new List<string>(); foreach (var item in specBlackList.Split(',')) { featureBlacklist.Add(item.Trim()); } <dl> @foreach (LoopItem feature in GetLoop("CustomFieldValues")) { var systemName = feature.GetString("Product.CustomField.System"); var specName = feature.GetString("Product.CustomField.Name"); var specValue = feature.GetString("Product.CustomField.Value"); foreach (var featureBlacklistItem in featureBlacklist) { if (featureBlacklist.Any(_ => systemName.StartsWith(_, StringComparison.InvariantCultureIgnoreCase))) { continue; } if (!string.IsNullOrWhiteSpace(specValue) && !string.IsNullOrWhiteSpace(specName)) { <dt> @specName: @* <aside class="explanation" data-module="explanation"> <div class="explanation__icon"> <svg aria-hidden="true"><use xlink:href="@staticResourceService.AddTimeStamp("/static/dist/svg/_bundle.svg")#info-circle"></use></svg> </div> <div class="explanation__text"> <h1>Lorem ipsum dolor sit amet, consectetur adipisicing elit</h1> <p>Accusantium aliquid eaque eos eveniet impedit.</p> <p>In ipsa magnam mollitia nam necessitatibus nobis officia pariatur perferendis quam quasi quia totam. Illo, modi!</p> </div> </aside> *@ </dt> <dd>@specValue</dd> } break; } } @if (!string.IsNullOrWhiteSpace(@viewModel.ProductNumber)) { <dt> @Translate("ProductNumber", "Product Number"): </dt> <dd>@viewModel.ProductNumber</dd> } </dl> } @if (viewModel.TemperatureImages.Count > 0) { <ul class="temprature-images"> @foreach (var image in viewModel.TemperatureImages) { <li><img src="@image.SetWidth(200).SetCrop(CropType.KeepAspectRatio).SetCompression(80).GetCrop()" /></li> } </ul> } </article> </div> </div> } @if (!string.IsNullOrWhiteSpace(@viewModel.LongDescription)) { <div class="product__details-item"> <div class="product__details-description text"> <article> <div class="text__body"> <div class="text__body-left" itemprop="description"> @viewModel.LongDescription </div> </div> </article> </div> </div> } @if (!string.IsNullOrWhiteSpace(@viewModel.CareText) || !string.IsNullOrWhiteSpace(@viewModel.CareVideoUrl) || !string.IsNullOrWhiteSpace(@viewModel.CareVideo) || !string.IsNullOrWhiteSpace(@viewModel.CareFile) || !string.IsNullOrWhiteSpace(@viewModel.CareFileDescription) || !string.IsNullOrWhiteSpace(@viewModel.Image082) ) { <div class="product__details-item"> <div class="product__details-maintenance"> <article> @if (!string.IsNullOrWhiteSpace(@viewModel.CareText)) { <div class="text__body">@viewModel.CareText</div> } @if (!string.IsNullOrWhiteSpace(@viewModel.CareVideo)) { <div class="margin-top-10px"> <div class="video-container"> <iframe src="@viewModel.CareVideo?rel=0&amp;showinfo=0&amp;controls=0" frameborder="0" allowfullscreen></iframe> </div> </div> } @if (!string.IsNullOrWhiteSpace(@viewModel.CareVideoUrl)) { <div class="margin-top-10px"> <div class="video-container"> <iframe src="@viewModel.CareVideoUrl?rel=0&amp;showinfo=0&amp;controls=0" frameborder="0" allowfullscreen></iframe> </div> </div> } <div> <ul> @if (!string.IsNullOrWhiteSpace(@viewModel.CareFile)) { <li> <a href="@viewModel.CareFile" target="_blank"> <svg aria-hidden="true"> <use xlink:href="@staticResourceService.AddTimeStamp("/static/dist/svg/_bundle.svg")#file-pdf"></use> </svg> @(string.IsNullOrWhiteSpace(viewModel.CareFileDescription) ? Translate("CareFileText", "Care label - PDF") : viewModel.CareFileDescription) </a> </li> } @if (!string.IsNullOrWhiteSpace(@viewModel.Image082)) { <li> <a href="@viewModel.Image082" target="_blank"> <svg aria-hidden="true"> <use xlink:href="@staticResourceService.AddTimeStamp("/static/dist/svg/_bundle.svg")#file-pdf"></use> </svg> @(string.IsNullOrWhiteSpace(viewModel.CareFileDescription) ? Translate("CareFileText", "Care label - PDF") : viewModel.CareFileDescription) </a> </li> } </ul> </div> </article> </div> </div> } @if (viewModel.PitchingImages.Count > 0 || !string.IsNullOrWhiteSpace(@viewModel.PitchingVideo) || !string.IsNullOrWhiteSpace(@viewModel.PitchingVideo2) || !string.IsNullOrWhiteSpace(@viewModel.PitchingVideo3)) { <div class="product__details-item"> <div class="product__details-maintenance"> <article> @if (!string.IsNullOrWhiteSpace(@viewModel.PitchingVideo)) { <div> <div class="video-container"> <iframe src="@viewModel.PitchingVideo?rel=0&amp;showinfo=0&amp;controls=0" frameborder="0" allowfullscreen></iframe> </div> </div> } @if (!string.IsNullOrWhiteSpace(@viewModel.PitchingVideo2)) { <div class="margin-top-10px"> <div class="video-container"> <iframe src="@viewModel.PitchingVideo2?rel=0&amp;showinfo=0&amp;controls=0" frameborder="0" allowfullscreen></iframe> </div> </div> } @if (!string.IsNullOrWhiteSpace(@viewModel.PitchingVideo3)) { <div class="margin-top-10px"> <div class="video-container"> <iframe src="@viewModel.PitchingVideo3?rel=0&amp;showinfo=0&amp;controls=0" frameborder="0" allowfullscreen></iframe> </div> </div> } <div> <ul> @if (viewModel.PitchingImages.Count > 0) { foreach (var image in viewModel.PitchingImages) { <li> <a href="@image" target="_blank"> <svg aria-hidden="true"> <use xlink:href="@staticResourceService.AddTimeStamp("/static/dist/svg/_bundle.svg")#file-pdf"></use> </svg>@Translate("PitchingFileText", "Pitching Instruction - PDF") </a> </li> } } </ul> </div> </article> </div> </div> } @if (viewModel.Icons.Count > 0) { <div class="product__details-item"> <div class="product__details-icons"> <article> @foreach (var icon in viewModel.Icons) { <section> <header> <div> <img src="@icon.Image.SetWidth(60).SetHeight(60).SetCrop(CropType.KeepAspectRatio).SetCompression(80).GetCrop()" alt=""> </div> <span class="h-1">@icon.Headline</span> </header> @icon.BodyText </section> } </article> </div> </div> } @if (viewModel.FeatureList.Count > 0) { <div class="product__details-item"> <div class="product__details-points"> <article> @foreach (var featureText in viewModel.FeatureList) { <section> <div><svg aria-hidden="true"><use xlink:href="@staticResourceService.AddTimeStamp("/static/dist/svg/_bundle.svg")#checkmark"></use></svg></div> @featureText </section> } </article> </div> </div> } @*optional extra tab*@ @if (viewModel.RelatedProductsCount > 0) { <div class="product__details-item only-desktop"> <div class="product__details-points related-item-tab"> <article> @{int count = 0;} @foreach (var item in viewModel.RelatedProducts) { if (count > 10) { break; } var relatedProduct = viewModelService.GetViewModel(item); <div class="product-item product-item-tab"> <a href="@urlService.GetUrl(relatedProduct.GroupId, relatedProduct.Id)"> <div class="product-item__header"> <figure> <img src="@relatedProduct.MainImage.SetWidth(200).SetHeight(120).SetCrop(CropType.KeepAspectRatio).SetCompression(50).GetCrop()" content="@relatedProduct.MainImage" alt="@relatedProduct.Name"> </figure> @if (!string.IsNullOrEmpty(relatedProduct.OutletcampingSplash) && !string.IsNullOrEmpty(relatedProduct.OutletcampingSplashColor)) { var splashTexts = relatedProduct.OutletcampingSplash.Split(' '); <div class="product-item__splash" style="background: @relatedProduct.OutletcampingSplashColor;"> <div class="product-item__splash-text"> <p> @for (var i = 0; i <= splashTexts.Length - 1; i++) { if (i == 1) { <span class="product-item__splash-text--bold"> @splashTexts[i]</span> } else { @splashTexts[i] } } </p> </div> </div> } </div> <div class="product-item__body"> @{ if (relatedProduct.PeriodEndDate >= DateTime.Now && relatedProduct.PeriodEndDate <= DateTime.Now.AddDays(14)) { <div data-module="countdown"> <div class="product-item__countdown" data-date="@relatedProduct.PeriodEndDate.ToString("MM/dd/yyyy HH:mm:ss")"> <div class="product-item__countdown-title">@Translate("Offer ends in")</div> <div class="product-item__countdown-counter"></div> <div class="product-item__countdown-text"> <span>@Translate("Hours", "Hours")</span> <span>@Translate("Min", "Min")</span> <span>@Translate("Sec", "Sec")</span> </div> </div> </div> } } <div class="product-item__headline"> @if (!string.IsNullOrEmpty(relatedProduct.Name)) { <h4>@relatedProduct.Name</h4> } </div> <div class="product-item__price"> <div class="price"><span content="@relatedProduct.Currency">@relatedProduct.CurrencySymbol</span> <span content="@relatedProduct.UnformatedPrice">@relatedProduct.Price</span></div> @if (!string.IsNullOrEmpty(@relatedProduct.BeforePrice)) { <div class="if-discount"> <span>@Translate("Before", "Used to be") @relatedProduct.CurrencySymbol @relatedProduct.BeforePrice</span> </div> } </div> <div class="product-item__button"> <span class="btn"> <span class="btn__icon"> <img src="@staticResourceService.AddTimeStamp("/static/dist/media/cart-white-outletcamping.png")"> </span> <span class="btn__text">@Translate("SeeMore", "See more")</span> </span> </div> </div> </a> </div> count++; } </article> </div> </div> } @*end optional extra tab*@ </div> </div> </section> <dl class="product__bullet-points product__bullet-points--mobile"> <dt><div class="product__bullet-points-image"><img src="@staticResourceService.AddTimeStamp("/static/dist/media/customer-service-outletcamping.png")"></div>@Translate("NeedHelp", "Need help?")</dt> <dd><a href="@viewModel.CustomerServiceLink">@viewModel.CustomerServiceLinkTitle</a></dd> <dt><div class="product__bullet-points-image"><img src="@staticResourceService.AddTimeStamp("/static/dist/media/delivery-outletcamping.png")"></div>@Translate("VP2Title", "Need help?")</dt> <dd> @if (!Translate("VP2Link").Equals("VP2Link")) { <a href="@Translate("VP2Link")">@Translate("VP2SubTitle", "Contact our customer service")</a> } else { @Translate("VP2SubTitle", "Contact our customer service") } <div data-module="bootstrap-modal"> <div class="bootstrap-modal__container" data-id="ProductDeliveryModal"> <div class="bootstrap-modal__text">@Translate("ProductDeliveryFrom", "Levering fra kr. 39,-")</div> <div class="bootstrap-modal__text"><a href="javascript:void(0);" class="bootstrap-modal__open">@Translate("ProductDeliverySeeMore", "Se mere om levering")</a></div> </div> </div> </dd> </dl> </article> <div class="container"> @if (viewModel.RelatedProductsCount > 0) { <section class="featured-products featured-products-related container-ribbon ribbon" data-module="featured-products"> <div class="container"> <h3>@Translate("Related products", "Related products")</h3> <div class="featured-products__container"> @foreach (var item in viewModel.RelatedProducts) { var relatedProduct = viewModelService.GetViewModel(item); <article class="product-item"> <a href="@urlService.GetUrl(relatedProduct.GroupId, relatedProduct.Id)"> <div class="product-item__header"> <figure> <img src="@relatedProduct.MainImage.SetWidth(500).SetHeight(300).SetCrop(CropType.KeepAspectRatio).SetCompression(50).GetCrop()" content="@relatedProduct.MainImage" alt="@relatedProduct.Name"> </figure> @if (!string.IsNullOrEmpty(relatedProduct.OutletcampingSplash) && !string.IsNullOrEmpty(relatedProduct.OutletcampingSplashColor)) { var splashTexts = relatedProduct.OutletcampingSplash.Split(' '); <div class="product-item__splash" style="background: @relatedProduct.OutletcampingSplashColor;"> <div class="product-item__splash-text"> <p> @for (var i = 0; i <= splashTexts.Length - 1; i++) { if (i == 1) { <span class="product-item__splash-text--bold"> @splashTexts[i]</span> } else { @splashTexts[i] } } </p> </div> </div> } </div> <div class="product-item__body"> @{ if (relatedProduct.PeriodEndDate >= DateTime.Now && relatedProduct.PeriodEndDate <= DateTime.Now.AddDays(14)) { <div data-module="countdown"> <div class="product-item__countdown" data-date="@relatedProduct.PeriodEndDate.ToString("MM/dd/yyyy HH:mm:ss")"> <div class="product-item__countdown-title">@Translate("Offer ends in")</div> <div class="product-item__countdown-counter"></div> <div class="product-item__countdown-text"> <span>@Translate("Hours", "Hours")</span> <span>@Translate("Min", "Min")</span> <span>@Translate("Sec", "Sec")</span> </div> </div> </div> } } <div class="product-item__headline"> @if (!string.IsNullOrEmpty(relatedProduct.Name)) { <h4>@relatedProduct.Name</h4> } </div> <div class="product-item__price"> @if (!string.IsNullOrEmpty(@relatedProduct.Savepct)) { <div class="save"> <span>@Translate("Save", "Save") @relatedProduct.Savepct%</span> </div> } <div class="price"><span content="@relatedProduct.Currency">@relatedProduct.CurrencySymbol</span> <span content="@relatedProduct.UnformatedPrice">@relatedProduct.Price</span></div> @if (!string.IsNullOrEmpty(@relatedProduct.BeforePrice)) { <div class="if-discount"> <span>@Translate("Before", "Used to be") @relatedProduct.CurrencySymbol @relatedProduct.BeforePrice</span> </div> } </div> <div class="product-item__button"> <span class="btn"> <span class="btn__icon"> <img src="@staticResourceService.AddTimeStamp("/static/dist/media/cart-white-outletcamping.png")"> </span> <span class="btn__text">@Translate("SeeMore", "See more")</span> </span> </div> </div> </a> </article> } </div> </div> </section> } </div> @{ // also bought products var alsoBoughtProducts = new List<Product>(); var alsoBoughtEcomLanguageId = area.EcomLanguageId; var alsoBoughtEcomShopId = area.EcomShopId; var alsoBoughtProductService = new ProductService(); var alsoBoughtFeedUrl = "https://dino.outwell.com/dino/oc/alsobought/" + viewModel.ProductNumber + "?return=12"; if (!string.IsNullOrEmpty(alsoBoughtFeedUrl)) { try { var url = urlParserService.FormatRaptorUrl(alsoBoughtFeedUrl); var data = (new WebClient()).DownloadString(url); JavaScriptSerializer raptorJson = new JavaScriptSerializer(); var alsoBoughtJsonProducts = raptorJson.Deserialize<ArrayList>(data); var alsoBoughtProductNumbers = new List<string>(); if (alsoBoughtJsonProducts.Count > 0) { foreach (Dictionary<string, object> alsoBoughtProductNumber in alsoBoughtJsonProducts) { string pId = "0"; if (alsoBoughtProductNumber.ContainsKey("ProductID")) { pId = alsoBoughtProductNumber["ProductID"].ToString(); } else if (alsoBoughtProductNumber.ContainsKey("RecommendedId")) { pId = alsoBoughtProductNumber["RecommendedId"].ToString(); } alsoBoughtProductNumbers.Add(pId); } if (alsoBoughtProductNumbers.Count > 0) { var alsoBoughtProductIds = new List<string>(); var alsoBoughtProductsCB = CommandBuilder.Create("SELECT ProductId FROM EcomProducts WHERE ProductNumber IN ('" + string.Join("','", alsoBoughtProductNumbers) + "') AND ProductLanguageId = {0} AND ProductDefaultShopId = {1}", alsoBoughtEcomLanguageId, alsoBoughtEcomShopId ); using (var reader = Database.CreateDataReader(alsoBoughtProductsCB)) { while (reader.Read()) { alsoBoughtProductIds.Add(reader["ProductId"].ToString()); } reader.Close(); reader.Dispose(); } if (alsoBoughtProductIds.Count > 0) { var alsoBoughtDwProducts = alsoBoughtProductService.GetByProductIDs(alsoBoughtProductIds.ToArray(), false, alsoBoughtEcomLanguageId, false, false); if (alsoBoughtDwProducts != null) { foreach (var alsoBoughtProductNumber in alsoBoughtProductNumbers) { var alsoBoughtFoundProduct = alsoBoughtDwProducts.Where(x => x.Number == alsoBoughtProductNumber).FirstOrDefault(); if (alsoBoughtFoundProduct != null) { alsoBoughtProducts.Add(alsoBoughtFoundProduct); } } } } } } } catch (Exception ex) { } } if (alsoBoughtProducts.Count > 0) { <div class="container"> <section class="featured-products featured-products-related container-ribbon ribbon" data-module="featured-products"> <div class="container"> <h3>@Translate("Also bought products", "Also bought products")</h3> <div class="featured-products__container"> @foreach (var item in alsoBoughtProducts) { var relatedProduct = viewModelService.GetViewModel(item); <article class="product-item"> <a href="@urlService.GetUrl(relatedProduct.GroupId, relatedProduct.Id)"> <div class="product-item__header"> <figure> <img src="@relatedProduct.MainImage.SetWidth(500).SetHeight(300).SetCrop(CropType.KeepAspectRatio).SetCompression(50).GetCrop()" content="@relatedProduct.MainImage" alt="@relatedProduct.Name"> </figure> @if (!string.IsNullOrEmpty(relatedProduct.OutletcampingSplash) && !string.IsNullOrEmpty(relatedProduct.OutletcampingSplashColor)) { var splashTexts = relatedProduct.OutletcampingSplash.Split(' '); <div class="product-item__splash" style="background: @relatedProduct.OutletcampingSplashColor;"> <div class="product-item__splash-text"> <p> @for (var i = 0; i <= splashTexts.Length - 1; i++) { if (i == 1) { <span class="product-item__splash-text--bold"> @splashTexts[i]</span> } else { @splashTexts[i] } } </p> </div> </div> } </div> <div class="product-item__body"> @{ if (relatedProduct.PeriodEndDate >= DateTime.Now && relatedProduct.PeriodEndDate <= DateTime.Now.AddDays(14)) { <div data-module="countdown"> <div class="product-item__countdown" data-date="@relatedProduct.PeriodEndDate.ToString("MM/dd/yyyy HH:mm:ss")"> <div class="product-item__countdown-title">@Translate("Offer ends in")</div> <div class="product-item__countdown-counter"></div> <div class="product-item__countdown-text"> <span>@Translate("Hours", "Hours")</span> <span>@Translate("Min", "Min")</span> <span>@Translate("Sec", "Sec")</span> </div> </div> </div> } } <div class="product-item__headline"> @if (!string.IsNullOrEmpty(relatedProduct.Name)) { <h4>@relatedProduct.Name</h4> } </div> <div class="product-item__price"> @if (!string.IsNullOrEmpty(@relatedProduct.Savepct)) { <div class="save"> <span>@Translate("Save", "Save") @relatedProduct.Savepct%</span> </div> } <div class="price"><span content="@relatedProduct.Currency">@relatedProduct.CurrencySymbol</span> <span content="@relatedProduct.UnformatedPrice">@relatedProduct.Price</span></div> @if (!string.IsNullOrEmpty(@relatedProduct.BeforePrice)) { <div class="if-discount"> <span>@Translate("Before", "Used to be") @relatedProduct.CurrencySymbol @relatedProduct.BeforePrice</span> </div> } </div> <div class="product-item__button"> <span class="btn"> <span class="btn__icon"> <img src="@staticResourceService.AddTimeStamp("/static/dist/media/cart-white-outletcamping.png")"> </span> <span class="btn__text">@Translate("SeeMore", "See more")</span> </span> </div> </div> </a> </article> } </div> </div> </section> </div> } } </section> @foreach (var paragraphId in viewModel.RibbonIds) { @RenderParagraphContent(paragraphId) } @* FOR DEBUGGING ONLY @foreach (var fieldValue in viewModel.ProductFieldValues) { <div>@fieldValue.ProductField.Name<text>: </text>@fieldValue.Value.ToString()</div> } *@ </section> @SnippetStart("jarvis") @{ var settingsRaptorApiKey = PageView.Current().Area.Item["SettingsRaptorApiKey"]; } @if (settingsRaptorApiKey != null) { if (PageView.Current().Device == Dynamicweb.Frontend.Devices.DeviceType.Desktop && !string.IsNullOrEmpty(settingsRaptorApiKey.ToString())) { var jarvis = (HttpContext.Current.Request.Cookies["jarvis"] != null) ? HttpContext.Current.Request.Cookies["jarvis"].Value : "1"; var jarvisBoxStatus = (jarvis == "1") ? "jarvis--open" : string.Empty; var jarvisBtnStatus = (jarvis == "1") ? "" : "jarvis-btn--open"; var raptorAreaId = area.ID; var raptorBrandId = (area.Item["SettingsRaptorUserId"] != null) ? area.Item["SettingsRaptorUserId"].ToString() : string.Empty; var raptorCookieId = (HttpContext.Current.Request.Cookies[raptorBrandId + "rsa"] != null) ? HttpContext.Current.Request.Cookies[raptorBrandId + "rsa"].Value : ""; var raptorContent1 = GetJarvisContent("GetCookieHistory", "", area); var raptorContent2 = GetJarvisContent("GetSimilarItems", viewModel.ProductNumber, area); var settingsShopId = area.Item["SettingsShopId"].ToString(); var ecomPageId = urlParserService.GetPageId(settingsShopId); if (!string.IsNullOrEmpty(raptorCookieId)) { <div data-module="jarvis"> <div class="jarvis @jarvisBoxStatus"> <div class="jarvis__header"> <span class="your">@Translate("Your", "Your")</span> <span class="guide">@Translate("Guide", "Guide")</span> <span class="logo"></span> </div> <div class="jarvis__guide"> <button class="jarvis__close"><span class="round"><svg viewBox="0 0 100 100"><path d="M 10,50 L 60,100 L 70,90 L 30,50 L 70,10 L 60,0 Z" class="arrow"></path></svg></span> @Translate("Hide the wizard", "Hide the wizard")</button> <div class="jarvis__text"> <p> @Translate("The guide follows you around and finds new recommendations based on what you're looking at.", "The guide follows you around and finds new recommendations based on what you're looking at.") </p> </div> </div> <div class="jarvis__alternatives"> <section class="featured-products container-ribbon ribbon"> <h3>@Translate("Similar items", "Similar items")</h3> <div class="featured-products__container" data-url="/webservices/jarvis.ashx?areaId=@raptorAreaId&raptorFunction=GetSimilarItems&raptorProductId=@productNumber"> @foreach (var raptorProduct in raptorContent2) { var raptorProductView = viewModelService.GetViewModel(raptorProduct); if (raptorProductView.MainImage != null) { raptorProductView.RaptorImage = raptorProductView.MainImage.SetWidth(500).SetHeight(300).SetCrop(CropType.KeepAspectRatio).SetCompression(50).GetCrop(); } raptorProductView.RaptorUrl = urlService.GetUrl(raptorProductView.GroupId, raptorProductView.Id, ecomPageId.GetValueOrDefault()); <article class="product-item"> <a href="@raptorProductView.RaptorUrl"> <div class="product-item__header"> <figure> <img src="@raptorProductView.RaptorImage" content="OaseOutdoors.Services.ImageService.ImageService" alt="@raptorProductView.Name"> </figure> </div> <div class="product-item__body"> <div class="product-item__headline"> <h3 class="h-1">@raptorProductView.Name</h3> </div> <div class="product-item__price"> <div class="price"><span content="@raptorProductView.Currency">@raptorProductView.CurrencySymbol</span> <span content="@raptorProductView.UnformatedPrice">@raptorProductView.Price</span></div> </div> </div> </a> </article> } </div> </section> </div> <div class="jarvis__suggest"> <section class="featured-products container-ribbon ribbon"> <h3>@Translate("You have previously looked at", "You have previously looked at")</h3> <div class="featured-products__container" data-url="/webservices/jarvis.ashx?areaId=@raptorAreaId&raptorFunction=GetCookieHistory"> @foreach (var raptorProduct in raptorContent1) { var raptorProductView = viewModelService.GetViewModel(raptorProduct); if (raptorProductView.MainImage != null) { raptorProductView.RaptorImage = raptorProductView.MainImage.SetWidth(500).SetHeight(300).SetCrop(CropType.KeepAspectRatio).SetCompression(50).GetCrop(); } raptorProductView.RaptorUrl = urlService.GetUrl(raptorProductView.GroupId, raptorProductView.Id, ecomPageId.GetValueOrDefault()); <article class="product-item"> <a href="@raptorProductView.RaptorUrl"> <div class="product-item__header"> <figure> <img src="@raptorProductView.RaptorImage" content="OaseOutdoors.Services.ImageService.ImageService" alt="@raptorProductView.Name"> </figure> </div> <div class="product-item__body"> <div class="product-item__headline"> <h3 class="h-1">@raptorProductView.Name</h3> </div> <div itemscope itemtype="https://schema.org/Offer" class="product-item__price"> <div class="price"><span content="@raptorProductView.Currency">@raptorProductView.CurrencySymbol</span> <span content="@raptorProductView.UnformatedPrice">@raptorProductView.Price</span></div> </div> </div> </a> </article> } </div> </section> </div> </div> <div class="jarvis-btn @jarvisBtnStatus"> <img src="/static/dist/img/jarvis/jarvis-small.png"> </div> </div> } } } @SnippetEnd("jarvis") <!-- Google Tracking Code --> @if (headStaticResourceService.IsProduction) { var googleEcommerceId = Pageview.Area.Item["SettingsGoogleEcommerceId"]; var googleProductIds = viewModel.Id; <script> if(typeof gtag !== 'undefined') { gtag('event', 'page_view', { 'send_to': '@googleEcommerceId', 'ecomm_pagetype': 'product', 'ecomm_prodid': '@googleProductIds', 'ecomm_totalvalue': '@viewModel.UnformatedPrice' }); gtag('event', 'view_item', { "items": [ { 'id': '@viewModel.Id', 'name': '@viewModel.Name', 'brand': '@GetString("Ecom:Product:Field.BrandName")', 'quantity': 1, 'price': '@viewModel.UnformatedPrice' } ] }); } </script> } <!-- Google Tracking Code Ends --> <!-- Facebook Tracking Code --> @if (headStaticResourceService.IsProduction) { <script> if (typeof fbq !== 'undefined') { fbq('track', 'ViewContent', { content_name: '@viewModel.Name', content_ids: ['@viewModel.ProductNumber'], content_type: 'product', value: @viewModel.UnformatedPrice, currency: '@viewModel.Currency', contents: [ { id: '@viewModel.ProductNumber', quantity: 1, item_price: @viewModel.UnformatedPrice } ] }); } </script> } <!-- Facebook Tracking Code --> @functions { private List<Product> GetJarvisContent(string function = "", string productId = "", Area area = null) { List<Product> raptorProductsCollection = new List<Product>(); var context = HttpContext.Current; var raptorBrandId = (area.Item["SettingsRaptorUserId"] != null) ? area.Item["SettingsRaptorUserId"].ToString() : string.Empty; var raptorApiKey = area.Item["SettingsRaptorApiKey"]; var raptorCookie = context.Request.Cookies[raptorBrandId + "rsa"]; if (raptorCookie != null && raptorApiKey != null) { if (!string.IsNullOrEmpty(raptorCookie.Value) && !string.IsNullOrEmpty(raptorApiKey.ToString())) { var raptorCookieId = raptorCookie.Value; var raptorFunction = function; var raptorProductId = (!string.IsNullOrEmpty(productId)) ? "&ProductId=" + productId : ""; var raptorUrl = ""; var raptorNumberOfItems = 12; var raptorMinPrice = 0; switch (raptorFunction) { case "GetSimilarItems": raptorUrl = "https://api.raptorsmartadvisor.com/v1/" + raptorBrandId + "/GetSimilarItems/" + raptorNumberOfItems + "/" + raptorApiKey + "?CookieId=" + raptorCookieId + raptorProductId; break; default: raptorUrl = "https://api.raptorsmartadvisor.com/v1/" + raptorBrandId + "/GetCookieHistory/" + raptorNumberOfItems + "/" + raptorApiKey + "?UserIdentifier=" + raptorCookieId + raptorProductId; break; } if (!string.IsNullOrEmpty(raptorUrl)) { try { var raptorData = (new WebClient()).DownloadString(raptorUrl); JavaScriptSerializer raptorJson = new JavaScriptSerializer(); List<string> raptorProductsList = new List<string>(); var raptorJsonProducts = raptorJson.Deserialize<ArrayList>(raptorData); if (raptorJsonProducts.Count > 0) { var n = 1; List<string> raptorJsonProductsList = new List<string>(); foreach (Dictionary<string, object> raptorJsonProduct in raptorJsonProducts) { var typeId = "ProductId"; if (raptorJsonProduct.ContainsKey("RecommendedId")) { typeId = "RecommendedId"; } raptorJsonProductsList.Add(raptorJsonProduct[typeId].ToString()); } var raptorProducts = Product.GetProductsBySql(string.Format("SELECT * FROM EcomProducts WHERE ProductNumber in ({0}) AND ProductLanguageId = '{1}' AND ProductActive = 'True'", string.Join(",", raptorJsonProductsList), area.EcomLanguageId)); foreach (var raptorProductNumber in raptorJsonProductsList) { var raptorProduct = raptorProducts.FirstOrDefault(x => x.Number == raptorProductNumber); if (raptorProduct != null) { if (n <= raptorNumberOfItems && raptorProduct.Price.Price >= raptorMinPrice && raptorProduct.DefaultGroup != null && (raptorProduct.Stock > 0 && raptorFunction != "GetCookieHistory" || raptorFunction == "GetCookieHistory")) { raptorProductsCollection.Add(raptorProduct); n++; } } } } } catch { } } } } return raptorProductsCollection; } }