MENU
0
Exception in template (Designs\EasyCamp\eCom/Product/Product.cshtml): System.Data.SqlClient.SqlException (0x80131904): Execution Timeout Expired.  The timeout period elapsed prior to completion of the operation or the server is not responding. ---> System.ComponentModel.Win32Exception (0x80004005): The wait operation timed out
   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 Dynamicweb.Data.Database.CreateDataReader(IDbCommand command, CommandBehavior behavior)
   at Dynamicweb.Data.Database.CreateDataReader(String sql, IDbConnection connection, IDbTransaction transaction, CommandBehavior behavior, Int32 commandTimeout, Dictionary`2 sqlParams)
   at Dynamicweb.Data.Database.CreateDataReader(String sql, IDbConnection connection, IDbTransaction transaction, Int32 commandTimeout, Dictionary`2 sqlParams)
   at Dynamicweb.Security.UserManagement.User.GetUsersBySql(String sqlCommandText)
   at OaseOutdoors.Components.Shared.Modules.Ecom.ModelBuilders.ProductViewModelBuilder.GetViewModel(Product entity) in C:\projects\oase\src\Components\Shared\Modules\eCom\ModelBuilders\ProductViewModelBuilder.cs:line 438
   at CompiledRazorTemplates.Dynamic.eedfbbbdfadb.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()
