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&showinfo=0&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&showinfo=0&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">×</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&showinfo=0&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&showinfo=0&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&showinfo=0&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&showinfo=0&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&showinfo=0&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;
}
}