Lagervarer bestilt inden kl 12 - levering 1-3 dage. Salg kun til erhverv   Gratis levering ved køb over 1.500 kr. - Levering 1-3 dage   Nememballage.dk er en del af KD Emballage. Dansk leverandør af emballage

Error executing template "Designs/Nememballage/eCom/ProductCatalog/ProductViewDetail.cshtml"
System.ArgumentException: An item with the same key has already been added.
   at System.ThrowHelper.ThrowArgumentException(ExceptionResource resource)
   at System.Collections.Generic.Dictionary`2.Insert(TKey key, TValue value, Boolean add)
   at Dynamicweb.Ecommerce.Products.GroupRelation.GetGroupRelationsByChildId(String childId)
   at Dynamicweb.Ecommerce.Products.Group.get_IsTopGroup()
   at Dynamicweb.Ecommerce.Shops.Shop.GetTopLevelGroups(String languageId)
   at Dynamicweb.Ecommerce.Shops.Shop.get_TopLevelGroups()
   at CompiledRazorTemplates.Dynamic.RazorEngine_ddc83214088f4810a6a2bac9834482b9.Execute()
   at RazorEngine.Templating.TemplateBase.RazorEngine.Templating.ITemplate.Run(ExecuteContext context, TextWriter reader)
   at RazorEngine.Templating.RazorEngineService.RunCompile(ITemplateKey key, TextWriter writer, Type modelType, Object model, DynamicViewBag viewBag)
   at RazorEngine.Templating.RazorEngineServiceExtensions.<>c__DisplayClass16_0.<RunCompile>b__0(TextWriter writer)
   at RazorEngine.Templating.RazorEngineServiceExtensions.WithWriter(Action`1 withWriter)
   at Dynamicweb.Rendering.RazorTemplateRenderingProvider.Render(Template template)
   at Dynamicweb.Rendering.TemplateRenderingService.Render(Template template)
   at Dynamicweb.Rendering.Template.RenderRazorTemplate()