ClientConnectionId:650641f1-506c-4dd7-9c57-1c0159bbef54
Error Number:-2,State:0,Class:11
@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() : ""; PageService pageService = new PageService(); var frontpage = pageService.GetFirstPageForArea(area.ID); //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 == 17) { hrefLang.Href = "https://www.easycamp.com/da-dk"; } if (hrefLang.HrefAreaId == 18) { hrefLang.Href = "https://www.easycamp.com/de-de"; } if (hrefLang.HrefAreaId == 19) { hrefLang.Href = "https://www.easycamp.com/fr-fr"; } if (hrefLang.HrefAreaId == 21) { hrefLang.Href = "https://www.easycamp.com/nl-nl"; } if (hrefLang.HrefAreaId == 20) { hrefLang.Href = "https://www.easycamp.com/sv-se"; } if (hrefLang.HrefAreaId == 30) { hrefLang.Href = "https://www.easycamp.com/en-gb-1"; } if (hrefLang.HrefAreaId == 16) { hrefLang.Href = "https://www.easycamp.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")#easycamp-arrow-right"></use> </svg> <span>@hrefLang.HrefName</span> </a> </li> } } </ul> @SnippetEnd("languageSelector") @SnippetStart("languageDropdownSelector") <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 != null && hrefLang.HrefLang != "x-default" && hrefLang.HrefAreaId != Pageview.AreaID) { <li class="country-picker__item @(hrefLang.HrefAreaId == Pageview.AreaID ? "country-picker__item--current" : string.Empty)"> <a href="@hrefLang.Href"> <span class="service-menu__language-flag"><svg aria-hidden="true"><use xlink:href="@staticResourceService.AddTimeStamp("/static/dist/svg/_bundle.svg")#flag-@hrefLang.HrefLang.Split('-')[0]"></use></svg></span> <span class="service-menu__language-list-text">@hrefLang.HrefName</span> </a> </li> } } </ul> @SnippetEnd("languageDropdownSelector") <section class="content content--breadcrumb container-ribbon"> <div class="container"> <ol class="breadcrumb breadcrumb--product" itemscope itemtype="http://schema.org/BreadcrumbList"> @if (HttpContext.Current.Request.UrlReferrer != null && HttpContext.Current.Request.UrlReferrer.Host.Contains("easycamp")) { <li class="breadcrumb__item" itemprop="itemListElement" itemscope itemtype="http://schema.org/ListItem"> @if (breadCrumbIndex == 1) { @* The second to last breadcrumb item is the only one visible on mobile devices and thus the only one with this SVG *@ <a href="javascript:window.history.back(-1);" class="breadcrumb__item-back"><svg aria-hidden="true"><use xlink:href="@staticResourceService.AddTimeStamp("/static/dist/svg/_bundle.svg")#arrow-left"></use></svg></a> } </li> } <li class="breadcrumb__item breadcrumb__item--link" itemprop="itemListElement" itemscope itemtype="http://schema.org/ListItem"> <a href="/Default.aspx?ID=@frontpage.ID" class="breadcrumb__item-link" itemprop="item"> <span itemprop="name"> @Translate("Home", "Home") </span> </a> <meta itemprop="position" content="0"> </li> @foreach (var item in viewModel.Breadcrumb) { <li class="breadcrumb__item breadcrumb__item--link @(item == viewModel.Breadcrumb.LastOrDefault() ? "breadcrumb__item--current" : "")" itemprop="itemListElement" itemscope itemtype="http://schema.org/ListItem"> @if (item == viewModel.Breadcrumb.LastOrDefault()) { <a class="breadcrumb__item-link" itemprop="item"> <span itemprop="name"> @item.LinkTitle </span> </a> } else { <a class="breadcrumb__item-link" itemprop="item" href="@item.Link"> <span itemprop="name"> @item.LinkTitle </span> </a> } <meta itemprop="position" content="@breadCrumbIndex"> </li> breadCrumbIndex++; } </ol> </div> </section> <section class="content content--body product-content"> <section class="container-fluid"> <article class="container product" itemscope itemtype="http://schema.org/Product" data-module="product"> <div class="mobile-slider"> @if (!string.IsNullOrEmpty(viewModel.OutletcampingSplash)) { var statustext = viewModel.OutletcampingSplash; if (statustext.Length > 4) { <div class="product-item__status4"> <span>@statustext</span> </div> } if (statustext.Length < 5) { <div class="product-item__status3"> <span>@statustext</span> </div> } } @if (!string.IsNullOrWhiteSpace(viewModel.LabelText)) { <div class="product__label"> <p>@viewModel.LabelText</p> </div> } <div class="MagicSlideshow video-container" data-options="selectors: bottom; bulletsPreview: none; caption: false;"> <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 (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> </div> <div class="product__essentials"> <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="Easycamp @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 (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="Easycamp @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="Easycamp @viewModel.Name" data-src-sm="@viewModel.MainImage.SetHeight(640).SetCrop(CropType.KeepAspectRatio).SetCompression(80).SetImageFormat(ImageFormat.Jpg).GetCrop()" alt="Easycamp @viewModel.Name" data-src-md="@viewModel.MainImage.SetWidth(630).SetCrop(CropType.KeepAspectRatio).SetCompression(80).SetImageFormat(ImageFormat.Jpg).GetCrop()" alt="Easycamp @viewModel.Name" data-src-lg="@viewModel.MainImage.SetWidth(728).SetCrop(CropType.KeepAspectRatio).SetCompression(80).SetImageFormat(ImageFormat.Jpg).GetCrop()" alt="Easycamp @viewModel.Name" data-gallery="@viewModel.MainImage.SetWidth(1230).SetCrop(CropType.KeepAspectRatio).SetCompression(80).SetImageFormat(ImageFormat.Jpg).GetCrop()" alt="Easycamp @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 (viewModel.ProductVideos.Count > 0) { foreach (var productVideo in viewModel.ProductVideos) { var ProductVideoURL = @productVideo.VideoID + ".mp4"; <div class="video-container" style="padding-top:0px;"> <video preload="meta" controls playsinline muted loop width='90%' src='/Files/Images/Productvideos/@ProductVideoURL' type='video/mp4'></video> </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="Easycamp @viewModel.Name" data-src-sm="@image.SetHeight(640).SetCrop(CropType.KeepAspectRatio).SetCompression(80).SetImageFormat(ImageFormat.Jpg).GetCrop()" alt="Easycamp @viewModel.Name" data-src-md="@image.SetWidth(630).SetCrop(CropType.KeepAspectRatio).SetCompression(80).SetImageFormat(ImageFormat.Jpg).GetCrop()" alt="Easycamp @viewModel.Name" data-src-lg="@image.SetWidth(728).SetCrop(CropType.KeepAspectRatio).SetCompression(80).SetImageFormat(ImageFormat.Jpg).GetCrop()" alt="Easycamp @viewModel.Name" data-gallery="@image.SetWidth(1230).SetCrop(CropType.KeepAspectRatio).SetCompression(80).SetImageFormat(ImageFormat.Jpg).GetCrop()" alt="Easycamp @viewModel.Name"> </div> } } </div> @if (!string.IsNullOrEmpty(viewModel.OutletcampingSplash)) { var statustext = viewModel.OutletcampingSplash; if (statustext.Length > 4) { <div class="product-item__statusslider"> <div class="product-item__status"> <span>@statustext</span> </div> </div> } if (statustext.Length < 5) { <div class="product-item__statusslider"> <div class="product-item__status2"> <span>@statustext</span> </div> </div> } } @if (!string.IsNullOrEmpty(viewModel.Award001)) { <div class="product_splash_award"> <img src="@viewModel.Award001" alt=""> </div> } @if (viewModel.Image090 != null) { <div class="product__splash-image"> <img src="@viewModel.Image090.SetWidth(200).SetCrop(CropType.KeepAspectRatio).SetCompression(80).GetCrop()" alt=""> </div> } @if (!string.IsNullOrWhiteSpace(viewModel.LabelText)) { <div class="product__label"> <p>@viewModel.LabelText</p> </div> } </div> <div class="product__info"> <div class="product__info-top"> <div class="product__info__shipping"> @if (@PageView.Current().AreaID == 30) { <div>@Translate("FreeShippingEU", "Free shipping")</div> } else { <div>@Translate("FreeShipping", "Free shipping")</div> } <div class="shipping-time">@Translate("ShippingTime", "Ships within 3-5 days")</div> <div class="shipping-time-underline"></div> </div> <link itemprop="brand" content="Easy camp" /> <link itemprop="image" href="@viewModel.MainImage.SetHeight(600).SetCrop(CropType.KeepAspectRatio).SetCompression(80).GetCrop()" /> <div class="product__price" itemprop="offers" itemscope itemtype="http://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 ? "http://schema.org/InStock" : "http://schema.org/OutOfStock")"> <link itemprop="url" href="@Pageview.SearchFriendlyUrl" /> @if (!string.IsNullOrWhiteSpace(viewModel.EnergyArrow)) { <div class="energyarrow" data-module="energyarrow"> <img src="@viewModel.EnergyArrow" class="@(viewModel.Image079 != null ? "energyarrow__show" : "")" alt="Energy"> <div class="energyarrow__info"> <div class="energyarrow__info__close">x</div> @if (viewModel.Image079 != null) { <img src="@viewModel.Image079.SetWidth(300).SetCrop(CropType.KeepAspectRatio).SetCompression(80).GetCrop()" alt=""> } </div> </div> } @if (!string.IsNullOrWhiteSpace(viewModel.Image401)) { <div class="datasheet_link"> <a href="@viewModel.Image401" target="_blank">@Translate("Datasheet", "Datasheet")</a> </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-name="viewModel.Name" 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="ProductID" id="ProductID" value="@viewModel.Id" />*@ <input type="hidden" name="Redirect" id="Redirect" value="/WebServices/MiniCart.ashx?productId=@viewModel.Id&areaId=@Pageview.AreaID" disabled /> <button type="submit" class="btn" @(viewModel.Stock > 0 ? "" : "disabled") data-added-msg="@(Translate("AddedToCart", "Added to cart"))"> <span class="btn__text"> @Translate("AddToCart", "Add To Cart") <span class="btn__icon"><svg aria-hidden="true"><use xlink:href="@staticResourceService.AddTimeStamp("/static/dist/svg/_bundle.svg")#arrow-right"></use></svg></span> </span> </button> </form> </div> <div class="product__availability product__availability--instock"> @Translate("InStock", "In stock"): </div> } else { <div class="product__soldout__box"> <div class="product__soldout"> <p class="product__soldout-title">@Translate("Sorry, this product is sold out.", "Sorry, this product is sold out.")</p> @if (!string.IsNullOrEmpty(@viewModel.AvailableAgain)) { <p class="product__soldout-date">@Translate("In stock again", "In stock again"): @viewModel.AvailableAgain</p> } <div class="product__soldout-button"> <a href="@Pageview.Area.Item["SettingsDealersPage"]&DealersProductNumber=@viewModel.ProductNumber&DealersLanguageId=@languageId" class="btn"> <span class="btn__text"> @Translate("Find dealer", "Find dealer") <span class="btn__icon"><svg aria-hidden="true"><use xlink:href="@staticResourceService.AddTimeStamp("/static/dist/svg/_bundle.svg")#arrow-right"></use></svg></span> </span> </a> </div> <div class="product__getnotified-box" data-area="@area.ID" data-product="@productNumber"> <a class="btn product__getnotified-button"> <span class="btn__text"> @Translate("Get notified when back in stock", "Get notified when back in stock") <span class="btn__icon"> <svg aria-hidden="true"><use xlink:href="/static/dist/svg/_bundle.svg?ts=636555677940000000#arrow-right"></use></svg> </span> </span> </a> <div class="product__getnotified-form hidden"> <div class="product__getnotified-header">@Translate("Get notified when back in stock", "Get notified when back in stock")</div> <div class="product__getnotified-text">@Translate("Get an instant notification via email when this item becomes available.", "Get an instant notification via email when this item becomes available.")</div> <label class="product__getnotified-input"><input type="text" class="product__getnotified-email" placeholder="@Translate("Enter your e-mail address here", "Enter your e-mail address here")" /></label> <label class="product__getnotified-checkbox"> <input type="checkbox" class="product__getnotified-consent trigger" /> <span class="product__getnotified-text">@Translate("Subscribe to our Newsletter and get latest news", "Subscribe to our Newsletter and get latest news")</span> </label> <a class="btn product__getnotified-send"> <span class="btn__text"> @Translate("Click to get notified", "Click to get notified") <span class="btn__icon"> <svg aria-hidden="true"><use xlink:href="/static/dist/svg/_bundle.svg?ts=636555677940000000#arrow-right"></use></svg> </span> </span> </a> <div class="product__getnotified-text">@Translate("While entering your email will not hold an item for you, it will allow us to notify you when it becomes available again!", "While entering your email will not hold an item for you, it will allow us to notify you when it becomes available again!")</div> </div> <div class="product__getnotified-thanks hidden"> <div class="product__getnotified-header">@Translate("Get notified when back in stock", "Get notified when back in stock")</div> <div class="product__getnotified-text">@Translate("Thank you, you will get notified when back in stock.", "Thank you, you will get notified when back in stock.")</div> </div> </div> </div> @if (viewModel.AlternativeProducts.Count > 0) { <div class="product__soldout"> <p class="product__soldout-text">@Translate("Please see these alternatives.", "Please see these alternatives.")</p> </div> <div class="product__alternatives"> <ul> @foreach (var item in viewModel.AlternativeProducts) { var alternativeProduct = viewModelService.GetViewModel(item); <li class="product-item"> <article itemscope="" itemtype="http://schema.org/Product"> <a itemprop="url" href="@urlService.GetUrl(alternativeProduct.GroupId, alternativeProduct.Id)"> <div class="product-item__header" style="height:250px;"> <div class="product-item__headlineNEW"> <h3 itemprop="name">@alternativeProduct.Name</h3> </div> <figure class="product-item__image"> <img src="@alternativeProduct.MainImage.SetWidth(500).SetHeight(300).SetCrop(CropType.KeepAspectRatio).SetCompression(50).GetCrop()" itemprop="image" content="@alternativeProduct.MainImage" alt="@alternativeProduct.Name"> </figure> <div itemprop="offers" itemscope itemtype="http://schema.org/Offer" class="product-item__price"> <div class="priceNEW" style="margin-right:25px;margin-top:0px;"><span itemprop="priceCurrency" content="@alternativeProduct.Currency">@alternativeProduct.CurrencySymbol</span> <span itemprop="price" content="@alternativeProduct.UnformatedPrice">@alternativeProduct.Price</span></div> </div> </div> </a> </article> </li> } </ul> </div> } </div> <div class="product__button"> <form method="get"> <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="ProductID" id="ProductID" value="@viewModel.Id" />*@ <input type="hidden" name="Redirect" id="Redirect" value="/WebServices/MiniCart.ashx?productId=@viewModel.Id&areaId=@Pageview.AreaID" disabled /> <button type="submit" class="btn btn--greyed" data-added-msg="@(Translate("AddedToCart", "Added to cart"))"> <span class="btn__text"> @Translate("AddToCart", "Add To Cart") <span class="btn__icon"><svg aria-hidden="true"><use xlink:href="@staticResourceService.AddTimeStamp("/static/dist/svg/_bundle.svg")#arrow-right"></use></svg></span> </span> </button> </form> </div> } } } @if (viewModel.AssortmentsOnDisplay.Count > 0) { <div class="product__assortments-button"> <div class="product__bullet-points" style="margin-top: 0px;padding-top: 0px;"> <p style="font-size: 22px;margin-bottom:0px;">@Translate("Item on display headline", "Item on display")</p> <a> <span>@Translate("See tents on display", "See tents on display")</span> </a> </div> </div> <div class="product__assortments__box"> <div class="product__assortments"> <span class="product__assortments-text">@Translate("See this item on display here", "See this item on display here"):</span> </div> <ul> @foreach (var assortment in viewModel.AssortmentsOnDisplay) { <li class="product-item"> <p><b>@assortment.Name</b></p> <p>@assortment.Address.Trim()</p> @if (!string.IsNullOrEmpty(assortment.Address2.Trim())) { <p>@assortment.Address2.Trim()</p> } <p>@assortment.Zip.Trim() @assortment.City.Trim()</p> <p>@Translate("Phone"): @assortment.Phone.Trim()</p> <hr style="height: 2px;color: #ee7d2a;background-color: #ee7d2a;border: none;" /> </li> } </ul> </div> } <dl class="product__bullet-points"> <dt>@Translate("Find dealers", "Find dealers")</dt> <dt class="link"><a href="@Pageview.Area.Item["SettingsDealersPage"]&DealersProductNumber=@viewModel.ProductNumber&DealersLanguageId=@languageId">@Translate("Available in these stores", "Available in these stores")</a></dt> <dt>@Translate("NeedHelp", "Need help?")</dt> <dd><a href="@viewModel.CustomerServiceLink">@viewModel.CustomerServiceLinkTitle</a></dd> <dt>@Translate("WarrentyTeaser", "")</dt> <dd style="font-size: 15px;">@Translate("WarrentyLink", "")</dd> </dl> </div> </div> </div> <section class="product-description"> @if (!string.IsNullOrWhiteSpace(@viewModel.Name)) { <h1 class="product__name" itemprop="name">@viewModel.Name</h1> } <div class="text__body"> <div itemprop="description"> @viewModel.LongDescription </div> </div> </section> <div class="product-detail"> @if (viewModel.DimensionImages.Count > 0) { <div class="product-detail-left"> <div class="product-detail-heading">@Translate("Layout", "Layout")</div> <div class="product-detail-images"> <article> @foreach (var image in viewModel.DimensionImages) { <div class="lazy" data-src-xxs="@image.SetWidth(470*2).SetCrop(CropType.KeepAspectRatio).SetCompression(80).SetImageFormat(ImageFormat.Jpg).GetCrop()" alt="Easycamp @viewModel.Name" data-src-sm="@image.SetWidth(348*2).SetCrop(CropType.KeepAspectRatio).SetCompression(80).SetImageFormat(ImageFormat.Jpg).GetCrop()" alt="Easycamp @viewModel.Name" data-src-md="@image.SetWidth(287*2).SetCrop(CropType.KeepAspectRatio).SetCompression(80).SetImageFormat(ImageFormat.Jpg).GetCrop()" alt="Easycamp @viewModel.Name" data-src-lg="@image.SetWidth(300*2).SetCrop(CropType.KeepAspectRatio).SetCompression(80).SetImageFormat(ImageFormat.Jpg).GetCrop()" alt="Easycamp @viewModel.Name" data-gallery="@image.SetWidth(1230).SetCrop(CropType.KeepAspectRatio).SetCompression(80).SetImageFormat(ImageFormat.Jpg).GetCrop()" alt="Easycamp @viewModel.Name"> </div> } </article> </div> </div> } @if (viewModel.Features.Count > 0 || viewModel.TemperatureImages.Count > 0) { <div class="product-detail-left"> <div class="product-detail-heading">@Translate("Specifications", "Specifications")</div> <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: </dt> <dd>@specValue</dd> } break; } } @if (!string.IsNullOrWhiteSpace(@viewModel.ProductNumber)) { <dt> @Translate("ProductNumber", "Product Number"): </dt> <dd>@viewModel.ProductNumber</dd> } </dl> } </article> </div> </div> </div> } @if (viewModel.FeatureList.Count > 0) { <div class="product-detail-left"> <div class="product-detail-heading">@Translate("FeatureList", "Feature list")</div> <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")#easycamp-bird"></use></svg></div> @featureText </section> } </article> </div> @if (viewModel.TemperatureImages.Count > 0) { <div class="temprature-images"> @foreach (var image in viewModel.TemperatureImages) { <img src="@image.SetWidth(200).SetCrop(CropType.KeepAspectRatio).SetCompression(100).GetCrop()" /> } </div> } </div> </div> } @if (!string.IsNullOrWhiteSpace(@viewModel.CareText) || !string.IsNullOrWhiteSpace(@viewModel.CareFile) || !string.IsNullOrWhiteSpace(@viewModel.Image082) || !string.IsNullOrWhiteSpace(@viewModel.CareVideoUrl)) { <div class="product-detail-left"> <div class="product-detail-heading">@Translate("CareVideoHeading", "CareVideoHeading")</div> <div class="product__details-item"> @if (!string.IsNullOrWhiteSpace(@viewModel.CareText)) { <div class="text__body"> <div itemprop="description" style="margin-top:20px;"> @viewModel.CareText </div> </div> } @if (!string.IsNullOrWhiteSpace(@viewModel.CareVideoUrl)) { <figure> <div class="media__showcase"> <div> <div class="video-container"> <iframe src="@viewModel.CareVideoUrl?rel=0&amp;showinfo=0&amp;controls=0" frameborder="0" allowfullscreen></iframe> </div> </div> </div> </figure> } @if (!string.IsNullOrWhiteSpace(@viewModel.Image082)) { <div class="pdf" style="margin-top:20px;margin-bottom:20px;"> <ul> <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("CareFileText2", "Care label - PDF") : viewModel.CareFileDescription) </a> </li> </ul> </div> } @if (!string.IsNullOrWhiteSpace(@viewModel.CareFile)) { <div class="pdf" style="margin-top:20px;margin-bottom:20px;"> <ul> <li> <a href="@viewModel.CareFile " target="_blank"> @(string.IsNullOrWhiteSpace(viewModel.CareFileDescription) ? Translate("CareFileText2", "Care label - PDF") : viewModel.CareFileDescription) </a> </li> </ul> </div> } </div> </div> } @if (viewModel.Icons.Count > 0) { <div class="product-detail-left"> <div class="product-detail-heading">@Translate("DetailIcons", "Detail icons")</div> <div class="product__details-item"> <div class="product__details-icons product__icons-options"> <article class="product__icons-options-items"> @foreach (var icon in viewModel.Icons) { var iconIndex = 0; <section> <header> <div class="product-icon-wrap product__icons-option" data-index="@iconIndex"> <img src="@icon.Image.SetWidth(60).SetHeight(60).SetCrop(CropType.KeepAspectRatio).SetCompression(80).GetCrop()" alt="@icon.Headline"> <span class="product-detail-icon-hidden-text">@icon.BodyText</span> </div> </header> </section> iconIndex++; } </article> @if (!string.IsNullOrEmpty(GetString("Ecom:Product:Field.Icon1Slide.Value.Clean"))) { <div class="product-detail-icon-text-top"></div> <div class="product-icon-text"> @Translate("Click the icons for more information", "Click the icons for more information") </div> <div class="product__icons-showcase"> @for (var i = 1; i <= 20; i++) { var iconSlide = GetString("Ecom:Product:Field.Icon" + i + "Slide.Value.Clean"); if (!string.IsNullOrEmpty(iconSlide)) { var iconSlideImage = "/Admin/Public/GetImage.ashx?Image=/Files/Images/Productimages/" + iconSlide + ".jpg&Crop=5&Compression=80"; <div class="product__image product__icon-slide-image lazy-loaded" data-src-XXS="@iconSlideImage&Width=728" alt="" data-gallery="@iconSlideImage&Width=1230"> <img alt="" src="@iconSlideImage&Width=728"> </div> } } </div> } </div> </div> </div> } </section> <section class="product__details" style="display:none;"> <div class="product__details-list"> <div class="product__details-options"> <div class="product__details-options-line"></div> <div class="product__details-option"> <button></button> </div> </div> <div class="product__details-items"> <div class="product__details-item"> <div class="product__details-images"> </div> </div> </div> </div> </section> @if (viewModel.PitchingImages.Count > 0 || !string.IsNullOrWhiteSpace(@viewModel.PitchingVideo)) { <section class="ribbon media media--video container-ribbon product__pitching"> <div class="container-fluid"> <div class="product"><div class="product-detail"><div class="product-detail-heading">@Translate("PitchingVideoHeading", "Pitching Video")</div></div></div> @if (!string.IsNullOrWhiteSpace(@viewModel.PitchingVideo)) { <figure> <div class="media__showcase"> <div> <div class="video-container"> <iframe src="@viewModel.PitchingVideo?rel=0&amp;showinfo=0&amp;controls=0" frameborder="0" allowfullscreen></iframe> </div> </div> </div> <div class="media__text-wrap"> <div class="media__bird lazy-bg"> <svg aria-hidden="true"><use xlink:href="/static/dist/svg/_bundle.svg?ts=636743678646712620#easycamp-bird"></use></svg> </div> <div class="media__text"> <div> <h2> @viewModel.Name</h2> @viewModel.ShortDescription <a href="@Translate("EasycampYoutubeUrl", "/")" class="btn"> <span class="btn__text">@Translate("VisitOurYoutubeChannel", "Visit our youtube channel") <span class="btn__icon"><svg aria-hidden="true"><use xlink:href="@staticResourceService.AddTimeStamp("/static/dist/svg/_bundle.svg")#arrow-right"></use></svg></span></span> </a> </div> </div> </div> </figure> } @if (viewModel.PitchingImages.Count > 0) { <div class="pdf" style="margin-top:-25px;"> <ul> @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> } </div> </section> } </article> @if (viewModel.RelatedProductsCount > 0) { <div class="container-fluid"> <section class="featured-products container-ribbon ribbon" data-module="featured-products"> <div class="product"><div class="product-detail"><div class="product-detail-heading">@Translate("OptionalExtra", "Optional Extra")</div></div></div> <div class="container"> <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"> <div class="product-item__statusbox"> @if (!string.IsNullOrEmpty(relatedProduct.OutletcampingSplash)) { var statustext = relatedProduct.OutletcampingSplash; <div class="product-item__labelstatusRibbon"> @if (statustext.Length > 4) { <div class="product-item__status"> <span>@statustext</span> </div> } @if (statustext.Length < 5) { <div class="product-item__status2"> <span>@statustext</span> </div> } </div> } </div> <figure style="height:200px;"> <img src="@relatedProduct.MainImage.SetWidth(500).SetHeight(200).SetCrop(CropType.KeepAspectRatio).SetCompression(50).GetCrop()" content="@relatedProduct.MainImage" alt="@relatedProduct.Name"> </figure> @if (relatedProduct.Image090 != null) { <div class="product-item__splash-image"> <img src="@relatedProduct.Image090.SetWidth(200).SetCrop(CropType.KeepAspectRatio).SetCompression(80).GetCrop()" alt=""> </div> } @if (!string.IsNullOrEmpty(relatedProduct.Award001)) { <div class="product-item_splash_award"> <img src="@relatedProduct.Award001" alt=""> </div> } @if (!string.IsNullOrEmpty(relatedProduct.LabelText)) { <div class="product-item__labelRibbon"> <p>@relatedProduct.LabelText</p> </div> } </div> <div class="product-item__body"> <div class="product-item__headlineNEW"> @if (!string.IsNullOrEmpty(relatedProduct.Name)) { <h2>@relatedProduct.Name</h2> } </div> <div class="product-item__information" itemprop="description"> @if (!string.IsNullOrEmpty(relatedProduct.LongDescription)) { @relatedProduct.LongDescription } </div> <div class="product-item__bulletpoints"> <ul> @if (!string.IsNullOrWhiteSpace(relatedProduct.Bullet1)) { <li>@relatedProduct.Bullet1</li> <li>@relatedProduct.Bullet2</li> <li>@relatedProduct.Bullet3</li> } @if (!string.IsNullOrWhiteSpace(relatedProduct.PackSize)) { <li>@Translate("Pack size", "Pack size"): @relatedProduct.PackSize</li> } @if (!string.IsNullOrWhiteSpace(relatedProduct.Weightsale)) { <li>@Translate("Weight", "Weight"): @relatedProduct.Weightsale</li> } </ul> </div> <div class="product-item__price"> <div class="priceNEW"><span content="@relatedProduct.Currency">@relatedProduct.CurrencySymbol</span> <span content="@relatedProduct.UnformatedPrice">@relatedProduct.Price</span></div> </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 = "http://dino.outwell.com/dino/ec/alsobought/" + viewModel.ProductNumber + "?return=12"; var n = 1; 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 container-ribbon ribbon" data-module="featured-products"> <div class="container container--product"> <h3 class="product-detail-heading">@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"> <div class="product-item__statusbox"> @if (!string.IsNullOrEmpty(relatedProduct.OutletcampingSplash)) { var statustext = relatedProduct.OutletcampingSplash; <div class="product-item__labelstatusRibbon"> @if (statustext.Length > 8) { <div class="product-item__status"> <span>@statustext</span> </div> } @if (statustext.Length < 8) { <div class="product-item__status2"> <span>@statustext</span> </div> } </div> } </div> <figure style="height:200px;"> <img src="@relatedProduct.MainImage.SetWidth(500).SetHeight(200).SetCrop(CropType.KeepAspectRatio).SetCompression(50).GetCrop()" content="@relatedProduct.MainImage" alt="@relatedProduct.Name"> </figure> @if (relatedProduct.Image090 != null) { <div class="product-item__splash-image"> <img src="@relatedProduct.Image090.SetWidth(200).SetCrop(CropType.KeepAspectRatio).SetCompression(80).GetCrop()" alt=""> </div> } @if (!string.IsNullOrEmpty(relatedProduct.Award001)) { <div class="product-item_splash_award"> <img src="@relatedProduct.Award001" alt=""> </div> } @if (!string.IsNullOrEmpty(relatedProduct.LabelText)) { <div class="product-item__labelRibbon"> <p>@relatedProduct.LabelText</p> </div> } </div> <div class="product-item__body"> <div class="product-item__headlineNEW"> @if (!string.IsNullOrEmpty(relatedProduct.Name)) { <h2>@relatedProduct.Name</h2> } </div> <div class="product-item__information" itemprop="description"> @if (!string.IsNullOrEmpty(relatedProduct.LongDescription)) { @relatedProduct.LongDescription } </div> <div class="product-item__bulletpoints"> <ul> @if (!string.IsNullOrWhiteSpace(relatedProduct.Bullet1)) { <li>@relatedProduct.Bullet1</li> <li>@relatedProduct.Bullet2</li> <li>@relatedProduct.Bullet3</li> } @if (!string.IsNullOrWhiteSpace(relatedProduct.PackSize)) { <li>@Translate("Pack size", "Pack size"): @relatedProduct.PackSize</li> } @if (!string.IsNullOrWhiteSpace(relatedProduct.Weightsale)) { <li>@Translate("Weight", "Weight"): @relatedProduct.Weightsale</li> } </ul> </div> <div class="product-item__price"> <div class="priceNEW"><span content="@relatedProduct.Currency">@relatedProduct.CurrencySymbol</span> <span content="@relatedProduct.UnformatedPrice">@relatedProduct.Price</span></div> </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__headlineNEW"> <h3 class="h-1">@raptorProductView.Name</h3> </div> <div class="product-item__price"> <div class="priceNEW"><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__headlineNEW"> <h3 class="h-1">@raptorProductView.Name</h3> </div> <div class="product-item__price"> <div class="priceNEW"><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 --> @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; } }