1 @using Dynamicweb.Rendering 2 @using Dynamicweb.Ecommerce.ProductCatalog 3 @using System.Linq 4 @using System.Collections 5 @using Newtonsoft.Json 6 @inherits ViewModelTemplate<ProductViewModel> 7 8 @using Dynamicweb.Rendering 9 @using Dynamicweb.Ecommerce.ProductCatalog 10 @using System; 11 @using System.Collections.Generic; 12 @using System.Linq; 13 14 @helper HelperRenderProductList(IList<ProductViewModel> products, string groupCategoryname = "") 15 { 16 int webshopPageId = GetPageIdByNavigationTag("Shop"); 17 18 //get all prices here from BC 19 20 var pricesRequest = new List<Website.CustomCode.Models.BC.CustomerSalesPriceLineRequest>(); 21 var productList = new List<string>(); 22 foreach (var product in products) 23 { 24 productList.Add(product.Number); 25 } 26 var priceLineQuantities = Website.Api.BC.BusinessCentralService.GetQuantitiesWithPrice(productList, ""); 27 foreach (var priceLine in priceLineQuantities) 28 { 29 pricesRequest.Add(new Website.CustomCode.Models.BC.CustomerSalesPriceLineRequest 30 { 31 ItemNo = priceLine.AssetNo, 32 Quantity = priceLine.MinimumQuantity, 33 VariantCode = priceLine.VariantCode 34 }); 35 } 36 37 var requestBC = new Website.CustomCode.Models.BC.RootCustomerSalesPricesRequest 38 { 39 CustomerNo = "", 40 CustomerSalesPriceLines = pricesRequest 41 }; 42 43 var pricesBcQuantities = Website.Api.BC.BusinessCentralService.GetCustomerPrices(requestBC); 44 45 46 for (int i = 0; i < products.Count; i++) 47 { 48 var productApi = new Dynamicweb.Ecommerce.Products.ProductService().GetProductById(products[i].Id, "", products[i].LanguageId); 49 if (productApi == null) 50 { 51 continue; 52 } 53 54 var group = productApi.GetDefaultGroupByShopId("SHOP2"); 55 var title = new Website.Helpers.Product().GetTitle(products[i]) + " " + productApi.ShortDescription; 56 var formattedTitle = title.Length > 60 ? title.Substring(0, 60).Trim() + "..." : title; 57 58 var resizedImage = VestjyskMarketing.Helpers.ImageHelper.ResizeImage(products[i].DefaultImage.Value, 600, 500); 59 if (group == null) 60 { 61 continue; 62 } 63 64 65 string productLink = "/Default.aspx?ID=" + webshopPageId + "&amp;GroupID=" + group.Id + "&amp;ProductID=" + products[i].Id; 66 var productBcPriceRow = pricesBcQuantities.OrderBy(x => x.DiscountedPrice).FirstOrDefault(x => x.ItemNo == productApi.Number); 67 68 double productPrice = 0; 69 if (productBcPriceRow != null) 70 { 71 productPrice = productBcPriceRow.DiscountedPrice; 72 } 73 74 FieldValueViewModel hideBuy; 75 FieldValueViewModel oldprice; 76 FieldValueViewModel environmentLogoEnable; 77 products[i].ProductFields.TryGetValue("HideBuy", out hideBuy); 78 products[i].ProductFields.TryGetValue("Gl_salgspris", out oldprice); 79 products[i].ProductFields.TryGetValue("MiljoeVenligtValg", out environmentLogoEnable); 80 81 //get height, lenght and width productinfoL: 190 MM B: 100 MM H: 70 MM 82 List<Tuple<string, string>> dimensionsList = new Website.Helpers.Product().GetProductFieldsDimensions(products[i]); 83 84 string fscLogo = VestjyskMarketing.Helpers.ImageHelper.ResizeImage("/Files/Images/Logoer/FSC_Logo.png", 50, 50, 6); 85 bool fscApproved = bool.Parse(products[i].ProductFields["FSC"].Value.ToString()); 86 87 <div class="productlist__item bg-light"> 88 <div class="row no-gutters"> 89 <div class="col-lg-3 col-xl-2 productlist__item__image" style="background-image: url(@resizedImage);"> 90 91 </div> 92 <div class="col-lg-5 col-xl-6"> 93 <div class="productlist__item__content"> 94 <h2> 95 <a href="@productLink" title="@Translate(" Gå til:") @title">@title</a> 96 </h2> 97 @if (dimensionsList.Count > 0) 98 { 99 <div class="productlist__item__fields text-primary font-weight-bold"> 100 @foreach (var dimension in dimensionsList) 101 { 102 <span> 103 @dimension.Item1.Substring(0, 1): @dimension.Item2 104 @if (dimension.Item1.ToLower().Contains("(m)")) 105 { 106 <text>M</text> 107 } 108 else 109 { 110 <text>MM</text> 111 } 112 </span> 113 } 114 </div> 115 } 116 <div class="productlist__item__number font-weight-bold">@Translate("Varenummer"): @products[i].Number</div> 117 118 @if (fscApproved) 119 { 120 <a class="productlist-miljø-link" href="Default.aspx?ID=@GetPageIdByNavigationTag("environmentpage")"> 121 <img src="@fscLogo" class="img-fluid productlist__item__fsc " alt="FSC logo" title="FSC Godkendt" /> 122 </a> 123 } 124 @if (Dynamicweb.Core.Converter.ToBoolean(environmentLogoEnable.Value)) 125 { 126 string environmentLogo = VestjyskMarketing.Helpers.ImageHelper.ResizeImage("/Files/Images/Logoer/Nem_Logo_miljø_FINAL.png", 50, 50, 6); 127 <a class="productlist-miljø-link" href="Default.aspx?ID=@GetPageIdByNavigationTag("environmentpage")"> 128 <img src="@environmentLogo" class="img-fluid productlist__item__fsc " alt="Miljøvenligt valg" title="Miljøvenligt valg" /> 129 </a> 130 } 131 </div> 132 </div> 133 <div class="col-lg-4 text-right"> 134 <div class="productlist__item__price__container "> 135 @if (Convert.ToBoolean(hideBuy.Value) == false && productPrice > 0) 136 { 137 <div class="productlist__item__price"> 138 139 Priser fra&nbsp; &nbsp;<span class="productlist__item__price__highlight">@string.Format("{0:0.00}", productPrice) DKK</span> 140 <div class="productlist__item__price__vat">eksl. moms</div> 141 @if (Dynamicweb.Core.Converter.ToDecimal(oldprice.Value) > 0) 142 { 143 <span class="productlist__item__oldprice">@string.Format("{0:0.00}", oldprice.Value) DKK</span> 144 } 145 </div> 146 } 147 <a class="btn btn-outline-primary rounded-pill btn-round btn-block" href="@productLink" title="@Translate(" Gå til:") @products[i].Title ">Se produkt</a> 148 149 <form method="post" class="js-product-form"> 150 <input type="hidden" name="ProductID" value="@products[i].Id"> 151 <input type="hidden" name="CartCmd" value="add"> 152 <input type="hidden" value="@products[i].PurchaseMinimumQuantity" name="Quantity" id="amount"> 153 <button class="mt-2 btn btn-primary rounded-pill btn-block productlist__item__add-button" data-productid="" title="Add to cart" type="submit"> 154 Tilføj til kurv <i class="far fa-shopping-cart pl-3"></i> 155 </button> 156 </form> 157 </div> 158 </div> 159 </div> 160 </div> 161 } 162 } 163 164 @helper HelperRenderProductSpotList(List<ProductViewModel> products) 165 { 166 int webshopPageId = GetPageIdByNavigationTag("Shop"); 167 168 var pricesRequest = new List<Website.CustomCode.Models.BC.CustomerSalesPriceLineRequest>(); 169 foreach (var product in products) 170 { 171 pricesRequest.Add(new Website.CustomCode.Models.BC.CustomerSalesPriceLineRequest 172 { 173 ItemNo = product.Number, 174 Quantity = Dynamicweb.Core.Converter.ToInt32(product.PurchaseMinimumQuantity) 175 }); 176 } 177 var requestBC = new Website.CustomCode.Models.BC.RootCustomerSalesPricesRequest 178 { 179 CustomerNo = "", 180 CustomerSalesPriceLines = pricesRequest 181 }; 182 var pricesBc = Website.Api.BC.BusinessCentralService.GetCustomerPrices(requestBC); 183 184 <div class="row"> 185 186 @foreach (var product in products) 187 { 188 var productApi = new Dynamicweb.Ecommerce.Products.ProductService().GetProductById(product.Id, "", product.LanguageId); 189 if (productApi == null || !productApi.IsActive) 190 { 191 continue; 192 } 193 194 var resizedImage = VestjyskMarketing.Helpers.ImageHelper.ResizeImage(product.DefaultImage.Value, 433, 353); 195 string productLink = "/Default.aspx?ID=" + webshopPageId + "&amp;GroupID=" + product.PrimaryOrDefaultGroup.Id + "&amp;ProductID=" + product.Id; 196 197 var productBcPriceRow = pricesBc.OrderBy(x => x.DiscountedPrice).FirstOrDefault(x => x.ItemNo == productApi.Number); 198 double productPrice = 0; 199 if (productBcPriceRow != null) 200 { 201 productPrice = productBcPriceRow.DiscountedPrice; 202 } 203 204 FieldValueViewModel hideBuy; 205 product.ProductFields.TryGetValue("HideBuy", out hideBuy); 206 207 //dont show related or any other product if price is 0 in this method 208 if (productPrice == 0) 209 { 210 continue; 211 } 212 213 <div class="col-12 col-lg-6 col-xl-3 px-0 px-lg-2 mb-5 mb-lg-3"> 214 <div class="productlist-spot__item"> 215 <div class="row h-100"> 216 <div class="col-3 col-lg-12"> 217 <div class="productlist-spot__item__img" style="background-image: url(@resizedImage)"></div> 218 </div> 219 <div class="col-9 col-lg-12"> 220 <div class="productlist-spot__item__description"> 221 <p class="productlist-spot__item__title"> 222 <a href="@productLink" title="@Translate(" Gå til:") @product.Title ">@product.Title</a> 223 </p> 224 <p class="productlist-spot__item__number">Varenummer: @product.Number</p> 225 </div> 226 </div> 227 228 <div class="col-12 mt-auto "> 229 <div class="productlist-spot__item__content"> 230 <div class="row"> 231 <div class="col-7 p-0 pl-4 pl-lg-0 pr-lg-3"> 232 @if (Convert.ToBoolean(hideBuy.Value) == false && productPrice > 0) 233 { 234 <p class="productlist-spot__item__price">Priser fra <br /> <strong> @productPrice DDK</strong></p> 235 <p class="productlist-spot__item__tax">ekskl. moms</p> 236 } 237 238 </div> 239 <div class="col-5 d-flex justify-content-end pr-2 p-0 p-lg-2"> 240 <a class="btn btn-round align-self-end rounded-pill productlist-spot__item__link " href="@productLink" title="@Translate(" Gå til:") @product.Title">Se produkt</a> 241 </div> 242 </div> 243 </div> 244 </div> 245 </div> 246 </div> 247 </div> 248 } 249 </div> 250 } 251 252 @functions { 253 254 public class UnitPrice 255 { 256 public double Amount { get; set; } 257 public double Price { get; set; } 258 } 259 260 } 261 262 @{ 263 //get product since Model does not contain all relevant fields 264 var product = new Dynamicweb.Ecommerce.Products.ProductService().GetProductById(Model.Id, "", Model.LanguageId); 265 266 //get product field values 267 FieldValueViewModel video; 268 FieldValueViewModel packedOfNumber; 269 FieldValueViewModel qtyOnPallet; 270 FieldValueViewModel baseUnit; 271 FieldValueViewModel hideBuy; 272 FieldValueViewModel ydrePakning; 273 FieldValueViewModel oldprice; 274 FieldValueViewModel environmentLogoEnable; 275 Model.ProductFields.TryGetValue("Video", out video); 276 Model.ProductFields.TryGetValue("PakketAf", out packedOfNumber); 277 Model.ProductFields.TryGetValue("QtyOnPallet", out qtyOnPallet); 278 Model.ProductFields.TryGetValue("BaseUnit", out baseUnit); 279 Model.ProductFields.TryGetValue("HideBuy", out hideBuy); 280 Model.ProductFields.TryGetValue("YdrePakning", out ydrePakning); 281 Model.ProductFields.TryGetValue("Gl_salgspris", out oldprice); 282 Model.ProductFields.TryGetValue("MiljoeVenligtValg", out environmentLogoEnable); 283 284 285 //add default image to patternimage 286 if (Model.DefaultImage != null) 287 { 288 Model.ImagePatternImages.Insert(0, Model.DefaultImage); 289 } 290 291 //get the title 292 var title = new Website.Helpers.Product().GetTitle(Model); 293 294 //get the cart pageId 295 int cartPageId = GetPageIdByNavigationTag("Cart"); 296 297 //get ths shopId 298 int webshopPageId = GetPageIdByNavigationTag("Shop"); 299 300 //List containing different breakpoints for prices 301 List<UnitPrice> lu = new List<UnitPrice>(); 302 303 //get related products 304 var relatedProducts = Dynamicweb.Ecommerce.Services.ProductRelated.GetRelations(Model.Id); 305 var productModel = new List<ProductViewModel>(); 306 var listViewModel = new ProductListViewModel(); 307 if (relatedProducts != null && relatedProducts.Count() > 0) 308 { 309 foreach (var item in relatedProducts) 310 { 311 var productRelated = item.Product; 312 if (productRelated != null) 313 { 314 Dynamicweb.Ecommerce.Products.ProductImageService productImageService = new Dynamicweb.Ecommerce.Products.ProductImageService(); 315 316 var productItem = new ProductViewModel(); 317 productItem.Id = productRelated.Id; 318 productItem.Name = productRelated.Name; 319 productItem.Title = productRelated.Name; 320 productItem.Number = productRelated.Number; 321 productItem.Title = new Website.Helpers.Product().GetTitle(productRelated); 322 323 324 var field = new FieldValueViewModel(); 325 field.Value = productRelated.GetProductFieldValue("HideBuy"); 326 productItem.ProductFields = new Dictionary<string, FieldValueViewModel>(); 327 productItem.ProductFields.Add("HideBuy", field); 328 329 productItem.Price = new PriceViewModel(); 330 productItem.Price.Price = productRelated.Price.Price; 331 332 333 productItem.DefaultImage = new MediaViewModel(); 334 productItem.DefaultImage.Value = productImageService.GetImagePath(productRelated); 335 336 337 productItem.PrimaryOrDefaultGroup = new GroupInfoViewModel(); 338 productItem.PrimaryOrDefaultGroup.Id = productRelated.PrimaryGroupId; 339 340 productModel.Add(productItem); 341 } 342 } 343 listViewModel.Products = productModel; 344 } 345 346 //get the fee we need to pay for fre shipping 347 double neededAmountFeeShipping = new Website.Helpers.Prices().GetCartFreeFeeAmountNeeded(); 348 349 350 //get all prices here from BC 351 var pricesRequest = new List<Website.CustomCode.Models.BC.CustomerSalesPriceLineRequest>(); 352 var priceLineQuantities = Website.Api.BC.BusinessCentralService.GetQuantitiesWithPrice(new List<string> { product.Number }, ""); 353 foreach (var priceLine in priceLineQuantities) 354 { 355 pricesRequest.Add(new Website.CustomCode.Models.BC.CustomerSalesPriceLineRequest 356 { 357 ItemNo = priceLine.AssetNo, 358 Quantity = priceLine.MinimumQuantity, 359 VariantCode = priceLine.VariantCode 360 }); 361 } 362 var requestBC = new Website.CustomCode.Models.BC.RootCustomerSalesPricesRequest 363 { 364 CustomerNo = "", 365 CustomerSalesPriceLines = pricesRequest 366 }; 367 368 var pricesBcQuantities = Website.Api.BC.BusinessCentralService.GetCustomerPrices(requestBC); 369 370 double priceProduct = 0; 371 if (pricesBcQuantities.Count > 0) 372 { 373 priceProduct = pricesBcQuantities.FirstOrDefault().DiscountedPrice; 374 } 375 376 //get height, lenght and width productinfoL: 190 MM B: 100 MM H: 70 MM 377 List<Tuple<string, string>> dimensionsList = new Website.Helpers.Product().GetProductFieldsDimensions(Model); 378 379 //lets get the last price for the cart added 380 double lastPriceAddedCart = 0; 381 var orderlines = Dynamicweb.Ecommerce.Common.Context.Cart?.OrderLines; 382 if (orderlines != null) 383 { 384 foreach (var orderline in orderlines) 385 { 386 if (orderline.ProductId == Model.Id) 387 { 388 lastPriceAddedCart = orderline.Price.PriceWithoutVAT; 389 } 390 } 391 } 392 393 //engliush culture for fb feed 394 System.Globalization.CultureInfo EnglishCulture = new System.Globalization.CultureInfo("en-EN"); 395 396 //fsc approved 397 string fscLogo = VestjyskMarketing.Helpers.ImageHelper.ResizeImage("/Files/Images/Logoer/FSC_Logo.png", 40, 40, 6); 398 // bool fscApproved = new Website.Helpers.Product().GetProductCategoryField("FSC_godkendt", Model) == "True" ? true : false; 399 bool fscApproved = bool.Parse(Model.ProductFields["FSC"].Value.ToString()); 400 401 //serialized pricepoints 402 if (pricesBcQuantities.Count > 0 && Convert.ToBoolean(hideBuy.Value) == false) 403 { 404 foreach (var price in pricesBcQuantities) 405 { 406 lu.Add(new UnitPrice() 407 { 408 Amount = Convert.ToDouble(price.Quantity), 409 Price = price.DiscountedPrice 410 }); 411 } 412 } 413 } 414 415 @{ 416 string groupIdBreadcrumb = Dynamicweb.Context.Current.Request["GroupID"] ?? ""; 417 string productIdBreadcrumb = Dynamicweb.Context.Current.Request["ProductID"] ?? ""; 418 var listBreadcrumbGroups = new List<Dynamicweb.Ecommerce.Products.Group>(); 419 var shop = Dynamicweb.Ecommerce.Services.Shops.GetShop("SHOP2"); 420 if (shop != null) 421 { 422 var topLevelGroups = shop.TopLevelGroups; 423 424 foreach (var topLevelGroup in topLevelGroups) 425 { 426 if (topLevelGroup.Id == groupIdBreadcrumb) 427 { 428 listBreadcrumbGroups.Add(topLevelGroup); 429 430 } 431 else 432 { 433 if (topLevelGroup.HasChildGroups) 434 { 435 foreach (var subgroup in topLevelGroup.Subgroups) 436 { 437 if (subgroup.Id == groupIdBreadcrumb) 438 { 439 listBreadcrumbGroups.Add(subgroup); 440 foreach (var parentGroup in subgroup.ParentGroups) 441 { 442 listBreadcrumbGroups.Insert(0, parentGroup); 443 } 444 } 445 } 446 } 447 } 448 } 449 } 450 } 451 452 <nav> 453 <ol class="breadcrumb"> 454 @if (String.IsNullOrEmpty(productIdBreadcrumb)) 455 { 456 <li class="breadcrumb__content__item js-breadcrumb-on-mobile d-lg-none"> 457 <a href="/"><i class="fal fa-chevron-left"> <span></span></i></a> 458 </li> 459 } 460 461 <li class="breadcrumb__content__item js-breadcrumb-off-mobile"> 462 <a href="/">Forside <span>|</span></a> 463 </li> 464 @* <li class="breadcrumb__content__item js-breadcrumb-off-mobile"> *@ 465 @* <a href="/webshop">Webshop <span>|</span></a> *@ 466 @* </li> *@ 467 468 469 @foreach (var groupBreadcrumb in listBreadcrumbGroups) 470 { 471 string activeClass = groupBreadcrumb.Id == groupIdBreadcrumb && String.IsNullOrEmpty(productIdBreadcrumb) ? "active d-block" : ""; ; 472 473 <li class="breadcrumb__content__item "> 474 <a href="/Default.aspx?ID=@Pageview.ID&GroupID=@groupBreadcrumb.Id" class="@activeClass js-breadcrumb-off-mobile"> 475 @groupBreadcrumb.Name 476 @if (groupBreadcrumb.Subgroups.Count > 0 || !String.IsNullOrEmpty(productIdBreadcrumb)) 477 { 478 <span>|</span> 479 } 480 </a> 481 </li> 482 } 483 484 485 @if (!String.IsNullOrEmpty(productIdBreadcrumb)) 486 { 487 string titleBreadcrumb = new Website.Helpers.Product().GetTitle(product); 488 <li class="breadcrumb__content__item js-breadcrumb-on-mobile d-lg-none"> 489 <a href="/Default.aspx?ID=@Pageview.ID&GroupID=@groupIdBreadcrumb"><i class="fal fa-chevron-left"> <span></span></i></a> 490 </li> 491 <li class="breadcrumb__content__item"> 492 <a href="/Default.aspx?ID=@Pageview.ID&GroupID=@groupIdBreadcrumb&ProductID=@productIdBreadcrumb" class="active"> 493 @titleBreadcrumb 494 </a> 495 </li> 496 } 497 498 </ol> 499 </nav> 500 501 <div class="product bg-gray-theme"> 502 <div class="container-fluid"> 503 <div class="row"> 504 <div class="col"> 505 <div class="row"> 506 <div class="col-12 col-xl-6"> 507 <div class="product__imagewrapper"> 508 <div class="row h-100"> 509 <div class="col-12 col-xxl-2 h-100"> 510 <div class="product__thumbnailslider"> 511 <div class="row no-gutters"> 512 @{ 513 int imgCounter = 1; 514 foreach (var image in Model.ImagePatternImages) 515 { 516 <div class="col-3 col-xxl-12"> 517 @{ 518 string thumbnailImage = VestjyskMarketing.Helpers.ImageHelper.ResizeImage(image.Value, 100, 100); 519 } 520 521 <div class="product__thumbnailslider__item" data-id="@image.Name"> 522 <img src="@thumbnailImage" class="img-fluid product__thumbnailslider__item__image " alt="Produkt billede @imgCounter" /> 523 </div> 524 @{ imgCounter++; } 525 </div> 526 } 527 528 <div class="col-3 col-xxl-12"> 529 @if (!String.IsNullOrEmpty(video.Value.ToString())) 530 { 531 <div class="product__thumbnailslider__item video-play-icon" data-id="@video.Name"> 532 <a alt="@Model.Name" href="javascript:void(0);"></a> 533 </div> 534 } 535 </div> 536 } 537 </div> 538 </div> 539 </div> 540 <div class="col-12 col-xxl-10 order-first order-xxl-last h-100"> 541 <div class="product__imageslider__container h-100"> 542 <span class="fal fa-search-plus product__imagewrapper__zoom"></span> 543 @if (fscApproved) 544 { 545 <a class="product-miljø-link" href="Default.aspx?ID=@GetPageIdByNavigationTag("environmentpage")"> 546 <img src="@fscLogo" class="img-fluid product__imagewrapper__fsc " alt="FSC logo" title="FSC Godkendt" /> 547 </a> 548 } 549 @if (Dynamicweb.Core.Converter.ToBoolean(environmentLogoEnable.Value)) 550 { 551 string environmentLogo = VestjyskMarketing.Helpers.ImageHelper.ResizeImage("/Files/Images/Logoer/Nem_Logo_miljø_FINAL.png", 40, 40, 6); 552 <a class="product-miljø-link" href="Default.aspx?ID=@GetPageIdByNavigationTag("environmentpage")"> 553 <img src="@environmentLogo" class="img-fluid product__imagewrapper__miljø-venlig" alt="Miljøvenligt valg" title="Miljøvenligt valg" /> 554 </a> 555 } 556 <div class="product__imageslider h-100"> 557 558 @for (int i = 0; i < Model.ImagePatternImages.Count; i++) 559 { 560 string imageResize = VestjyskMarketing.Helpers.ImageHelper.ResizeImage(Model.ImagePatternImages[i].Value, 900, 750); 561 var activeClass = ""; 562 if (i == 0) 563 { 564 activeClass = "active"; 565 } 566 567 <div class="product__imageslider__item @activeClass" data-id="bigimage_@Model.ImagePatternImages[i].Name" style="background-image: url('@imageResize')"> 568 <a href="@Model.ImagePatternImages[i].Value" data-fancybox="gallery"> </a> 569 570 </div> 571 } 572 573 @if (!String.IsNullOrEmpty(video.Value.ToString())) 574 { 575 <div class="product__imageslider__item" data-id="bigimage_@video.Name"> 576 <iframe width="420" height="315" 577 src="https://www.youtube.com/embed/@video.Value.ToString()" 578 allowFullScreen='allowFullScreen'> 579 </iframe> 580 </div> 581 } 582 </div> 583 </div> 584 </div> 585 </div> 586 </div> 587 </div> 588 <div class="col-12 col-xl-6 col-xxl-5 col-xxl-push-1"> 589 590 <h1>@title <br/>@Model.ShortDescription</h1> 591 592 @if (dimensionsList.Count > 0) 593 { 594 <div class="productlist__item__fields product__fields text-primary font-weight-bold float-left float-lg-none"> 595 @foreach (var dimension in dimensionsList) 596 { 597 <span> 598 @dimension.Item1.Substring(0, 1): @dimension.Item2 599 @if (dimension.Item1.ToLower().Contains("(m)")) 600 { 601 <text>M</text> 602 } 603 else 604 { 605 <text>MM</text> 606 } 607 </span> 608 } 609 </div> 610 } 611 612 <div class="product__number font-weight-bold">@Translate("Varenummer"): @Model.Number</div> 613 614 @if (Convert.ToBoolean(hideBuy.Value) == false && priceProduct > 0) 615 { 616 var serializedpricepoints = JsonConvert.SerializeObject(lu); 617 <div class="product__total-price"> 618 <span class="js-calculated-total-price" data-serializedpricepoints='@serializedpricepoints'></span> DKK 619 <div class="productlist__item__price__vat product__total-price__vat">eksl. moms</div> 620 </div> 621 622 if (Dynamicweb.Core.Converter.ToDecimal(oldprice.Value) > 0) 623 { 624 <span class="productlist__item__oldprice">@string.Format("{0:0.00}", oldprice.Value) DKK</span> 625 } 626 } 627 628 @if (priceProduct > 0) 629 { 630 <form method="post" class="js-product-form"> 631 <div class="row"> 632 <div class="col-12 col-lg-5 mb-4"> 633 634 <input type="hidden" name="ProductID" value="@Model.Id" /> 635 <input type="hidden" name="CartCmd" value="add" /> 636 <div class="product__quantity"> 637 <div class="row h-100 px-4"> 638 <div class="col-4 col-lg-2 px-lg-0"> 639 <div class="product__textwrapper__amountwrapper h-100"> 640 <div class="row h-100 text-right"> 641 <div class="col-12"> 642 <span class="fas fa-sort-up product__textwrapper__amountwrapper--increase increase"></span> 643 </div> 644 <div class="col-12 mt-auto"> 645 <span class="fas fa-sort-down product__textwrapper__amountwrapper--decrease decrease"></span> 646 </div> 647 </div> 648 </div> 649 </div> 650 <div class="col-8 col-lg-10 pl-lg-0"> 651 <div class="bg-light h-100 rounded ml-2 product__textwrapper__amountwrapper__content"> 652 <input value="@product.PurchaseMinimumQuantity" name="Quantity" id="amount" class=" rounded product__textwrapper__amountwrapper__input border-0" type="number" min="@product.PurchaseMinimumQuantity" /> 653 <span class="product__textwrapper__amountwrapper__text">stk</span> 654 </div> 655 </div> 656 </div> 657 </div> 658 </div> 659 <div class="col-12 col-lg-7 p-0"> 660 <button class="product__textwrapper__submit btn btn-primary rounded-pill js-basket-popup-open" data-productid title="@Translate("Add_to_cart", "Add to cart")" type="submit"> 661 Tilføj til kurv <i class="far fa-shopping-cart pl-3"></i> 662 </button> 663 </div> 664 </div> 665 </form> 666 } 667 668 669 <div class="product__infoprices__wrapper"> 670 <div class="row h-100"> 671 <div class="col-12 col-lg-5"> 672 673 @if (Convert.ToBoolean(hideBuy.Value) == false && priceProduct > 0) 674 { 675 var parentId = Dynamicweb.Ecommerce.Products.Group.GetGroupById(Model.PrimaryOrDefaultGroup.Id).PrimaryParentGroupId; 676 var parent = Dynamicweb.Ecommerce.Products.Group.GetGroupById(parentId); 677 678 <div class="product__price font-weight-bold"> 679 Pris pr. @baseUnit.Value.ToString().ToLower() ved @product.PurchaseMinimumQuantity 680 <div class="h3">@string.Format("{0:0.00}", pricesBcQuantities.FirstOrDefault().DiscountedPrice) DKK</div> 681 <div class="productlist__item__price__vat">eksl. moms</div> 682 </div> 683 684 if (Dynamicweb.Core.Converter.ToDecimal(oldprice.Value) > 0) 685 { 686 <span class="productlist__item__oldprice">@string.Format("{0:0.00}", oldprice.Value) DKK</span> 687 } 688 } 689 690 <dl class="product__info row"> 691 <dt class="col-6">Pakke af:</dt> 692 <dd class="col-6">@packedOfNumber.Value.ToString()</dd> 693 @if (!String.IsNullOrEmpty(ydrePakning.Value.ToString()) && ydrePakning.Value.ToString() != "0") 694 { 695 <dt class="col-6">Ydre kolli:</dt> 696 <dd class="col-6">@ydrePakning.Value.ToString()</dd> 697 } 698 @if (!String.IsNullOrEmpty(qtyOnPallet.Value.ToString()) && qtyOnPallet.Value.ToString() != "0") 699 { 700 <dt class="col-6">Antal pr. palle:</dt> 701 <dd class="col-6">@qtyOnPallet.Value.ToString()</dd> 702 } 703 </dl> 704 </div> 705 <div class="col-12 col-lg-7"> 706 @if (pricesBcQuantities.Count > 0 && Convert.ToBoolean(hideBuy.Value) == false && priceProduct > 0) 707 { 708 <dl class="row product__prices bg-white"> 709 @foreach (var price in pricesBcQuantities) 710 { 711 <dt class="col-5 col-xxl-4 text-right p-0">@Convert.ToDouble(price.Quantity) @price.BaseUnitOfMeasure.ToLower() <span>=</span></dt> 712 <dd class="col-7 col-xxl-8 text-left">@string.Format("{0:0.00}", price.DiscountedPrice) DKK pr. @price.BaseUnitOfMeasure.ToLower()</dd> 713 } 714 </dl> 715 <div class="product__prices__vat">Priser angives eksl. moms</div> 716 } 717 </div> 718 </div> 719 </div> 720 </div> 721 </div> 722 723 724 <div id="accordion"> 725 <div class="product__specifications card"> 726 <div class="product__specifications__header" id="header"> 727 <div class="mb-0"> 728 <a href="#" class="btn btn-link collapsed text-light w-100 panel-title" data-toggle="collapse" data-target="#productdetails" aria-expanded="false" aria-controls="productdetails"> 729 <h2>Specifikationer</h2> 730 </a> 731 </div> 732 </div> 733 <div id="productdetails" class="collapse" data-parent="#accordion"> 734 <div class="card-body"> 735 <div class="row"> 736 @foreach (var item in Model.ProductCategories.Where(x => x.Key.Equals("ImportedNAVItemAttributes"))) 737 { 738 foreach (var field in item.Value.Fields) 739 { 740 var count = 1; 741 if (field.Value.Value != null) 742 { 743 if (field.Value.Value.GetType() == typeof(List<Dynamicweb.Ecommerce.ProductCatalog.FieldOptionValueViewModel>)) 744 { 745 var f = (List<Dynamicweb.Ecommerce.ProductCatalog.FieldOptionValueViewModel>)field.Value.Value; 746 747 count = f.Count; 748 } 749 } 750 751 if (field.Value.Value != null && !string.IsNullOrWhiteSpace(field.Value.Value.ToString()) && count > 0 && field.Value.Value.ToString() != "0") 752 { 753 <div class="col-12 col-md-6 col-lg-3"> 754 <div class="product__specifications__field"> 755 <p> 756 <strong>@field.Value.Name</strong> 757 </p> 758 759 @if (field.Value.Value.GetType() == typeof(List<Dynamicweb.Ecommerce.ProductCatalog.FieldOptionValueViewModel>)) 760 { 761 var f = (List<Dynamicweb.Ecommerce.ProductCatalog.FieldOptionValueViewModel>)field.Value.Value; 762 if (f.Count > 0) 763 { 764 var value = f[0].Name; 765 <p>@value</p> 766 } 767 } 768 else 769 { 770 var value = field.Value.Value.ToString(); 771 if (value == "True") 772 { 773 value = "Ja"; 774 } 775 if (value == "False") 776 { 777 value = "Nej"; 778 } 779 <p>@value</p> 780 } 781 782 </div> 783 </div> 784 } 785 } 786 } 787 </div> 788 <div> 789 @if (!String.IsNullOrWhiteSpace(@Model.LongDescription)) 790 { 791 <h3>Beskrivelse</h3> 792 @Model.LongDescription 793 } 794 795 </div> 796 </div> 797 </div> 798 </div> 799 </div> 800 801 <div class="product__relatedproducts"> 802 @if (relatedProducts != null && relatedProducts.Count() > 0) 803 { 804 <h2>@Translate("Relaterede varer"):</h2> 805 806 @HelperRenderProductSpotList(@listViewModel.Products.ToList()) 807 } 808 </div> 809 </div> 810 </div> 811 </div> 812 </div> 813 814 <section class="basket__popup d-none"> 815 <div class="container-fluid"> 816 <div class="row no-args no-gutters"> 817 <div class="col-12"> 818 <div class="row no-gutters"> 819 <div class="col-11"> 820 <p class="basket__popup__title">Tilføjet til din kurv</p> 821 </div> 822 <div class="col-1 d-flex"> 823 <i class="fal fa-times js-basket-popup-close"></i> 824 </div> 825 </div> 826 <div class="basket__popup__line"></div> 827 </div> 828 <div class="col-12"> 829 <div class="basket__popup__product__item"> 830 @{ 831 var resizedImage = VestjyskMarketing.Helpers.ImageHelper.ResizeImage(Model.DefaultImage.Value, 100, 100); 832 string productLink = "/Default.aspx?ID=" + webshopPageId + "&amp;GroupID=" + Model.PrimaryOrDefaultGroup.Id + "&amp;ProductID=" + Model.Id; 833 } 834 <div class="row no-gutters"> 835 <div class="d-none d-lg-flex col-3 basket__popup__product__item__image d-lg-flex align-self-center" style="background-image: url(@resizedImage)"></div> 836 <div class="col-12 col-lg-9"> 837 <div class="row no-gutters"> 838 <div class="d-lg-none col-3 basket__popup__product__item__image" style="background-image: url(@resizedImage)"></div> 839 840 <div class="col-9 col-lg-12 "> 841 <div class="basket__popup__product__item__productname"> 842 <h2> 843 <a href="@productLink" title="@Translate("Gå til:") @title ">@title @Model.ShortDescription</a> 844 </h2> 845 </div> 846 </div> 847 848 <div class="col-12 text-center text-lg-left "> 849 @if (dimensionsList.Count > 0) 850 { 851 <div class="basket__popup__product__item__fields text-primary font-weight-bold"> 852 @foreach (var dimension in dimensionsList) 853 { 854 <span>@dimension.Item1.Substring(0, 1): @dimension.Item2 MM</span> 855 } 856 </div> 857 } 858 859 <div class="productlist__item__number font-weight-bold">@Translate("Varenummer ") @Model.Number:</div> 860 <div class="productlist__item__number font-weight-bold"> 861 @(orderlines?.FirstOrDefault(x => x.ProductId == Model.Id)?.Quantity) stk 862 </div> 863 864 <div class="basket__popup__product__item__price__container "> 865 <div class="basket__popup__product__item__price"> 866 <p> 867 <span class="productlist__item__price__highlight">@string.Format("{0:0.00}", lastPriceAddedCart) DKK</span> 868 <br /> 869 <span class="productlist__item__price__vat">eksl. moms</span> 870 </p> 871 </div> 872 </div> 873 </div> 874 </div> 875 </div> 876 </div> 877 </div> 878 <div class="basket__popup__line"></div> 879 <div class="basket__popup__bottoms"> 880 @if (neededAmountFeeShipping > 0) 881 { 882 <p>Køb for <strong>@string.Format("{0:N2}", neededAmountFeeShipping) DKK mere</strong> og få gratis fragt</p> 883 } 884 <div class="row"> 885 <div class="col-6"> 886 <a class="btn btn-outline-light btn-primary rounded-pill btn-round btn-block basket__popup__bottoms__link" href="/kurv" title="@Translate("Gå til:") name ">Gå til kurv</a> 887 </div> 888 <div class="col-6"> 889 <a class="btn btn-outline-primary rounded-pill btn-round btn-block js-basket-popup-close" href="#" title="@Translate("Gå til:") name ">Shop videre</a> 890 </div> 891 </div> 892 </div> 893 <div class="basket__popup__product-spot"> 894 895 @if (listViewModel.Products != null && listViewModel.Products.Count() != 0 && false) 896 { 897 <p class="basket__popup__title">Relaterede varer</p> 898 <div class="basket__popup__line"></div> 899 <div class="basket__popup__product-spot__item"> 900 @for (int i = 0; i < listViewModel.Products.Count(); i++) 901 { 902 var backgroundClass = ""; 903 if (i % 2 == 0) 904 { 905 backgroundClass = ""; 906 } 907 else 908 { 909 backgroundClass = "gray"; 910 } 911 912 <div class="@backgroundClass"> 913 <div class="row no-gutters"> 914 @{ 915 var resizedImageRelatedProduct = VestjyskMarketing.Helpers.ImageHelper.ResizeImage(listViewModel.Products[i].DefaultImage.Value, 100, 100); 916 string productLinkRelatedProducts = "/Default.aspx?ID=" + webshopPageId + "&amp;GroupID=" + listViewModel.Products[i].PrimaryOrDefaultGroup.Id + "&amp;ProductID=" + listViewModel.Products[i].Id; 917 918 } 919 <div class="d-none d-lg-flex col-3 basket__popup__product-spot__item__image align-self-center" style="background-image: url(@resizedImageRelatedProduct)"></div> 920 <div class="col-12 col-lg-9"> 921 <div class="row no-gutters"> 922 <div class="d-lg-none col-3 basket__popup__product-spot__item__image" style="background-image: url(@resizedImageRelatedProduct)"></div> 923 924 <div class="col-9 col-lg-12 "> 925 <div class="basket__popup__product-spot__item__description"> 926 <p class="basket__popup__product-spot__item__title">@listViewModel.Products[i].Title</p> 927 <p class="basket__popup__product-spot__item__number">Varenummer: @listViewModel.Products[i].Number</p> 928 </div> 929 </div> 930 931 <div class="col-12"> 932 <div class="basket__popup__product-spot__item__content"> 933 <div class="row"> 934 <div class="col-7"> 935 <p class="basket__popup__product-spot__item__price">Priser fra <br class="d-lg-none" /> &nbsp;<strong>@string.Format("{0:0.00}", listViewModel.Products[i].Price.Price) DDK</strong></p> 936 <p class="basket__popup__product-spot__item__tax">ekskl. moms</p> 937 </div> 938 <div class="col-5 d-flex justify-content-end"> 939 <a class="btn btn-round align-self-end rounded-pill basket__popup__product-spot__item__link " href="@productLinkRelatedProducts">Se produkt</a> 940 </div> 941 </div> 942 </div> 943 </div> 944 </div> 945 </div> 946 </div> 947 </div> 948 } 949 </div> 950 } 951 </div> 952 </div> 953 </div> 954 </div> 955 </section> 956 957 @SnippetStart("script") 958 <script> 959 window.dataLayer = window.dataLayer || []; 960 window.dataLayer.push({ 961 'page_type': 'product', 962 'product_ids': '@Model.Number', 963 'value': '@priceProduct.ToString("F2", EnglishCulture)', 964 'currency': 'DKK' 965 }); 966 </script> 967 @SnippetEnd("script") 968 969 @SnippetStart("JavaScriptBottom") 970 <script> 971 972 $('#amount').change(function(e){ 973 var step = @Convert.ToInt32(@product.PurchaseQuantityStep); 974 var inputVal = e.target.value; 975 var result = inputVal / step; 976 e.target.value = Math.ceil(result) * step; 977 978 //calculate total price logic 979 var priceElem = $('.js-calculated-total-price'); 980 var parsedPricePoints = JSON.parse(priceElem.attr('data-serializedpricepoints')); 981 //sets initial unitprice 982 var unitPrice = parsedPricePoints[0].Price; 983 984 for (var i = 0; i < parsedPricePoints.length; i++) { 985 if ($(this).val() >= parsedPricePoints[i].Amount){ 986 unitPrice = parsedPricePoints[i].Price; 987 } 988 } 989 990 var totalPrice = e.target.value * unitPrice; 991 $(priceElem).text(totalPrice.toFixed(2).replace('.', ',')); 992 }); 993 994 $('.product__imagewrapper__zoom').on('click', function () { 995 //Trigger fancybox for currect image 996 $('.product__imageslider').find('.active').find('a').trigger('click'); 997 }); 998 999 var multiply = "@Convert.ToInt32(@product.PurchaseQuantityStep)"; 1000 $('.product__textwrapper__amountwrapper--increase, .product__textwrapper__amountwrapper--decrease').on('click', function () { 1001 var $amount = $('#amount'); 1002 var $this = $(this); 1003 1004 var intMultiply = parseInt(multiply) 1005 1006 if (isNaN(intMultiply) || intMultiply == 0) { 1007 intMultiply = 1; 1008 } 1009 1010 1011 if ($this.hasClass('decrease') && $amount.val() > @Convert.ToInt32(@product.PurchaseQuantityStep)) { 1012 $amount.val(parseInt($amount.val()) - intMultiply); 1013 } else if ($this.hasClass('increase')) { 1014 $amount.val(parseInt($amount.val()) + intMultiply); 1015 } 1016 1017 //calculate total price logic 1018 var priceElem = $('.js-calculated-total-price'); 1019 var parsedPricePoints = JSON.parse(priceElem.attr('data-serializedpricepoints')); 1020 //sets initial unitprice 1021 var unitPrice = parsedPricePoints[0].Price; 1022 1023 for (var i = 0; i < parsedPricePoints.length; i++) { 1024 if ($amount.val() >= parsedPricePoints[i].Amount){ 1025 unitPrice = parsedPricePoints[i].Price; 1026 } 1027 } 1028 1029 var totalPrice = $amount.val() * unitPrice; 1030 $(priceElem).text(totalPrice.toFixed(2).replace('.', ',')); 1031 }); 1032 1033 $(function (){ 1034 //calculate total price logic 1035 var $amount = $('#amount'); 1036 var priceElem = $('.js-calculated-total-price'); 1037 var parsedPricePoints = JSON.parse(priceElem.attr('data-serializedpricepoints')); 1038 //sets initial unitprice 1039 var unitPrice = parsedPricePoints[0].Price; 1040 1041 for (var i = 0; i < parsedPricePoints.length; i++) { 1042 if ($amount.val() >= parsedPricePoints[i].Amount){ 1043 unitPrice = parsedPricePoints[i].Price; 1044 } 1045 } 1046 1047 var totalPrice = $amount.val() * unitPrice; 1048 $(priceElem).text(totalPrice.toFixed(2).replace('.', ',')); 1049 }); 1050 </script> 1051 @SnippetEnd("JavaScriptBottom") 1052 @SnippetStart("EcommerceCanonical") 1053 @{ 1054 string fullUrl = "https://" + System.Web.HttpContext.Current.Request.Url.Host + System.Web.HttpContext.Current.Request.RawUrl; 1055 } 1056 <link rel="canonical" href="@fullUrl" /> 1057 @SnippetEnd("EcommerceCanonical")