Error executing template "Designs/Default/eCom/ProductCatalog/ProductList.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.Rendering.Translation.Source.GetTranslationSource(String designName, String moduleName, String cultureName)
   at Dynamicweb.Rendering.Template.TranslateText(String text, String defaultValue, String cultureName)
   at Dynamicweb.Rendering.TemplateBase`1.Translate(String text, String defaultValue)
   at CompiledRazorTemplates.Dynamic.RazorEngine_314168f031e64d489542a6782ca37780.<RenderSearch>b__50_0(TextWriter __razor_helper_writer) in E:\Dynamicweb.net\Solutions\Webshop\Files\Templates\Designs\Default\eCom\ProductCatalog\ProductList.cshtml:line 607
   at CompiledRazorTemplates.Dynamic.RazorEngine_314168f031e64d489542a6782ca37780.Execute() in E:\Dynamicweb.net\Solutions\Webshop\Files\Templates\Designs\Default\eCom\ProductCatalog\ProductList.cshtml:line 2832
   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 @inherits ViewModelTemplate<ProductListViewModel> 2 @using Dynamicweb; 3 @using Dynamicweb.Core; 4 @using Dynamicweb.Environment; 5 @using Dynamicweb.Environment.Helpers; 6 @using Dynamicweb.Rendering; 7 @using Dynamicweb.Ecommerce.ProductCatalog; 8 @using System.Linq; 9 @using Cookie = Dynamicweb.Environment.Cookie; 10 @using Gasa.ProductInformation.Helpers; 11 12 @using Dynamicweb.Ecommerce.Orders; 13 @using System.Globalization; 14 @using Dynamicweb.Security.UserManagement; 15 @using Dynamicweb.Security.UserManagement.Common.CustomFields; 16 @using Dynamicweb; 17 @using Dynamicweb.Core; 18 @using Dynamicweb.Environment; 19 @using Dynamicweb.Environment.Helpers; 20 @using Dynamicweb.Rendering; 21 @using Dynamicweb.Ecommerce.ProductCatalog; 22 @using System.Linq; 23 @using Gasa.ProductInformation; 24 @using Gasa.Calendar; 25 26 @* Note that this file will be inserted directly into another one by Dynamicweb IncludeFile 27 before evaluating the Razor code, so keep the syntax right *@ 28 29 30 @* global functions *@ 31 32 @functions { 33 bool checkIfFileExists(string imgURL) 34 { 35 return System.IO.File.Exists(System.Web.HttpContext.Current.Server.MapPath(imgURL)); 36 } 37 string FormatDiameter(string value) 38 { 39 if (string.IsNullOrEmpty(value)) 40 { 41 return value; 42 } 43 44 Decimal d; 45 if (Decimal.TryParse(value, out d)) 46 { 47 return Converter.ToDouble(value).ToString("0.0", Dynamicweb.Frontend.PageView.Current().Area.CultureInfo.NumberFormat); 48 //return d.ToString("0.0", Base.GetCulture(true)); 49 } 50 51 return value; 52 } 53 54 string FormatPrice(string value) 55 { 56 if (string.IsNullOrEmpty(value)) 57 { 58 return value; 59 } 60 61 Decimal d; 62 if (Decimal.TryParse(value, out d)) 63 { 64 return Converter.ToDouble(value).ToString("0.00", Dynamicweb.Frontend.PageView.Current().Area.CultureInfo.NumberFormat); 65 } 66 67 return value; 68 } 69 70 string AvailableDeliveryDay(int leadDays) 71 { 72 DateTime today = DateTime.Now.Date; 73 DateTime availableDate = today; 74 DateTime deliveryDate = CalenderHelper.ParseDateTime(Dynamicweb.Ecommerce.Common.Context.Cart.OrderFieldValues.GetOrderFieldValue("DeadlineTime").Value); 75 TimeSpan daysDifference = deliveryDate - today; 76 CultureInfo localLanguage = System.Threading.Thread.CurrentThread.CurrentCulture; 77 string result; 78 79 int leadWeekendDays = 0; 80 81 82 // check how many weekends within lead days 83 for (var i = 0; i < leadDays; i++) 84 { 85 if (availableDate.AddDays(i).DayOfWeek == DayOfWeek.Saturday) 86 { 87 leadWeekendDays++; 88 } 89 else if (availableDate.AddDays(i).DayOfWeek == DayOfWeek.Sunday) 90 { 91 leadWeekendDays++; 92 } 93 } 94 95 // check how many weekends after lead weekdays 96 for (var i = 0; i < leadWeekendDays; i++) 97 { 98 if (availableDate.AddDays(leadDays + i).DayOfWeek == DayOfWeek.Saturday) 99 { 100 leadWeekendDays++; 101 } 102 else if (availableDate.AddDays(leadDays + i).DayOfWeek == DayOfWeek.Sunday) 103 { 104 leadWeekendDays++; 105 } 106 } 107 108 var leadDaysTotal = leadWeekendDays + leadDays; 109 110 availableDate = availableDate.AddDays(leadDaysTotal); 111 112 if (daysDifference.TotalDays >= leadDaysTotal && availableDate <= deliveryDate) 113 { 114 result = null; 115 } 116 else 117 { 118 result = availableDate.ToString("dd-MM-yyyy", localLanguage); 119 } 120 //result=daysDifference.TotalDays.ToString(); 121 return result; 122 } 123 124 /* 125 bool EnableEditing() 126 { 127 return EnableEditableBarcode(); 128 } 129 */ 130 131 bool? _enableManufacturerPage; 132 bool EnableManufacturerPage() 133 { 134 if (!_enableManufacturerPage.HasValue) 135 { 136 if (Pageview.Page.PropertyItem != null && Converter.ToBoolean(Pageview.Page.PropertyItem["EnableManufacturer"])) 137 { 138 _enableManufacturerPage = true; 139 } 140 else 141 { 142 _enableManufacturerPage = false; 143 } 144 } 145 return _enableManufacturerPage.Value; 146 } 147 148 ///* generic validation of custom user fields */ 149 //bool? returnCustomUserFieldValidation(string CustomerUserFieldString) 150 //{ 151 // return GetCustomUserField<bool>(user, CustomerUserFieldString); 152 //} 153 154 155 bool? _displayPricesInclVat; 156 bool DisplayPricesInclVat() 157 { 158 if (!_displayPricesInclVat.HasValue) 159 { 160 _displayPricesInclVat = GetCustomUserField<bool>("AccessUser_DisplayPricesInclVat"); 161 } 162 return _displayPricesInclVat.Value; 163 } 164 165 bool? _enableEditableItemNumber; 166 bool EnableEditableItemNumber() 167 { 168 if (!_enableEditableItemNumber.HasValue) 169 { 170 _enableEditableItemNumber = GetCustomUserField<bool>("AccessUser_EnableEditableItemNumber"); 171 } 172 return _enableEditableItemNumber.Value; 173 } 174 175 //AccessUser_EnableManufacturerFiltering 176 bool? _enableManufacturerFiltering; 177 bool EnableManufacturerFiltering(bool chkEnableManufacturerPageEnableManufacturerPage = true) 178 { 179 if (chkEnableManufacturerPageEnableManufacturerPage && !EnableManufacturerPage()) 180 return false; 181 182 if (!_enableManufacturerFiltering.HasValue) 183 { 184 _enableManufacturerFiltering = GetCustomUserField<bool>("AccessUser_EnableManufacturerFiltering"); 185 } 186 return _enableManufacturerFiltering.Value; 187 } 188 189 bool? _enableCustomerItemNumber; 190 bool EnableCustomerItemNumber() 191 { 192 if (!_enableCustomerItemNumber.HasValue) 193 { 194 _enableCustomerItemNumber = GetCustomUserField<bool>("AccessUser_EnableCustomerItemNumber"); 195 } 196 return _enableCustomerItemNumber.Value; 197 } 198 199 bool? _enableEditableRetailPrice; 200 bool EnableEditableRetailPrice() 201 { 202 if (!_enableEditableRetailPrice.HasValue) 203 { 204 _enableEditableRetailPrice = GetCustomUserField<bool>("AccessUser_EnableEditableRetailPrice"); 205 } 206 return _enableEditableRetailPrice.Value; 207 } 208 209 bool? _enableEditableBarcode; 210 bool EnableEditableBarcode() 211 { 212 if (!_enableEditableBarcode.HasValue) 213 { 214 _enableEditableBarcode = GetCustomUserField<bool>("AccessUser_EnableEditableBarcode"); 215 } 216 return _enableEditableBarcode.Value; 217 } 218 219 bool? _enableCustomerRetailPrice; 220 bool EnableCustomerRetailPrice() 221 { 222 if (!_enableCustomerRetailPrice.HasValue) 223 { 224 _enableCustomerRetailPrice = GetCustomUserField<bool>("AccessUser_EnableCustomerRetailPrice"); 225 } 226 return _enableCustomerRetailPrice.Value; 227 } 228 229 bool? _enableCustomerBarcode; 230 bool EnableCustomerBarcode() 231 { 232 if (!_enableCustomerBarcode.HasValue) 233 { 234 _enableCustomerBarcode = GetCustomUserField<bool>("AccessUser_EnableCustomerBarcode"); 235 } 236 return _enableCustomerBarcode.Value; 237 238 } 239 240 bool? _enableComments; 241 bool EnableComments() 242 { 243 if (!_enableComments.HasValue) 244 { 245 _enableComments = GetCustomUserField<bool>("AccessUser_EnableCommentOnLine"); 246 } 247 return _enableComments.Value; 248 } 249 250 bool? _enableMinimumCCQuantity; 251 bool EnableMinimumCCQuantity() 252 { 253 if (!_enableMinimumCCQuantity.HasValue) 254 { 255 _enableMinimumCCQuantity = GetCustomUserField<bool>("AccessUser_EnableMinimumCCQuantity"); 256 } 257 return _enableMinimumCCQuantity.Value; 258 } 259 bool? _enableFullCCCheck; 260 bool EnableFullCCCheck() 261 { 262 if (!_enableFullCCCheck.HasValue) 263 { 264 _enableFullCCCheck = GetCustomUserField<bool>("AccessUser_EnableFullCCCheck"); 265 } 266 return _enableFullCCCheck.Value; 267 } 268 269 bool? _enableDisplayGrossMargin; 270 bool EnableDisplayOfGrossMargin() 271 { 272 if (DisablePrices()) 273 return false; 274 275 if (!_enableDisplayGrossMargin.HasValue) 276 { 277 _enableDisplayGrossMargin = GetCustomUserField<bool>("AccessUser_DisplayGrossMargin"); 278 } 279 return _enableDisplayGrossMargin.Value; 280 } 281 282 string GetGrossMargin(double retailPrice, double salesPrice) 283 { 284 var resultValue = ((retailPrice - salesPrice) * 100) / retailPrice; 285 return Converter.ToString(Math.Round(resultValue, 2)) + "%"; 286 } 287 288 289 double? _minimumCCQuantity; 290 double MinimumCCQuantity(string flag = "") 291 { 292 if (!_minimumCCQuantity.HasValue) 293 { 294 _minimumCCQuantity = GetCustomUserField<double>("AccessUser_MinimumCCQuantity" + flag.ToUpper()); 295 } 296 return _minimumCCQuantity.Value; 297 } 298 299 bool? _disablePrices; 300 bool DisablePrices() 301 { 302 if (!_disablePrices.HasValue) 303 { 304 _disablePrices = GetCustomUserField<bool>("AccessUser_DisablePrices"); 305 } 306 return _disablePrices.Value; 307 } 308 309 double? _fullCCCheckDeviation; 310 double FullCCCheckDeviation() 311 { 312 if (!_fullCCCheckDeviation.HasValue) 313 { 314 _fullCCCheckDeviation = GetCustomUserField<double>("AccessUser_FullCCCheckDeviation"); 315 } 316 317 return _fullCCCheckDeviation.Value; 318 } 319 320 //bool HasReachedMinimumQuantity() 321 //{ 322 // if (!EnableMinimumCCQuantity()) 323 // { 324 // return true; 325 // } 326 327 // var orderlinesGroupByCode = GetLoop("OrderLines").GroupBy(o => o.GetString("Ecom:Product:Field.NavCompanyCode")) 328 // .Select(o => new { 329 // Flag = o.FirstOrDefault().GetString("Ecom:Product:Field.NavCompanyCode"), 330 // CCRate = o.Sum(f => f.GetInteger("Ecom:Order:OrderLine.Quantity") * f.GetDouble("CustomerSpecificProductInformation.CCRate")) 331 // }); 332 333 // if (orderlinesGroupByCode.Count() == orderlinesGroupByCode.Where(o => o.CCRate >= MinimumCCQuantity(o.Flag)).Count()) 334 // { 335 // return true; 336 // } 337 338 // return false; 339 //} 340 341 //bool HasPassedFullCCCheckDeviationCheck() 342 //{ 343 // if (!EnableFullCCCheck()) 344 // { 345 // return true; 346 // } 347 348 // var orderlinesGroupByCode = GetLoop("OrderLines").GroupBy(o => o.GetString("Ecom:Product:Field.NavCompanyCode")) 349 // .Select(o => new { CCRate = o.Sum(f => f.GetInteger("Ecom:Order:OrderLine.Quantity") * f.GetDouble("CustomerSpecificProductInformation.CCRate")) }); 350 351 // if (orderlinesGroupByCode.Count() == orderlinesGroupByCode.Where(o => (o.CCRate % 1) == 0 || LessOrEqual((o.CCRate % 1), FullCCCheckDeviation()) || LessOrEqual(Math.Abs(1 - (o.CCRate % 1)), FullCCCheckDeviation())).Count()) 352 // { 353 // return true; 354 // } 355 356 // return false; 357 //} 358 359 //AE: Workaround for comparing doubles 360 bool LessOrEqual(double d1, double d2) 361 { 362 return d1 < d2 || Math.Abs(d1 - d2) <= 0.0000001; 363 } 364 365 /* 366 bool DisableComments() 367 { 368 User user = User.get_Current(PagePermissionLevels.Frontend); 369 370 return GetCustomField<bool>(user, "AccessUser_EnableCommentOnLine"); 371 } 372 */ 373 //static T GetCustomOrderLineField<T>(OrderLine orderLine, string customSystemFieldName) 374 //{ 375 // OrderLineFieldValue myFieldValue = 376 // orderLine.OrderLineFieldValues.FirstOrDefault(cfv => cfv.OrderLineFieldSystemName == customSystemFieldName); 377 378 // if (myFieldValue != null) 379 // { 380 // return (T)Convert.ChangeType(myFieldValue.Value, typeof(T)); 381 // } 382 383 // // Return default(T) which means you'll return null 384 // return default(T); 385 //} 386 387 //static T GetCustomOrderLineField<T>(LoopItem orderLine, string customSystemFieldName) 388 //{ 389 // var template = 390 // orderLine.GetLoop("Order.OrderLineFields").FirstOrDefault(o => o.GetString("Ecom:Order:OrderLine.OrderLineField.SystemName") == customSystemFieldName); 391 392 // if (template != null) 393 // { 394 // return (T)Convert.ChangeType(template.GetValue("Ecom:Order:OrderLine.OrderLineField.Value.Clean"), typeof(T)); 395 // } 396 397 // // Return default(T) which means you'll return null 398 // return default(T); 399 //} 400 401 Dynamicweb.Security.UserManagement.User _user = null; 402 T GetCustomUserField<T>(string customSystemFieldName) 403 { 404 if (_user == null) 405 { 406 _user = Dynamicweb.Security.UserManagement.User.GetCurrentExtranetUser(); 407 } 408 409 if (_user != null) 410 { 411 CustomFieldValue myFieldValue = _user.CustomFieldValues.FirstOrDefault(cfv => cfv.CustomField.SystemName == customSystemFieldName); 412 413 try 414 { 415 if (myFieldValue != null) 416 { 417 return (T)Convert.ChangeType(myFieldValue.Value, typeof(T)); 418 } 419 } 420 catch (Exception) 421 { 422 return default(T); 423 } 424 } 425 426 // Return default(T) which means you'll return null 427 return default(T); 428 } 429 430 431 ICollection<Dynamicweb.Ecommerce.Orders.OrderLineField> SortOrderLineFields(ICollection<Dynamicweb.Ecommerce.Orders.OrderLineField> loop) 432 { 433 return loop 434 .OrderByDescending(o => o.SystemName == "OrderLineComment") 435 .ThenByDescending(o => o.SystemName == "OrderLineRetailPrice") 436 .ThenByDescending(o => o.SystemName == "OrderLineItemNumber") 437 .ThenByDescending(o => o.SystemName == "OrderLineEAN").ToList(); 438 } 439 440 bool IsInCart(ProductViewModel product) 441 { 442 var cart = Dynamicweb.Ecommerce.Common.Context.Cart; 443 if (cart != null) 444 { 445 foreach (var ol in cart.OrderLines) 446 { 447 if (ol.ProductId == product.Id) 448 { 449 return true; 450 } 451 } 452 } 453 return false; 454 } 455 456 string GetProductInfoValue(ProductInformation productInfo, string key) 457 { 458 if (productInfo.Values != null) 459 { 460 object value; 461 if (productInfo.Values.TryGetValue(key, out value)) 462 { 463 if (!string.IsNullOrEmpty(Converter.ToString(value))) 464 { 465 return Converter.ToString(value); 466 } 467 } 468 } 469 return string.Empty; 470 } 471 472 } 473 474 475 @* html helpers section *@ 476 477 478 @helper renderToolTip() 479 { 480 var jsSuggestionStock = "<span class='js-suggestion-stock'></span>"; 481 <div class="hide js-tooltip-content quantity-tooltip-content"> 482 <h4 class="title"> 483 @Translate("Smartpage:Product.PackageSizeCeiled", "Antallet vil blive opskrevet til") <span class="js-package-size-quantity"></span> <a href="#" data-toggle="tooltip" data-placement="top" class="js-package-size-single package-size-single" title='@Translate("Smartpage:Product.PackageSizeCeiled.singleProduct.Text", "Det ønskede antal vare stemmer ikke overens med kollistørrelsen")'><i class="glyphicon glyphicon-info-sign"></i></a> 484 </h4> 485 <button class="btn btn-xs btn-info js-package-size-cancel" data-toggle="clickover"><i class="glyphicon glyphicon-remove"></i></button> 486 <button class="btn btn-xs btn-primary js-package-size-ok" data-toggle="clickover"><i class="glyphicon glyphicon-ok"></i></button> 487 </div> 488 489 <div class="hide js-tooltip-smaller-quantity quantity-tooltip-content"> 490 <h4 class="title"> 491 @Translate("Smartpage:Popover.OutOfStockText.LessQuantity", "Varen blev ikke tilføjet til kurven, forsøg med et mindre antal") 492 </h4> 493 <button class="btn btn-xs btn-info js-close-out-of-stock" data-toggle="clickover"><i class="glyphicon glyphicon-ok"></i></button> 494 </div> 495 496 <div class="hide js-tooltip-stock-content quantity-tooltip-content"> 497 <h4 class="title"> 498 @Translate("Smartpage:Popover.OutOfStockText", "Varen blev ikke tilføjet til kurven, fordi vi har ikke flere på lager") 499 </h4> 500 <button class="btn btn-xs btn-info js-close-out-of-stock" data-toggle="clickover"><i class="glyphicon glyphicon-ok"></i></button> 501 </div> 502 503 <div class="hide js-tooltip-stock-suggestion quantity-tooltip-content"> 504 <h4 class="title"> 505 @Translate("Smartpage:Popover.OutOfStockText.Suggestion", String.Format("Vi har kun {0} på lager. Vil du ændre antal?", jsSuggestionStock)) 506 </h4> 507 <button class="btn btn-xs btn-info js-cancel-out-of-stock" data-toggle="clickover"><i class="glyphicon glyphicon-remove"></i></button> 508 <button class="btn btn-xs btn-info js-accept-out-of-stock" data-toggle="clickover"><i class="glyphicon glyphicon-ok"></i></button> 509 </div> 510 } 511 512 513 @helper AddedToCart(ProductViewModel i, string cssClass) 514 { 515 var cart = Dynamicweb.Ecommerce.Common.Context.Cart; 516 string cssIsInCart = !IsInCart(i) ? "hide" : ""; 517 518 <span class='label label-success js-in-cart in-cart @cssClass @cssIsInCart'><i class="glyphicon glyphicon-shopping-cart"></i> @Translate("Smartpage:AddedInCart", "added")</span> 519 } 520 521 @helper SingleAddedToCart(ProductViewModel product) 522 { 523 string cssIsInCart = !IsInCart(product) ? "hide" : ""; 524 <span class='label label-success in-cart js-in-cart product @cssIsInCart'><i class="glyphicon glyphicon-shopping-cart"></i> @Translate("Smartpage:AddedInCart", "added")</span> 525 } 526 527 @helper SingleStockStatus(ProductViewModel product) 528 { 529 bool outOfStock = product.StockLevel <= 0; 530 bool isServiceProduct = Dynamicweb.Ecommerce.Services.Products.GetProductById(product.Id, product.VariantId, Dynamicweb.Ecommerce.Common.Context.LanguageID, false).Type == Dynamicweb.Ecommerce.Products.ProductType.Service; 531 532 <div class='stock-status single-product'> 533 @if (outOfStock && !isServiceProduct) 534 { 535 <span class="label label-danger js-out-of-stock">@Translate("Smartpage:OutOfStock", "Ikke på lager")</span> 536 } 537 </div> 538 } 539 540 @helper ListStockStatus(ProductViewModel i, string currentViewMode) 541 { 542 bool outOfStock = i.StockLevel <= 0; 543 bool isServiceProduct = Dynamicweb.Ecommerce.Services.Products.GetProductById(i.Id, i.VariantId, Dynamicweb.Ecommerce.Common.Context.LanguageID, false).Type == Dynamicweb.Ecommerce.Products.ProductType.Service; 544 545 <div class='stock-status @currentViewMode'> 546 @if (outOfStock && !isServiceProduct) 547 { 548 <span class="label label-danger js-out-of-stock">@Translate("Smartpage:OutOfStock", "Ikke på lager")</span> 549 } 550 @if (!isServiceProduct && !outOfStock) { 551 <span class='label label-success'>@i.StockLevel @Translate("GASA.LeftOnStock", "left on stock")</span> 552 } 553 </div> 554 } 555 556 557 @helper PricesWithVATStatus(string positionCSS) { 558 if (DisplayPricesInclVat()) 559 { 560 <p class='vat-message text-muted text-center @positionCSS'>@Translate("Smartpage:PricesIncludeVAT.Message", "Alle priser er inkl. Moms")</p> 561 } 562 else 563 { 564 <p class='vat-message text-muted text-center @positionCSS'>@Translate("Smartpage:PricesDoNotIncludeVAT.Message", "Alle priser er ekskl. Moms")</p> 565 } 566 } 567 568 @helper RenderManufacturer(string manufacturerId, string manufacturerName, string manufacturerWebsiteUrl) 569 { 570 if (EnableManufacturerFiltering()) 571 { 572 var name = manufacturerName + "/" + manufacturerId; 573 if (!string.IsNullOrEmpty(manufacturerWebsiteUrl)) 574 { 575 <a class="manufacturer-info-link" href="@manufacturerWebsiteUrl" target="_blank">@name</a> 576 } 577 else 578 { 579 <span class="manufacturer-info">@name</span> 580 } 581 } 582 } 583 @inherits ViewModelTemplate<ProductListViewModel> 584 @using System.Web 585 @using Dynamicweb; 586 @using Dynamicweb.Rendering; 587 @using Dynamicweb.Ecommerce.ProductCatalog; 588 589 @helper RenderSearch() 590 { 591 @SnippetStart("NavigationGroups") 592 593 var originalLink = "/Default.aspx?ID=" + HttpContext.Current.Request["id"].ToString(); 594 595 string groupId = System.Web.HttpContext.Current.Request["GroupId"]; 596 string groupName = string.Empty; 597 598 if (!string.IsNullOrEmpty(groupId)) 599 { 600 var group = Dynamicweb.Ecommerce.Services.ProductGroups.GetGroup(groupId); 601 if (group != null) 602 { 603 groupName = group.Name; 604 } 605 } 606 607 <button type="button" class="btn btn-default btn-square dropdown-toggle js-select-group-dropdown" id="js-search-filters" data-toggle="dropdown" aria-expanded="false" data-whole-site="false"><span class="js-text-label hidden-xs hidden-sm">@Translate("Smartpage:Search.Select.InCategory", "in") @groupName</span> <span class="caret"></span></button> 608 <ul class="dropdown-menu js-search-dropdown-menu" role="menu" id="js-search-filters"> 609 <li><a class="js-search-group-choice" href='@originalLink' data-whole-site="true">@Translate("Smartpage:Search.WholeSite", "Whole site")</a></li> 610 <li><a class="js-search-group-choice" href='@("/Default.aspx?ID=" + Pageview.Page.ID + "&GroupId=" + groupId)' data-whole-site="false">@Translate("Smartpage:Search.Select.InCategory", "in") @groupName</a></li> 611 </ul> 612 613 @SnippetEnd("NavigationGroups") 614 } 615 616 @functions{ 617 public class GoogleImpression 618 { 619 public string name { get; set; } 620 public string id { get; set; } 621 public string price { get; set; } 622 public string list { get; set; } 623 public string url { get; set; } 624 public string currency { get; set; } 625 public int position { get; set; } 626 public string brand { get; set; } 627 } 628 } 629 630 @inherits ViewModelTemplate<ProductListViewModel> 631 @using Dynamicweb; 632 @using Dynamicweb.Core; 633 @using Dynamicweb.Environment; 634 @using Dynamicweb.Rendering; 635 @using Dynamicweb.Ecommerce.ProductCatalog; 636 @using System.Linq; 637 @using Gasa.ProductInformation; 638 @using Gasa.PriceInformation; 639 @using Gasa.ProductInformation.Helpers; 640 @using Dynamicweb.Ecommerce.Prices; 641 @using Gasa.Calendar; 642 643 @helper RenderListView() 644 { 645 646 <form method="post" class="js-basket-add js-set-tabindex js-product-form-container" autocomplete="false" data-submit-url='@Pageview.Area.Item["JsonCart"]'> 647 <input type="hidden" name="CartCmd" value="addmulti" /> 648 <input type="hidden" name="Spleadday-accepted" class="js-leadday-accepted" value="false" /> 649 <input type="hidden" name="Spleadday-declined" class="js-leadday-declined" value="false" /> 650 @{ 651 652 int pageNum = Math.Max(Dynamicweb.Context.Current.Request.GetInt32("PageNum"), 1); 653 var isLoggedIn = Dynamicweb.Security.UserManagement.User.IsExtranetUserLoggedIn(); 654 var defaultImage = !string.IsNullOrWhiteSpace(Converter.ToString(Pageview.Area.Item["DefaultImage"])) ? Converter.ToString(Pageview.Area.Item["DefaultImage"]) : "/Files/images/default-image.png"; 655 656 var baseLoopCounter = Model.PageSize * (pageNum - 1); 657 int productLoopCounter = 0; 658 659 var productService = Dynamicweb.Ecommerce.Services.Products; 660 var helperService = new CustomProductFieldHelpers(); 661 string currentPageLink = "/Default.aspx?ID=" + GetPageIdByNavigationTag("SpProducts"); 662 string host = Converter.ToBoolean(Pageview.Area.Item["CDNActivate"]) ? Converter.ToString(Pageview.Area.Item["CDNUrl"]) : string.Empty; 663 664 CultureInfo culture = CultureInfo.CreateSpecificCulture("en-US"); 665 } 666 <div class="clearfix"></div> 667 <div class="col-sm-12"> 668 669 <div class="product-list list-group js-grid-group"> 670 671 @foreach (var i in Model.Products) 672 { 673 productLoopCounter++; 674 675 var manufacturerName = i.Manufacturer.Name; 676 var manufacturerWebsiteUrl = i.Manufacturer.Web; 677 var manufacturerId = i.Manufacturer.Id; 678 679 var product = productService.GetProductById(i.Id, i.VariantId, Dynamicweb.Ecommerce.Common.Context.LanguageID, false); 680 var productInfo = new ProductInformation(product, Dynamicweb.Security.UserManagement.User.GetCurrentExtranetUser()?.CustomerNumber); 681 var priceInformation = new PriceInformation(product, productInfo); 682 683 string productLink = currentPageLink + "&amp;GroupId=" + product.PrimaryGroupId + "&amp;ProductID=" + product.Id; 684 685 var images = i.ImagePatternImages; 686 string image = defaultImage; 687 688 if (images.Any()) 689 { 690 image = images.FirstOrDefault().Value; 691 } 692 693 int minQty = Converter.ToInt32(helperService.GetFieldValue("MinimumPurchaseQuantityLimit", i.ProductFields)); 694 if (minQty == 0) 695 { 696 switch (Converter.ToString(helperService.GetFieldValue("MinimumPurchaseQuantity", i.ProductFields)).ToLower().Trim()) 697 { 698 case "layer": 699 minQty = productInfo.ColliPerLayer; 700 break; 701 case "cc": 702 minQty = productInfo.ColliPerCc; 703 break; 704 default: 705 minQty = 1; 706 break; 707 } 708 } 709 710 DateTime availableFrom = DateTime.MinValue; 711 bool isDeliverable = Converter.ToDouble(priceInformation.Prices.PricePerColliUnit.Price) > 0 && DateTime.TryParseExact(Converter.ToString(helperService.GetFieldValue("SpAvailableFrom", i.ProductFields)), "dd-MM-yyyy", System.Globalization.CultureInfo.InvariantCulture, System.Globalization.DateTimeStyles.None, out availableFrom) && Dynamicweb.Ecommerce.Common.Context.Cart.OrderFieldValues.GetOrderFieldValue("DeadlineTime") != null && availableFrom <= CalenderHelper.ParseDateTime(Dynamicweb.Ecommerce.Common.Context.Cart.OrderFieldValues.GetOrderFieldValue("DeadlineTime").Value); 712 713 string productClass = "list-group-item row js-product border-bottom js-grid-product"; 714 if (!product.Active) 715 { 716 productClass += " in-active"; 717 } 718 719 string cssIDSelector = "js-" + i.Id; 720 721 <div class="@productClass" data-min-quantity='@minQty' id="@cssIDSelector" data-page-num="@pageNum"> 722 <div class="col-md-1 col-sm-2 list-group-item-img"> 723 724 @{ 725 var previewImageUrl = host + "/Admin/Public/getimage.ashx?Image=" + image + "&amp;Resolution=75&amp;Compression=70&amp;Width=500&amp;Height=500&amp;Crop=5&fillcanvas=true"; 726 string fallBackImage = $"/Admin/Public/getimage.ashx?Image={image}&amp;Resolution=75&amp;Compression=70&amp;Width=500&amp;Height=500&amp;Crop=5&fillcanvas=true"; 727 var preImage = "data:image/gif;base64,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"; 728 } 729 <a href="@productLink" class="js-product-title js-gtm-product" data-name="@HttpUtility.HtmlAttributeEncode(i.Name)" data-id="@HttpUtility.HtmlAttributeEncode(i.Id)"> 730 <img src="@preImage" data-src="@previewImageUrl" data-fallback-image-url="@fallBackImage" alt="@HttpUtility.HtmlAttributeEncode(i.Name)" class="img-responsive b-lazy" /> 731 </a> 732 733 @if (images.Count > 1) 734 { 735 <span class="label label-info label-amount-pictures"><i class="glyphicon glyphicon-picture"></i> @images.Count</span> 736 } 737 738 </div> 739 740 <div class="col-md-3 col-sm-4"> 741 <h2 class="grid-item-name grid-item-name-list"> 742 <a href="@productLink" class="js-product-title js-gtm-product" data-name="@HttpUtility.HtmlAttributeEncode(i.Name)" data-id="@HttpUtility.HtmlAttributeEncode(i.Id)">@i.Name</a> 743 @if (Converter.ToBoolean(helperService.GetFieldValue("NewProduct", i.ProductFields))) 744 { 745 <span class="label label-warning">@Translate("Smartpage:NewProduct", "NEW")</span> 746 } 747 @if (Converter.ToBoolean(helperService.GetFieldValue("Bestseller", i.ProductFields))) 748 { 749 <span class="label label-warning">@Translate("Smartpage:Bestseller", "BESTSELLER")</span> 750 } 751 @if (!string.IsNullOrEmpty(Converter.ToString(helperService.GetFieldValue("NavCompanyCode", i.ProductFields)))) 752 { 753 var flagImgPath = "/Admin/Images/Flags/Small/flag_" + Converter.ToString(helperService.GetFieldValue("NavCompanyCode", i.ProductFields)) + ".png"; 754 <img src='@flagImgPath' alt='@Converter.ToString(helperService.GetFieldValue("NavCompanyCode", i.ProductFields))' title='@Converter.ToString(helperService.GetFieldValue("NavCompanyCode", i.ProductFields))' /> 755 } 756 </h2> 757 758 <div class="shortdescription"> 759 @AddedToCart(i, "standard") 760 <p>@i.ShortDescription</p> 761 @ListStockStatus(i, "list") 762 </div> 763 <div class="manufacturer-website hidden-sm hidden-xs"> 764 @RenderManufacturer(manufacturerId, manufacturerName, manufacturerWebsiteUrl) <br /> 765 @if (product.Height > 0) 766 { 767 @FormatDiameter("H: " + product.Height + " cm") 768 } 769 </div> 770 771 </div> 772 773 <div class="col-md-1 col-sm-5"> 774 775 <div class="potsize text-right hidden-sm hidden-xs "> 776 @FormatDiameter(Converter.ToString(helperService.GetFieldValue("ProductPotSize", i.ProductFields))) cm 777 </div> 778 <div class="hidden-md hidden-lg"> 779 @FormatDiameter(Converter.ToString(helperService.GetFieldValue("ProductPotSize", i.ProductFields))) 780 @RenderManufacturer(manufacturerId, manufacturerName, manufacturerWebsiteUrl) <br /> 781 @if (product.Height > 0) 782 { 783 @FormatDiameter("H: " + product.Height + " cm") 784 } 785 </div> 786 </div> 787 788 <div class="clearfix visible-sm"></div> 789 <div class="col-md-4 col-sm-6"> 790 @if (isLoggedIn) 791 { 792 <div class="product-price"> 793 <table class="table"> 794 <tbody> 795 <tr> 796 <td> 797 @Translate("Pcs", "Stk") 798 </td> 799 <td> 800 1 &times; 801 @productInfo.ColliSize 802 </td> 803 <td> 804 <span class="js-colli-per-layer">@productInfo.ColliPerLayer</span> 805 &times; @productInfo.ColliSize 806 </td> 807 <td> 808 <span class="js-colli-per-cc">@productInfo.ColliPerCc</span> 809 &times; @productInfo.ColliSize 810 </td> 811 </tr> 812 @if (!DisablePrices()) 813 { 814 815 <tr> 816 <td> 817 @Translate("price", "Pris") 818 </td> 819 <td class="js-product-field-price js-product-field-price-colli"> 820 @if (DisplayPricesInclVat()) 821 { 822 if (Converter.ToDouble(priceInformation.Prices.PricePerColliUnit.PriceWithVAT) > 0) 823 { 824 @:@priceInformation.Prices.PricePerColliUnit.PriceWithVAT.ToString("0.00") 825 } 826 827 } 828 else 829 { 830 if (Converter.ToDouble(priceInformation.Prices.PricePerColliUnit.PriceWithoutVAT) > 0) 831 { 832 @:@priceInformation.Prices.PricePerColliUnit.PriceWithoutVAT.ToString("0.00") 833 } 834 } 835 </td> 836 <td class="js-product-field-price js-product-field-price-layer"> 837 @if (DisplayPricesInclVat()) 838 { 839 if (Converter.ToDouble(priceInformation.Prices.PricePerLayerUnit.PriceWithVAT) > 0) 840 { 841 @:@priceInformation.Prices.PricePerLayerUnit.PriceWithVAT.ToString("0.00") 842 } 843 } 844 else 845 { 846 if (Converter.ToDouble(priceInformation.Prices.PricePerLayerUnit.PriceWithoutVAT) > 0) 847 { 848 @:@priceInformation.Prices.PricePerLayerUnit.PriceWithoutVAT.ToString("0.00") 849 } 850 } 851 </td> 852 <td class="js-product-field-price js-product-field-price-cc"> 853 @if (DisplayPricesInclVat()) 854 { 855 if (Converter.ToDouble(priceInformation.Prices.PricePerCcUnit.PriceWithVAT) > 0) 856 { 857 @:@priceInformation.Prices.PricePerCcUnit.PriceWithVAT.ToString("0.00") 858 } 859 } 860 else 861 { 862 if (Converter.ToDouble(priceInformation.Prices.PricePerCcUnit.PriceWithoutVAT) > 0) 863 { 864 @:@priceInformation.Prices.PricePerCcUnit.PriceWithoutVAT.ToString("0.00") 865 } 866 } 867 </td> 868 </tr> 869 } 870 </tbody> 871 </table> 872 </div> 873 } 874 </div> 875 <br class="hidden-sm hidden-md hidden-lg" /> 876 <div> 877 @FavoriteHelper(i, "list-view") 878 </div> 879 <div class="col-md-3 col-sm-6"> 880 @if (isLoggedIn && product.VariantCount == 0) 881 { 882 var loopCounter = productLoopCounter + baseLoopCounter; 883 var nameProductLoopCounter = "ProductLoopCounter" + loopCounter; 884 var nameProductIdCounter = "ProductID" + loopCounter; 885 var nameVariantIdCounter = "VariantID" + loopCounter; 886 var nameUnitIdCounter = "UnitID" + loopCounter; 887 var namewishListIdCounter = "wishListID" + loopCounter; 888 var priceRetailValue = productInfo.CustomerRetailPrice; 889 var priceRetail = new PriceCalculated(new PriceRaw(priceRetailValue, Dynamicweb.Ecommerce.Common.Context.Currency)); 890 var retailPriceValue = DisplayPricesInclVat() ? Converter.ToString(priceRetail.PriceWithVAT) : Converter.ToString(priceRetail.PriceWithoutVAT); 891 retailPriceValue = Converter.ToInt32(retailPriceValue) == 0 ? "" : FormatPrice(retailPriceValue); 892 893 <input type="hidden" value='@loopCounter' name='@nameProductLoopCounter'> 894 <input type="hidden" class="js-product-id" value='@i.Id' name="@nameProductIdCounter"> 895 <input type="hidden" value="" name="@nameVariantIdCounter"> 896 <input type="hidden" value="" name="@nameUnitIdCounter"> 897 <input type="hidden" value="0" name="@namewishListIdCounter"> 898 if (Converter.ToInt32(helperService.GetFieldValue("LeadDays", i.ProductFields)) > 0) 899 { 900 <input class="js-leadday-amount" type="hidden" value="@Converter.ToInt32(helperService.GetFieldValue("LeadDays", i.ProductFields))" name="SpLeadDaysOnProduct_@i.Id" /> 901 <input class="js-available-from-date" type="hidden" value="@(AvailableDeliveryDay(Converter.ToInt32(helperService.GetFieldValue("LeadDays", i.ProductFields))))" name="SpAvailableFromDate_@i.Id" /> 902 } 903 904 if (!string.IsNullOrEmpty(Converter.ToString(Pageview.Area.Item["GoogleTagManager"]))) 905 { 906 string specifier = "G"; 907 var googleImpression = new GoogleImpression() 908 { 909 name = HttpUtility.JavaScriptStringEncode(i.Name), 910 id = HttpUtility.JavaScriptStringEncode(i.Id), 911 price = HttpUtility.JavaScriptStringEncode(priceInformation.Prices.PricePerColliUnit.PriceWithoutVAT.ToString(specifier, culture)), 912 url = HttpUtility.JavaScriptStringEncode(productLink), 913 currency = HttpUtility.JavaScriptStringEncode(Dynamicweb.Ecommerce.Common.Context.Currency.Code), 914 list = string.IsNullOrEmpty(HttpContext.Current.Request["q"]) ? "Product List" : "Search results", 915 position = loopCounter, 916 brand = HttpUtility.JavaScriptStringEncode(manufacturerName) 917 }; 918 <input type="hidden" value='@Newtonsoft.Json.JsonConvert.SerializeObject(googleImpression)' data-id="@HttpUtility.HtmlAttributeEncode(product.Id)" class="js-gtm-productdata" /> 919 } 920 921 if (isDeliverable) 922 { 923 <div class="row"> 924 @renderToolTip() 925 <div class="col-xs-3 js-quantity-tooltip" data-placement="right" data-toggle="popover" data-trigger="manual"> 926 @{ 927 var quantityFieldName = "Quantity" + loopCounter; 928 bool isServiceProduct = product.Type == Dynamicweb.Ecommerce.Products.ProductType.Service; 929 930 var placeholder = minQty > 0 ? String.Format("min. {0}", minQty) : minQty.ToString(); 931 932 <div class="product-list-number"> 933 <input type="number" min="0" name='@quantityFieldName' tabindex='@loopCounter' data-is-service="@isServiceProduct" data-stock-status='@i.StockLevel' class="form-control js-quantity js-gtm-quantity text-right" placeholder="@placeholder" /> 934 </div> 935 } 936 </div> 937 938 <div class="col-xs-9"> 939 @foreach (var o in product.OrderLineFields) 940 { 941 var inputName = "EcomOrderLineFieldInput_" + o.Name + loopCounter; 942 string placeholderText = o.Name; 943 switch (o.SystemName) 944 { 945 case "OrderLineComment": 946 if (EnableComments()) 947 { 948 placeholderText = Translate("LineComment", "Comment"); 949 <input type="text" class="form-control" maxlength="80" name="@inputName" placeholder="@placeholderText" /> 950 } 951 break; 952 case "OrderLineColliSize": 953 <input type="hidden" name="@inputName" value='@productInfo.ColliSize' /> 954 break; 955 case "OrderLineColliPerLayer": 956 <input type="hidden" name="@inputName" value='@productInfo.ColliPerLayer' /> 957 break; 958 case "OrderLineColliPerCC": 959 <input type="hidden" name="@inputName" value='@productInfo.ColliPerCc' /> 960 break; 961 case "OrderLineRetailPrice": 962 placeholderText = Translate("Smartpage:eCom:CustomerSpecificInfo.RetailPrice", "Add retail price"); 963 <div class="hidden"> 964 <input type="text" id="js-retail-price-@loopCounter" class="form-control js-retail-price-input js-product-field-replace text-right" data-replace-target=".js-product-field-retail-price" name="@inputName" value='@retailPriceValue' placeholder="@placeholderText" /> 965 </div> 966 break; 967 case "OrderLineItemNumber": 968 placeholderText = Translate("Smartpage:eCom:CustomerSpecificInfo.ItemNumber", "Item no."); 969 <div class="hidden"> 970 <input type="text" id="js-item-number-@loopCounter" class="form-control js-product-field-replace text-right" data-replace-target=".js-product-field-item-number" name="@inputName" value='@productInfo.CustomerItemNumber.Trim()' placeholder="@placeholderText" /> 971 </div> 972 break; 973 case "OrderLineEAN": 974 placeholderText = Translate("Deres_EAN_nummer-short", "EAN"); 975 976 <div class="hidden"> 977 <div class="editable" data-placeholder="my placeholder"> 978 <input type="text" id="js-ean-number-@loopCounter" class="form-control js-product-field-replace text-right" data-replace-target=".js-product-field-ean" name="@inputName" value='@productInfo.EAN.Trim()' placeholder="@placeholderText" /> 979 </div> 980 </div> 981 982 break; 983 default: 984 <text>@inputName</text> 985 break; 986 } 987 } 988 </div> 989 </div> 990 } 991 992 if (EnableDisplayOfGrossMargin() && isDeliverable) 993 { 994 var pricePerColliUnit = priceInformation.Prices.PricePerColliUnit; 995 double customerSalesPrice = DisplayPricesInclVat() ? pricePerColliUnit.PriceWithVAT : pricePerColliUnit.PriceWithoutVAT; 996 997 <div class="row"> 998 <div class="col-sm-12 col-md-12 col-lg-offset-3 col-lg-9 text-right product-retail-price product-gross-margin-list"> 999 <i class="js-product-field-gross-margin text-muted"> 1000 <span class="pull-left">@Translate("Smartpage:eCom:CustomerSpecificInfo.GrossMargin", "Gross margin")</span> 1001 <span class="pull-right js-gross-margin-value"> 1002 @if (priceRetail.Price > 0) 1003 { 1004 @GetGrossMargin(priceRetail.Price, customerSalesPrice); 1005 } 1006 else 1007 { 1008 @Translate("Smartpage:ecom:CustomerSpecificInfo.GrossMargin.NA", "N/A") 1009 } 1010 </span> 1011 </i> 1012 </div> 1013 </div> 1014 } 1015 1016 if (EnableCustomerRetailPrice() && isDeliverable) 1017 { 1018 <div class="row"> 1019 <div class="col-sm-12 col-md-12 col-lg-offset-3 col-lg-9 text-right product-retail-price product-editable-area"> 1020 1021 @if (EnableEditableRetailPrice() && isDeliverable && !String.IsNullOrEmpty(Converter.ToString(priceRetail.Price))) 1022 { 1023 <div class="product-selectable-edit pull-right"> 1024 <i class="glyphicon glyphicon-edit js-product-fields-edit product-fields-edit" data-source="#js-retail-price-@loopCounter"></i> 1025 </div> 1026 } 1027 <div class="js-product-field-retail-price"> 1028 <span class="pull-left">@Translate("Smartpage:eCom:CustomerSpecificInfo.RetailPrice", "Retail price")</span> 1029 <span class="pull-right">@retailPriceValue</span> 1030 </div> 1031 </div> 1032 </div> 1033 } 1034 1035 if (EnableCustomerItemNumber()) 1036 { 1037 <div class="row"> 1038 1039 1040 <div class="col-sm-12 col-md-12 col-lg-offset-3 col-lg-9 text-right product-item-number product-editable-area"> 1041 @if (EnableEditableItemNumber() && isDeliverable) 1042 { 1043 <div class="product-selectable-edit pull-right"> 1044 <i class="glyphicon glyphicon-edit js-product-fields-edit product-fields-edit" data-source="#js-item-number-@loopCounter"></i> 1045 </div> 1046 } 1047 <div class="js-product-field-item-number text-left"> 1048 <span class="pull-left">@Translate("Smartpage:eCom:CustomerSpecificInfo.ItemNumber", "Item no.")</span> 1049 <span class="pull-right">@productInfo.CustomerItemNumber</span> 1050 </div> 1051 </div> 1052 </div> 1053 } 1054 <div class="row"> 1055 <div class="hidden-xs col-sm-3 hidden-md hidden-lg"></div> 1056 <div class="col-sm-12 col-md-12 col-lg-offset-3 col-lg-9 text-right product-editable-area"> 1057 @if (EnableEditableBarcode() && isDeliverable && !String.IsNullOrEmpty(productInfo.EAN)) 1058 { 1059 <div class="product-selectable-edit pull-right"> 1060 <i class="glyphicon glyphicon-edit js-product-fields-edit product-fields-edit" data-source="#js-ean-number-@loopCounter"></i> 1061 </div> 1062 } 1063 @if (EnableCustomerBarcode() && !String.IsNullOrEmpty(productInfo.EAN)) 1064 { 1065 <div class="js-product-field-ean text-left"> 1066 <span class="pull-left">@Translate("Deres_EAN_nummer-short", "EAN")</span> 1067 <span class="pull-right">@productInfo.EAN</span> 1068 </div> 1069 } 1070 </div> 1071 </div> 1072 1073 1074 <div class="row"> 1075 <div class="hidden-xs col-sm-3 hidden-md hidden-lg"></div> 1076 @* If product has lead day *@ 1077 @if (Converter.ToInt32(helperService.GetFieldValue("LeadDays", i.ProductFields)) > 0 && Converter.ToString(helperService.GetFieldValue("SpAvailableFrom", i.ProductFields)) == string.Empty) 1078 { 1079 <div class="col-sm-9 col-md-12 col-lg-offset-3 col-lg-9 product-editable-area"> 1080 <p>@Translate("Smartpage:Ecom.LeadDaysWarning", "Available on") <span class="label label-warning">@(AvailableDeliveryDay(Converter.ToInt32(helperService.GetFieldValue("LeadDays", i.ProductFields))))</span></p> 1081 </div> 1082 } 1083 @* If 'Available from' is in the future *@ 1084 else if (Converter.ToString(helperService.GetFieldValue("SpAvailableFrom", i.ProductFields)) != string.Empty && Dynamicweb.Ecommerce.Common.Context.Cart.OrderFieldValues.GetOrderFieldValue("DeadlineTime") != null && availableFrom > CalenderHelper.ParseDateTime(Dynamicweb.Ecommerce.Common.Context.Cart.OrderFieldValues.GetOrderFieldValue("DeadlineTime").Value)) 1085 { 1086 <div class="col-sm-9 col-md-12 col-lg-offset-3 col-lg-9 product-editable-area"> 1087 <p>@Translate("Smartpage:Ecom.AvailableFromWarning", "Available from") <span class="label label-warning">@(helperService.GetFieldValue("SpAvailableFrom", i.ProductFields))</span></p> 1088 </div> 1089 } 1090 @* If there is no prices *@ 1091 else if (!priceInformation.ArePricesAvailable(product.AutoId, Dynamicweb.Security.UserManagement.User.GetCurrentExtranetUser()?.CustomerNumber)) 1092 { 1093 <div class="col-sm-9 col-md-12 col-lg-offset-3 col-lg-9 product-editable-area"> 1094 <p><span class="label label-warning">@(Translate("Smartpage:Ecom.NoPricesOnProductWarning", "Prices are being generated"))</span></p> 1095 </div> 1096 } 1097 @* If there is no valid prices *@ 1098 else if (Dynamicweb.Ecommerce.Common.Context.Cart.OrderFieldValues.GetOrderFieldValue("DeadlineTime") != null && Dynamicweb.Ecommerce.Common.Context.Cart.OrderFieldValues.GetOrderFieldValue("DeadlineTime").Value != null && priceInformation.ArePricesValidInTheFuture(product.AutoId, CalenderHelper.ParseDateTime(Dynamicweb.Ecommerce.Common.Context.Cart.OrderFieldValues.GetOrderFieldValue("DeadlineTime").Value), Dynamicweb.Security.UserManagement.User.GetCurrentExtranetUser()?.CustomerNumber)) 1099 { 1100 <div class="col-sm-9 col-md-12 col-lg-offset-3 col-lg-9 product-editable-area"> 1101 <p>@Translate("Smartpage:Ecom.PricesValidFrom", "Prices available on") <span class="label label-warning">@(priceInformation.GetValidFromDate(product.AutoId, CalenderHelper.ParseDateTime(Dynamicweb.Ecommerce.Common.Context.Cart.OrderFieldValues.GetOrderFieldValue("DeadlineTime").Value), Dynamicweb.Security.UserManagement.User.GetCurrentExtranetUser()?.CustomerNumber))</span></p> 1102 </div> 1103 } 1104 @* If there is no valid prices *@ 1105 else if (Dynamicweb.Ecommerce.Common.Context.Cart.OrderFieldValues.GetOrderFieldValue("DeadlineTime") != null && Dynamicweb.Ecommerce.Common.Context.Cart.OrderFieldValues.GetOrderFieldValue("DeadlineTime").Value != null && priceInformation.ArePricesExpired(product.AutoId, CalenderHelper.ParseDateTime(Dynamicweb.Ecommerce.Common.Context.Cart.OrderFieldValues.GetOrderFieldValue("DeadlineTime").Value), Dynamicweb.Security.UserManagement.User.GetCurrentExtranetUser()?.CustomerNumber)) 1106 { 1107 <div class="col-sm-9 col-md-12 col-lg-offset-3 col-lg-9 product-editable-area"> 1108 <p><span class="label label-warning">@(Translate("Smartpage:Ecom.NoPricesFoundOnDeliveryDate", "No prices found on Delivery Date"))</span></p> 1109 </div> 1110 } 1111 </div> 1112 1113 } 1114 </div> 1115 1116 @if (Converter.ToInt32(helperService.GetFieldValue("LeadDays", i.ProductFields)) > 0) 1117 { 1118 <div class="row bottom"> 1119 <div class="col-sm-12 col-md-12 col-lg-9 product-lead-days "> 1120 <span class="label label-warning m-l-15px">@Translate("Smartpage:Ecom.LeadDaysMessage", "Lead days") @Converter.ToInt32(helperService.GetFieldValue("LeadDays", i.ProductFields))</span> 1121 </div> 1122 </div> 1123 } 1124 </div> 1125 } 1126 </div> 1127 1128 </div> 1129 1130 <input type="submit" value="Add to basket" class="sr-only" /> 1131 1132 @if (isLoggedIn) 1133 { 1134 @SnippetStart("SmartpageAddToBasket") 1135 <button class="btn btn-primary btn-block btn-lg js-submit-form" data-form-selector=".js-basket-add">@Translate("Smartpage:eCom.AddToCart", "Læg i kurven")</button> 1136 @SnippetEnd("SmartpageAddToBasket") 1137 } 1138 </form> 1139 1140 } 1141 1142 @inherits ViewModelTemplate<ProductListViewModel> 1143 @using Dynamicweb; 1144 @using Dynamicweb.Core; 1145 @using Dynamicweb.Environment; 1146 @using Dynamicweb.Rendering; 1147 @using Dynamicweb.Ecommerce.ProductCatalog; 1148 @using System.Linq; 1149 @using Gasa.ProductInformation; 1150 @using Gasa.PriceInformation; 1151 @using Gasa.ProductInformation.Helpers; 1152 @using Dynamicweb.Ecommerce.Prices; 1153 @using Gasa.Calendar; 1154 1155 @using Dynamicweb.Ecommerce.Orders; 1156 @using System.Globalization; 1157 @using Dynamicweb.Security.UserManagement; 1158 @using Dynamicweb.Security.UserManagement.Common.CustomFields; 1159 @using Dynamicweb; 1160 @using Dynamicweb.Core; 1161 @using Dynamicweb.Environment; 1162 @using Dynamicweb.Environment.Helpers; 1163 @using Dynamicweb.Rendering; 1164 @using Dynamicweb.Ecommerce.ProductCatalog; 1165 @using System.Linq; 1166 @using Gasa.ProductInformation; 1167 @using Gasa.Calendar; 1168 1169 @* Note that this file will be inserted directly into another one by Dynamicweb IncludeFile 1170 before evaluating the Razor code, so keep the syntax right *@ 1171 1172 @* Favorite Helper *@ 1173 1174 @helper FavoriteHelper(ProductViewModel pvm, string displayType, bool isSimpleAddToCartSection = false) 1175 { 1176 Dynamicweb.Ecommerce.CustomerExperienceCenter.Favorites.FavoriteListService favoriteListService = new Dynamicweb.Ecommerce.CustomerExperienceCenter.Favorites.FavoriteListService(); 1177 var user = Dynamicweb.Security.UserManagement.User.GetCurrentExtranetUser(); 1178 string pageId = Dynamicweb.Context.Current.Request["ID"]; 1179 string currentPrice = pvm.Price.PriceFormatted != pvm.PriceBeforeDiscount.PriceFormatted ? pvm.Price.PriceFormatted : pvm.PriceBeforeDiscount.PriceFormatted; 1180 1181 string favoriteIcon = "fas fa-"; 1182 string favoriteOutlineIcon = "fal fa-"; 1183 int modifyFavoriteListPage = GetPageIdByNavigationTag("ModifyFavoriteListPage"); 1184 1185 if (user != null && modifyFavoriteListPage > 0) 1186 { 1187 string favoriteId = "Favorite" + pvm.Id + (isSimpleAddToCartSection ? "simple" : ""); 1188 var customerCenterLists = Dynamicweb.Ecommerce.CustomerCenter.CustomerProductList.GetListByCustomerId(user.ID); 1189 1190 // This page needs to be used since View pvm catalogue can't handle adding to favorites 1191 // Use standard product catalogue instead 1192 string favoriteButtonCss = ""; 1193 1194 switch (displayType) 1195 { 1196 case "product-detail": 1197 favoriteButtonCss = "favorite-button-product-detail"; 1198 break; 1199 case "photo-view": 1200 favoriteButtonCss = "favorite-button-photo-view"; 1201 break; 1202 case "tiles-view": 1203 favoriteButtonCss = "favorite-button-tiles-view"; 1204 break; 1205 case "list-view": 1206 favoriteButtonCss = "favorite-button-list-view"; 1207 break; 1208 case "quicklist-view": 1209 favoriteButtonCss = "favorite-button-quicklist-view"; 1210 break; 1211 default: 1212 favoriteButtonCss = "favorite-button-tiles-view"; 1213 break; 1214 } 1215 1216 <div id="@favoriteId" class=""> 1217 @{ 1218 string favorite = customerCenterLists.Any(l => l.Products.Any(p => p.ProductId == pvm.Id)) ? favoriteIcon : favoriteOutlineIcon; 1219 } 1220 <div> 1221 @if (customerCenterLists.Count() > 0) 1222 { 1223 //Custom 1224 Dynamicweb.Ecommerce.CustomerExperienceCenter.Favorites.FavoriteList favoriteLists = new Dynamicweb.Ecommerce.CustomerExperienceCenter.Favorites.FavoriteList(); 1225 1226 1227 foreach (var list in customerCenterLists) 1228 { 1229 bool isInFavoriteList = list.Products.Any(p => p.ProductId == pvm.Id); 1230 string addLink = "/Default.aspx?ID=" + modifyFavoriteListPage + "&feed=true&CCAddToMyLists=" + pvm.Id + "&CCAddToListVariantID=" + pvm.VariantId + "&CCAddToListLanguageID=" + pvm.LanguageId + "&CCAddToListID=" + list.ListId + "&CCListType=" + list.Type; 1231 string removeLink = "/Default.aspx?ID=" + modifyFavoriteListPage + "&feed=true&CCRemoveFromMyLists=" + pvm.Id + "&CCRemoveFromListVariantID=" + pvm.VariantId + "&CCRemoveFromListLanguageID=" + pvm.LanguageId + "&ListID=" + list.ListId + "&CCListType=" + list.Type; 1232 string favLinkType = isInFavoriteList ? removeLink : addLink; 1233 string isInListIcon = isInFavoriteList ? favoriteIcon : favoriteOutlineIcon; 1234 1235 //Custom 1236 <a href="@addLink" class="@favoriteButtonCss btn glyphicon glyphicon-star-empty js-favorite js-handle-favorite-add js-favorite-add-@favoriteId @(isInFavoriteList ? "hidden" : "")" data-fav-id="@(Dynamicweb.Core.Encoders.HtmlEncoder.HtmlAttributeEncode(favoriteId))" ><i class="@isInListIcon u-margin-right"></i></a> 1237 <a href="@removeLink" class="@favoriteButtonCss btn glyphicon glyphicon-star js-favorite js-handle-favorite-remove js-favorite-remove-@favoriteId @(!isInFavoriteList ? "hidden" : "")" data-fav-id="@(Dynamicweb.Core.Encoders.HtmlEncoder.HtmlAttributeEncode(favoriteId))"><i class="@isInListIcon u-margin-right"></i></a> 1238 } 1239 } 1240 else 1241 { 1242 string favLinkType = "/Default.aspx?ID=" + modifyFavoriteListPage + "&feed=true&DoNotShowVariantsAsSingleProducts=True&CCAddToMyLists=" + pvm.Id + "&CCAddToListVariantID=" + pvm.VariantId + "&CCAddToListLanguageID=" + pvm.LanguageId + "&CCListType=0&CCCreateNewList="; 1243 <a href="@favLinkType" class="@favoriteButtonCss btn glyphicon glyphicon-star-empty"></a> 1244 } 1245 </div> 1246 </div> 1247 } 1248 } 1249 1250 @helper RenderPhotoView() 1251 { 1252 <form method="post" class="js-basket-add js-set-tabindex row js-product-form-container" autocomplete="false" data-submit-url='@Pageview.Area.Item["JsonCart"]'> 1253 <input type="hidden" name="CartCmd" value="addmulti" /> 1254 <input type="hidden" name="Spleadday-accepted" class="js-leadday-accepted" value="false" /> 1255 <input type="hidden" name="Spleadday-declined" class="js-leadday-declined" value="false" /> 1256 @{ 1257 1258 var isLoggedIn = Dynamicweb.Security.UserManagement.User.IsExtranetUserLoggedIn(); 1259 var pagenum = 1; 1260 var defaultImage = !string.IsNullOrWhiteSpace(Converter.ToString(Pageview.Area.Item["DefaultImage"])) ? Converter.ToString(Pageview.Area.Item["DefaultImage"]) : "/Files/images/default-image.png"; 1261 1262 if (Dynamicweb.Context.Current.Request.GetInt32("pagenum") > 0) 1263 { 1264 pagenum = Dynamicweb.Context.Current.Request.GetInt32("pagenum"); 1265 } 1266 1267 var baseLoopCounter = Model.PageSize * (pagenum - 1); 1268 int productLoopCounter = 0; 1269 1270 var productService = Dynamicweb.Ecommerce.Services.Products; 1271 var helperService = new CustomProductFieldHelpers(); 1272 string currentPageLink = "/Default.aspx?ID=" + GetPageIdByNavigationTag("SpProducts"); 1273 string host = Converter.ToBoolean(Pageview.Area.Item["CDNActivate"]) ? Converter.ToString(Pageview.Area.Item["CDNUrl"]) : string.Empty; 1274 } 1275 <div class="col-xs-12"> 1276 <div class="product-grid photo-group js-grid-group"> 1277 @foreach (ProductViewModel i in Model.Products) 1278 { 1279 productLoopCounter++; 1280 1281 var manufacturerName = i.Manufacturer.Name; 1282 var manufacturerWebsiteUrl = i.Manufacturer.Web; 1283 var manufacturerId = i.Manufacturer.Id; 1284 1285 var product = productService.GetProductById(i.Id, i.VariantId, Dynamicweb.Ecommerce.Common.Context.LanguageID, false); 1286 var productInfo = new ProductInformation(product, Dynamicweb.Security.UserManagement.User.GetCurrentExtranetUser()?.CustomerNumber); 1287 var priceInformation = new PriceInformation(product, productInfo); 1288 1289 string productLink = currentPageLink + "&amp;GroupId=" + product.PrimaryGroupId + "&amp;ProductID=" + product.Id; 1290 1291 var hasMultipleImages = i.ImagePatternImages.Count > 1; 1292 var hasThumbs = hasMultipleImages ? "has-bullets" : ""; 1293 1294 var images = i.ImagePatternImages; 1295 string image = defaultImage; 1296 1297 if (images.Any()) 1298 { 1299 image = images.FirstOrDefault().Value; 1300 } 1301 1302 int minQty = Converter.ToInt32(helperService.GetFieldValue("MinimumPurchaseQuantityLimit", i.ProductFields)); 1303 if (minQty == 0) 1304 { 1305 switch (Converter.ToString(helperService.GetFieldValue("MinimumPurchaseQuantity", i.ProductFields)).ToLower().Trim()) 1306 { 1307 case "layer": 1308 minQty = productInfo.ColliPerLayer; 1309 break; 1310 case "cc": 1311 minQty = productInfo.ColliPerCc; 1312 break; 1313 default: 1314 minQty = 1; 1315 break; 1316 } 1317 } 1318 1319 DateTime availableFrom = DateTime.MinValue; 1320 bool isDeliverable = Converter.ToDouble(priceInformation.Prices.PricePerColliUnit.Price) > 0 && DateTime.TryParseExact(Converter.ToString(helperService.GetFieldValue("SpAvailableFrom", i.ProductFields)), "dd-MM-yyyy", System.Globalization.CultureInfo.InvariantCulture, System.Globalization.DateTimeStyles.None, out availableFrom) && Dynamicweb.Ecommerce.Common.Context.Cart.OrderFieldValues.GetOrderFieldValue("DeadlineTime") != null && availableFrom <= CalenderHelper.ParseDateTime(Dynamicweb.Ecommerce.Common.Context.Cart.OrderFieldValues.GetOrderFieldValue("DeadlineTime").Value); 1321 string cssIDSelector = "js-" + i.Id; 1322 1323 string productClass = "photo-group-item col-xs-12 clearfix js-product js-grid-product"; 1324 if (!product.Active) 1325 { 1326 productClass += " in-active"; 1327 } 1328 1329 <div class="@productClass" data-min-quantity="@minQty" id="@cssIDSelector" data-has-multiple-images="@hasMultipleImages"> 1330 <div class="col-sm-6 col-md-3"> 1331 @FavoriteHelper(i, "photo-view") 1332 <div class="photo-group-item-img"> 1333 @{ 1334 var previewImageUrl = host + "/Admin/Public/getimage.ashx?Image=" + image + "&amp;Resolution=75&amp;Compression=70&amp;Width=500&amp;Height=500&amp;Crop=5&fillcanvas=true"; 1335 string fallBackImage = $"/Admin/Public/getimage.ashx?Image={image}&amp;Resolution=75&amp;Compression=70&amp;Width=500&amp;Height=500&amp;Crop=5&fillcanvas=true"; 1336 var preImage = "data:image/gif;base64,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"; 1337 } 1338 <a href="#" class="ms-layer ms-btn fullscreen-btn js-show-fullscreen" data-modal-target="@("ModalFull" + i.Id)" data-slider-target="@("ModalFullSlider" + i.Id)" data-offset-x="10" data-offset-y="15" data-type="button" data-duration="500"><i class="glyphicon glyphicon-fullscreen"></i></a> 1339 <a href="@productLink" class="js-product-title js-gtm-product" data-name="@HttpUtility.HtmlAttributeEncode(i.Name)" data-id="@HttpUtility.HtmlAttributeEncode(i.Id)"> 1340 <img src="@preImage" data-src="@previewImageUrl" data-fallback-image-url="@fallBackImage" alt="@HttpUtility.HtmlAttributeEncode(i.Name)" class="img-responsive b-lazy" /> 1341 </a> 1342 @if (images.Count > 1) 1343 { 1344 <span class="label label-info label-amount-pictures"><i class="glyphicon glyphicon-picture"></i> @images.Count</span> 1345 } 1346 @AddedToCart(i, "absolute") 1347 </div> 1348 1349 @if (Converter.ToInt32(helperService.GetFieldValue("LeadDays", i.ProductFields)) > 0) 1350 { 1351 <div class="row"> 1352 <div class="col-sm-12 col-md-12 col-lg-9 product-lead-days"> 1353 <span class="label label-warning">@Translate("Smartpage:Ecom.LeadDaysMessage", "Lead days") @Converter.ToInt32(helperService.GetFieldValue("LeadDays", i.ProductFields))</span> 1354 </div> 1355 </div> 1356 } 1357 </div> 1358 1359 <div class="col-sm-6 col-md-4 photo-group-item-details"> 1360 <h2 class="grid-item-name grid-item-name-photo"> 1361 <a href="@productLink" class="js-product-title js-gtm-product" data-name="@HttpUtility.HtmlAttributeEncode(i.Name)" data-id="@HttpUtility.HtmlAttributeEncode(i.Id)">@i.Name</a> 1362 @if (Converter.ToBoolean(helperService.GetFieldValue("NewProduct", i.ProductFields))) 1363 { 1364 <span class="label label-warning">@Translate("Smartpage:NewProduct", "NEW")</span> 1365 } 1366 @if (Converter.ToBoolean(helperService.GetFieldValue("Bestseller", i.ProductFields))) 1367 { 1368 <span class="label label-warning">@Translate("Smartpage:Bestseller", "BESTSELLER")</span> 1369 } 1370 @if (!string.IsNullOrEmpty(Converter.ToString(helperService.GetFieldValue("NavCompanyCode", i.ProductFields)))) 1371 { 1372 var flagImgPath = "/Admin/Images/Flags/Small/flag_" + Converter.ToString(helperService.GetFieldValue("NavCompanyCode", i.ProductFields)) + ".png"; 1373 <img src="@flagImgPath" alt="@Converter.ToString(helperService.GetFieldValue("NavCompanyCode", i.ProductFields))" title="@Converter.ToString(helperService.GetFieldValue("NavCompanyCode", i.ProductFields))" /> 1374 } 1375 </h2> 1376 <div class="product-description"> 1377 @i.ShortDescription 1378 @ListStockStatus(i, "photo") 1379 </div> 1380 <div class="product-unit"> 1381 &Oslash; @FormatDiameter(Converter.ToString(helperService.GetFieldValue("ProductPotSize", i.ProductFields)) + " cm H: " + product.Height) cm <br /> 1382 @RenderManufacturer(manufacturerId, manufacturerName, manufacturerWebsiteUrl) 1383 </div> 1384 1385 @if (isLoggedIn) 1386 { 1387 <div class="product-price"> 1388 <table class="table"> 1389 <thead> 1390 <tr> 1391 <td>&nbsp;</td> 1392 <th> 1393 <div class="pictogram"> 1394 <div class="pictogram-box"></div> 1395 </div> 1396 </th> 1397 <th> 1398 <div class="pictogram"> 1399 <div class="pictogram-layer"></div> 1400 </div> 1401 </th> 1402 <th> 1403 <div class="pictogram"> 1404 <div class="pictogram-container"></div> 1405 </div> 1406 </th> 1407 </tr> 1408 </thead> 1409 <tbody> 1410 <tr> 1411 <td> 1412 @Translate("Pcs", "Stk") 1413 </td> 1414 <td> 1415 1 &times; 1416 @productInfo.ColliSize 1417 </td> 1418 <td> 1419 <span class="js-colli-per-layer">@productInfo.ColliPerLayer</span> 1420 &times; @productInfo.ColliSize 1421 </td> 1422 <td> 1423 <span class="js-colli-per-cc">@productInfo.ColliPerCc</span> 1424 &times; @productInfo.ColliSize 1425 </td> 1426 </tr> 1427 @if (!DisablePrices()) 1428 { 1429 1430 <tr> 1431 <td> 1432 @Translate("price", "Pris") 1433 </td> 1434 <td class="js-product-field-price js-product-field-price-colli"> 1435 @if (DisplayPricesInclVat()) 1436 { 1437 if (Converter.ToDouble(priceInformation.Prices.PricePerColliUnit.PriceWithVAT) > 0) 1438 { 1439 @:@priceInformation.Prices.PricePerColliUnit.PriceWithVAT.ToString("0.00") 1440 } 1441 1442 } 1443 else 1444 { 1445 if (Converter.ToDouble(priceInformation.Prices.PricePerColliUnit.PriceWithoutVAT) > 0) 1446 { 1447 @:@priceInformation.Prices.PricePerColliUnit.PriceWithoutVAT.ToString("0.00") 1448 } 1449 } 1450 </td> 1451 <td class="js-product-field-price js-product-field-price-layer"> 1452 @if (DisplayPricesInclVat()) 1453 { 1454 if (Converter.ToDouble(priceInformation.Prices.PricePerLayerUnit.PriceWithVAT) > 0) 1455 { 1456 @:@priceInformation.Prices.PricePerLayerUnit.PriceWithVAT.ToString("0.00") 1457 } 1458 } 1459 else 1460 { 1461 if (Converter.ToDouble(priceInformation.Prices.PricePerLayerUnit.PriceWithoutVAT) > 0) 1462 { 1463 @:@priceInformation.Prices.PricePerLayerUnit.PriceWithoutVAT.ToString("0.00") 1464 } 1465 } 1466 </td> 1467 <td class="js-product-field-price js-product-field-price-cc"> 1468 @if (DisplayPricesInclVat()) 1469 { 1470 if (Converter.ToDouble(priceInformation.Prices.PricePerCcUnit.PriceWithVAT) > 0) 1471 { 1472 @:@priceInformation.Prices.PricePerCcUnit.PriceWithVAT.ToString("0.00") 1473 } 1474 } 1475 else 1476 { 1477 if (Converter.ToDouble(priceInformation.Prices.PricePerCcUnit.PriceWithoutVAT) > 0) 1478 { 1479 @:@priceInformation.Prices.PricePerCcUnit.PriceWithoutVAT.ToString("0.00") 1480 } 1481 } 1482 </td> 1483 </tr> 1484 } 1485 </tbody> 1486 </table> 1487 </div> 1488 } 1489 </div> 1490 1491 <div class="clearfix visible-sm visible-xs"></div> 1492 <div class="col-md-5 col-sm-6 hidden-xs"></div> 1493 <div class="col-md-5 col-sm-6 col-xs-12"> 1494 <div class="product-informations"> 1495 @{ 1496 string customerSpecificRemark = GetProductInfoValue(productInfo, "CustomerSpecificRemark"); 1497 1498 if (!string.IsNullOrWhiteSpace(customerSpecificRemark)) 1499 { 1500 <span class="detail-info"> 1501 @Translate("Deres_bemaerkning", "Your Comment"): @customerSpecificRemark 1502 </span> 1503 } 1504 } 1505 <br /> 1506 </div> 1507 <div class="product-photo-price"> 1508 @if (isLoggedIn) 1509 { 1510 var loopCounter = productLoopCounter + baseLoopCounter; 1511 var nameProductLoopCounter = "ProductLoopCounter" + loopCounter; 1512 var nameProductIdCounter = "ProductID" + loopCounter; 1513 var nameVariantIdCounter = "VariantID" + loopCounter; 1514 var nameUnitIdCounter = "UnitID" + loopCounter; 1515 var namewishListIdCounter = "wishListID" + loopCounter; 1516 var cssIsAvailable = isDeliverable ? "available" : "not-available"; 1517 var priceRetailValue = productInfo.CustomerRetailPrice; 1518 var priceRetail = new PriceCalculated(new PriceRaw(priceRetailValue, Dynamicweb.Ecommerce.Common.Context.Currency)); 1519 var retailPriceValue = DisplayPricesInclVat() ? Converter.ToString(priceRetail.PriceWithVAT) : Converter.ToString(priceRetail.PriceWithoutVAT); 1520 retailPriceValue = Converter.ToInt32(retailPriceValue) == 0 ? "" : FormatPrice(retailPriceValue); 1521 1522 <input type="hidden" value='@loopCounter' name='@nameProductLoopCounter'> 1523 <input type="hidden" class="js-product-id" value='@i.Id' name="@nameProductIdCounter"> 1524 <input type="hidden" value="" name="@nameVariantIdCounter"> 1525 <input type="hidden" value="" name="@nameUnitIdCounter"> 1526 <input type="hidden" value="0" name="@namewishListIdCounter"> 1527 if (Converter.ToInt32(helperService.GetFieldValue("LeadDays", i.ProductFields)) > 0) 1528 { 1529 <input class="js-leadday-amount" type="hidden" value="@Converter.ToInt32(helperService.GetFieldValue("LeadDays", i.ProductFields))" name="SpLeadDaysOnProduct_@i.Id" /> 1530 <input class="js-available-from-date" type="hidden" value="@(AvailableDeliveryDay(Converter.ToInt32(helperService.GetFieldValue("LeadDays", i.ProductFields))))" name="SpAvailableFromDate_@i.Id" /> 1531 } 1532 1533 if (!string.IsNullOrEmpty(Converter.ToString(Pageview.Area.Item["GoogleTagManager"]))) 1534 { 1535 string specifier = "G"; 1536 CultureInfo culture = CultureInfo.CreateSpecificCulture("en-US"); 1537 var googleImpression = new GoogleImpression() 1538 { 1539 name = HttpUtility.JavaScriptStringEncode(i.Name), 1540 id = HttpUtility.JavaScriptStringEncode(i.Id), 1541 price = HttpUtility.JavaScriptStringEncode(priceInformation.Prices.PricePerColliUnit.PriceWithoutVAT.ToString(specifier, culture)), 1542 url = HttpUtility.JavaScriptStringEncode(productLink), 1543 currency = HttpUtility.JavaScriptStringEncode(Dynamicweb.Ecommerce.Common.Context.Currency.Code), 1544 list = string.IsNullOrEmpty(HttpContext.Current.Request["q"]) ? "Product List" : "Search results", 1545 position = loopCounter, 1546 brand = HttpUtility.JavaScriptStringEncode(manufacturerName) 1547 }; 1548 <input type="hidden" value='@Newtonsoft.Json.JsonConvert.SerializeObject(googleImpression)' class="js-gtm-productdata" /> 1549 1550 } 1551 1552 <div class='row product-photo-price-element @cssIsAvailable'> 1553 1554 @if (EnableDisplayOfGrossMargin() && isDeliverable) 1555 { 1556 var pricePerColliUnit = priceInformation.Prices.PricePerColliUnit; 1557 double customerSalesPrice = DisplayPricesInclVat() ? pricePerColliUnit.PriceWithVAT : pricePerColliUnit.PriceWithoutVAT; 1558 <div class="col-xs-9 col-xs-offset-3 product-editable-area"> 1559 <i class="js-product-field-gross-margin text-muted"> 1560 <span class="pull-left">@Translate("Smartpage:eCom:CustomerSpecificInfo.GrossMargin", "Gross margin")</span> 1561 <span class="pull-right js-gross-margin-value"> 1562 @if (priceRetail.Price > 0) 1563 { 1564 @GetGrossMargin(priceRetail.Price, customerSalesPrice); 1565 } 1566 else 1567 { 1568 @Translate("Smartpage:ecom:CustomerSpecificInfo.GrossMargin.NA", "N/A") 1569 } 1570 </span> 1571 </i> 1572 </div> 1573 } 1574 1575 @if (EnableCustomerRetailPrice() && isDeliverable) 1576 { 1577 var formattedRetailPrice = DisplayPricesInclVat() ? priceRetail.PriceWithVATFormatted : priceRetail.PriceWithoutVATFormatted; 1578 formattedRetailPrice = Converter.ToDouble(formattedRetailPrice) == 0.00 ? "" : formattedRetailPrice; 1579 <div class="col-xs-9 col-xs-offset-3 product-editable-area"> 1580 1581 @if (EnableEditableRetailPrice() && isDeliverable && !String.IsNullOrEmpty(Converter.ToString(priceRetailValue))) 1582 { 1583 <div class="product-selectable-edit pull-right"> 1584 <i class="glyphicon glyphicon-edit js-product-fields-edit product-fields-edit" data-source="#js-retail-price-@loopCounter"></i> 1585 </div> 1586 } 1587 <div class="js-product-field-retail-price"> 1588 <span class="pull-left">@Translate("Smartpage:eCom:CustomerSpecificInfo.RetailPrice", "Retail price")</span> 1589 <span class="pull-right">@retailPriceValue</span> 1590 </div> 1591 </div> 1592 } 1593 1594 @if (EnableCustomerItemNumber()) 1595 { 1596 <div class="col-xs-9 col-xs-offset-3 product-editable-area"> 1597 1598 @if (EnableEditableItemNumber() && isDeliverable) 1599 { 1600 <div class="product-selectable-edit pull-right"> 1601 <i class="glyphicon glyphicon-edit js-product-fields-edit product-fields-edit" data-source="#js-item-number-@loopCounter"></i> 1602 </div> 1603 } 1604 <div class="js-product-field-item-number text-left"> 1605 <span class="pull-left">@Translate("Smartpage:eCom:CustomerSpecificInfo.ItemNumber", "Item no.")</span> 1606 <span class="pull-right">@productInfo.CustomerItemNumber</span> 1607 </div> 1608 </div> 1609 } 1610 1611 1612 <div class="col-xs-9 col-xs-offset-3 product-editable-area"> 1613 @if (EnableEditableBarcode() && isDeliverable) 1614 { 1615 <div class="pull-right product-selectable-edit"> 1616 <i class="glyphicon glyphicon-edit pull-right js-product-fields-edit product-fields-edit" data-source="#js-ean-number-@loopCounter"></i> 1617 </div> 1618 } 1619 @if (EnableCustomerBarcode() && !String.IsNullOrEmpty(productInfo.EAN)) 1620 { 1621 <div class="js-product-field-ean text-left"> 1622 <span class="pull-left">@Translate("Deres_EAN_nummer", "EAN")</span> 1623 <span class="pull-right">@productInfo.EAN</span> 1624 </div> 1625 } 1626 </div> 1627 1628 @if (isDeliverable) 1629 { 1630 var placeholder = minQty > 0 ? String.Format("min. {0}", minQty) : minQty.ToString(); 1631 1632 <div class="col-xs-3 js-quantity-tooltip" data-placement="top" data-toggle="popover" data-trigger="manual"> 1633 @renderToolTip() 1634 @{ 1635 var quantityFieldName = "Quantity" + loopCounter; 1636 bool isServiceProduct = product.Type == Dynamicweb.Ecommerce.Products.ProductType.Service; 1637 1638 <div class="form-group photo-list-number"> 1639 <input type="number" min="0" name='@quantityFieldName' tabindex='@loopCounter' data-is-service="@isServiceProduct" data-stock-status='@i.StockLevel' class="form-control text-right js-quantity js-gtm-quantity" placeholder="@placeholder" /> 1640 </div> 1641 } 1642 </div> 1643 <div class="col-xs-9"> 1644 @foreach (Dynamicweb.Ecommerce.Orders.OrderLineField o in SortOrderLineFields(product.OrderLineFields)) 1645 { 1646 var inputName = "EcomOrderLineFieldInput_" + o.Name + loopCounter; 1647 string placeholderText = o.Name; 1648 1649 switch (o.SystemName) 1650 { 1651 case "OrderLineComment": 1652 if (EnableComments()) 1653 { 1654 placeholderText = Translate("LineComment", "Comment"); 1655 <div class="form-group"> 1656 <input type="text" class="form-control" maxlength="80" name="@inputName" placeholder="@placeholderText" /> 1657 </div> 1658 } 1659 break; 1660 case "OrderLineColliSize": 1661 <input type="hidden" name="@inputName" value='@productInfo.ColliSize' /> 1662 break; 1663 case "OrderLineColliPerLayer": 1664 <input type="hidden" name="@inputName" value='@productInfo.ColliPerLayer' /> 1665 break; 1666 case "OrderLineColliPerCC": 1667 <input type="hidden" name="@inputName" value='@productInfo.ColliPerCc' /> 1668 break; 1669 case "OrderLineRetailPrice": 1670 placeholderText = Translate("Smartpage:eCom:CustomerSpecificInfo.RetailPrice", "Add retail price"); 1671 <div class="hidden"> 1672 <input type="text" id="js-retail-price-@loopCounter" class="form-control js-product-field-replace js-retail-price-input text-right" data-replace-target=".js-product-field-retail-price" name="@inputName" value='@retailPriceValue' placeholder="@placeholderText" /> 1673 </div> 1674 break; 1675 case "OrderLineItemNumber": 1676 placeholderText = Translate("Smartpage:eCom:CustomerSpecificInfo.ItemNumber", "Item no."); 1677 <div class="hidden"> 1678 <input type="text" id="js-item-number-@loopCounter" class="form-control js-product-field-replace text-right" data-replace-target=".js-product-field-item-number" name="@inputName" value='@productInfo.CustomerItemNumber.Trim()' placeholder="@placeholderText" /> 1679 </div> 1680 break; 1681 case "OrderLineEAN": 1682 placeholderText = Translate("Deres_EAN_nummer-short", "EAN"); 1683 <div class="hidden"> 1684 <input type="text" class="form-control js-product-field-replace text-right" id="js-ean-number-@loopCounter" data-replace-target=".js-product-field-ean" name="@inputName" value='@productInfo.EAN.Trim()' placeholder="@placeholderText" /> 1685 </div> 1686 break; 1687 } 1688 } 1689 </div> 1690 } 1691 @* If product has lead day *@ 1692 @if (Converter.ToInt32(helperService.GetFieldValue("LeadDays", i.ProductFields)) > 0 && Converter.ToString(helperService.GetFieldValue("SpAvailableFrom", i.ProductFields)) == string.Empty) 1693 { 1694 <div class="col-xs-9 col-xs-offset-3"> 1695 <p class="pull-left">@Translate("Smartpage:Ecom.LeadDaysWarning", "Available on") <span class="label label-warning pull-right not-deliverable">@(AvailableDeliveryDay(Converter.ToInt32(helperService.GetFieldValue("LeadDays", i.ProductFields))))</span></p> 1696 </div> 1697 } 1698 @* If 'Available from' is in the future *@ 1699 else if (Converter.ToString(helperService.GetFieldValue("SpAvailableFrom", i.ProductFields)) != string.Empty && Dynamicweb.Ecommerce.Common.Context.Cart.OrderFieldValues.GetOrderFieldValue("DeadlineTime") != null && availableFrom > CalenderHelper.ParseDateTime(Dynamicweb.Ecommerce.Common.Context.Cart.OrderFieldValues.GetOrderFieldValue("DeadlineTime").Value)) 1700 { 1701 <div class="col-xs-9 col-xs-offset-3"> 1702 <p class="pull-left">@Translate("Smartpage:Ecom.AvailableFromWarning", "Available from") <span class="label label-warning pull-right not-deliverable">@(helperService.GetFieldValue("SpAvailableFrom", i.ProductFields))</span></p> 1703 </div> 1704 } 1705 @* If there is no prices *@ 1706 else if (!priceInformation.ArePricesAvailable(product.AutoId, Dynamicweb.Security.UserManagement.User.GetCurrentExtranetUser()?.CustomerNumber)) 1707 { 1708 <div class="col-xs-9 col-xs-offset-3"> 1709 <p><span class="label label-warning pull-right not-deliverable">@(Translate("Smartpage:Ecom.NoPricesOnProductWarning", "Prices are being generated"))</span></p> 1710 </div> 1711 } 1712 @* If there is no valid prices *@ 1713 else if (Dynamicweb.Ecommerce.Common.Context.Cart.OrderFieldValues.GetOrderFieldValue("DeadlineTime") != null && Dynamicweb.Ecommerce.Common.Context.Cart.OrderFieldValues.GetOrderFieldValue("DeadlineTime").Value != null && priceInformation.ArePricesValidInTheFuture(product.AutoId, CalenderHelper.ParseDateTime(Dynamicweb.Ecommerce.Common.Context.Cart.OrderFieldValues.GetOrderFieldValue("DeadlineTime").Value), Dynamicweb.Security.UserManagement.User.GetCurrentExtranetUser()?.CustomerNumber)) 1714 { 1715 <div class="col-xs-9 col-xs-offset-3"> 1716 <p class="pull-left">@Translate("Smartpage:Ecom.PricesValidFrom", "Prices available on") <span class="label label-warning pull-right not-deliverable"> @(priceInformation.GetValidFromDate(product.AutoId, CalenderHelper.ParseDateTime(Dynamicweb.Ecommerce.Common.Context.Cart.OrderFieldValues.GetOrderFieldValue("DeadlineTime").Value), Dynamicweb.Security.UserManagement.User.GetCurrentExtranetUser()?.CustomerNumber))</span></p> 1717 </div> 1718 } 1719 @* If there is no valid prices *@ 1720 else if (Dynamicweb.Ecommerce.Common.Context.Cart.OrderFieldValues.GetOrderFieldValue("DeadlineTime") != null && Dynamicweb.Ecommerce.Common.Context.Cart.OrderFieldValues.GetOrderFieldValue("DeadlineTime").Value != null && priceInformation.ArePricesExpired(product.AutoId, CalenderHelper.ParseDateTime(Dynamicweb.Ecommerce.Common.Context.Cart.OrderFieldValues.GetOrderFieldValue("DeadlineTime").Value), Dynamicweb.Security.UserManagement.User.GetCurrentExtranetUser()?.CustomerNumber)) 1721 { 1722 <div class="col-xs-9 col-xs-offset-3"> 1723 <p><span class="label label-warning pull-right not-deliverable">@(Translate("Smartpage:Ecom.NoPricesFoundOnDeliveryDate", "No prices found on Delivery Date"))</span></p> 1724 </div> 1725 } 1726 1727 </div> 1728 } 1729 </div> 1730 </div> 1731 </div> 1732 <div id="@("ModalFull" + i.Id)" class="modal fade" tabindex="-1" role="dialog"> 1733 <div class="modal-dialog"> 1734 <div class="modal-content"> 1735 <div class="modal-header"> 1736 <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">&times;</span></button> 1737 <h4 class="modal-title">@i.Name</h4> 1738 </div> 1739 <div class="modal-body"> 1740 <div class="row"> 1741 <div class="col-sm-12"> 1742 @RenderImages("ModalFullSlider" + i.Id, i) 1743 </div> 1744 </div> 1745 </div> 1746 </div><!--/.modal-content --> 1747 </div> <!-- /.modal-dialog --> 1748 </div> <!-- /.modal --> 1749 } 1750 </div> 1751 </div> 1752 1753 <input type="submit" value="Add to basket" class="sr-only" /> 1754 1755 @if (isLoggedIn) 1756 { 1757 @SnippetStart("SmartpageAddToBasket") 1758 <button class="btn btn-primary btn-block btn-lg js-submit-form" data-form-selector=".js-basket-add">@Translate("Smartpage:eCom.AddToCart", "Læg i kurven")</button> 1759 @SnippetEnd("SmartpageAddToBasket") 1760 } 1761 </form> 1762 } 1763 1764 @inherits ViewModelTemplate<ProductListViewModel> 1765 @using Dynamicweb; 1766 @using Dynamicweb.Core; 1767 @using Dynamicweb.Environment; 1768 @using Dynamicweb.Rendering; 1769 @using Dynamicweb.Ecommerce.ProductCatalog; 1770 @using System.Linq; 1771 @using Gasa.ProductInformation; 1772 @using Gasa.PriceInformation; 1773 @using Gasa.ProductInformation.Helpers; 1774 @using Dynamicweb.Ecommerce.Prices; 1775 @using Gasa.Calendar; 1776 1777 1778 @helper RenderQuicklistView() 1779 { 1780 <form method="post" class="js-basket-add js-set-tabindex js-product-form-container" autocomplete="false" data-submit-url='@Pageview.Area.Item["JsonCart"]'> 1781 <input type="hidden" name="CartCmd" value="addmulti" /> 1782 <input type="hidden" name="Spleadday-accepted" class="js-leadday-accepted" value="false" /> 1783 <input type="hidden" name="Spleadday-declined" class="js-leadday-declined" value="false" /> 1784 @{ 1785 1786 int pageNum = Math.Max(Dynamicweb.Context.Current.Request.GetInt32("PageNum"), 1); 1787 var isLoggedIn = Dynamicweb.Security.UserManagement.User.IsExtranetUserLoggedIn(); 1788 var pagenum = 1; 1789 var defaultImage = !string.IsNullOrWhiteSpace(Converter.ToString(Pageview.Area.Item["DefaultImage"])) ? Converter.ToString(Pageview.Area.Item["DefaultImage"]) : "/Files/images/default-image.png"; 1790 1791 if (Dynamicweb.Context.Current.Request.GetInt32("pagenum") > 0) 1792 { 1793 pagenum = Dynamicweb.Context.Current.Request.GetInt32("pagenum"); 1794 } 1795 1796 var baseLoopCounter = Model.PageSize * (pageNum - 1); 1797 int productLoopCounter = 0; 1798 1799 var productService = Dynamicweb.Ecommerce.Services.Products; 1800 var helperService = new CustomProductFieldHelpers(); 1801 string currentPageLink = "/Default.aspx?ID=" + GetPageIdByNavigationTag("SpProducts"); 1802 string host = Converter.ToBoolean(Pageview.Area.Item["CDNActivate"]) ? Converter.ToString(Pageview.Area.Item["CDNUrl"]) : string.Empty; 1803 } 1804 <div class="clearfix"></div> 1805 <div class="col-sm-12"> 1806 <div class="product-list list-group js-grid-group"> 1807 1808 @foreach (var i in Model.Products) 1809 { 1810 1811 productLoopCounter++; 1812 1813 var manufacturerName = i.Manufacturer.Name; 1814 var manufacturerWebsiteUrl = i.Manufacturer.Web; 1815 var manufacturerId = i.Manufacturer.Id; 1816 1817 var product = productService.GetProductById(i.Id, i.VariantId, Dynamicweb.Ecommerce.Common.Context.LanguageID, false); 1818 var productInfo = new ProductInformation(product, Dynamicweb.Security.UserManagement.User.GetCurrentExtranetUser()?.CustomerNumber); 1819 var priceInformation = new PriceInformation(product, productInfo); 1820 1821 string productLink = currentPageLink + "&amp;GroupId=" + product.PrimaryGroupId + "&amp;ProductID=" + product.Id; 1822 1823 var images = i.ImagePatternImages; 1824 string image = defaultImage; 1825 1826 if (images.Any()) 1827 { 1828 image = images.FirstOrDefault().Value; 1829 } 1830 1831 int minQty = Converter.ToInt32(helperService.GetFieldValue("MinimumPurchaseQuantityLimit", i.ProductFields)); 1832 if (minQty == 0) 1833 { 1834 switch (Converter.ToString(helperService.GetFieldValue("MinimumPurchaseQuantity", i.ProductFields)).ToLower().Trim()) 1835 { 1836 case "layer": 1837 minQty = productInfo.ColliPerLayer; 1838 break; 1839 case "cc": 1840 minQty = productInfo.ColliPerCc; 1841 break; 1842 default: 1843 minQty = 1; 1844 break; 1845 } 1846 } 1847 1848 DateTime availableFrom = DateTime.MinValue; 1849 bool isDeliverable = Converter.ToDouble(priceInformation.Prices.PricePerColliUnit.Price) > 0 && DateTime.TryParseExact(Converter.ToString(helperService.GetFieldValue("SpAvailableFrom", i.ProductFields)), "dd-MM-yyyy", System.Globalization.CultureInfo.InvariantCulture, System.Globalization.DateTimeStyles.None, out availableFrom) && Dynamicweb.Ecommerce.Common.Context.Cart.OrderFieldValues.GetOrderFieldValue("DeadlineTime") != null && availableFrom <= CalenderHelper.ParseDateTime(Dynamicweb.Ecommerce.Common.Context.Cart.OrderFieldValues.GetOrderFieldValue("DeadlineTime").Value); 1850 1851 string cssIDSelector = "js-" + i.Id; 1852 1853 string productClass = "list-group-item row js-product border-bottom js-grid-product"; 1854 if (!product.Active) 1855 { 1856 productClass += " in-active"; 1857 } 1858 1859 <div class="@productClass" data-min-quantity='@minQty' id="@cssIDSelector" data-page-num="@pageNum"> 1860 @FavoriteHelper(i, "quicklist-view") 1861 1862 <div class="col-sm-4"> 1863 1864 <h2 class="grid-item-name-list grid-item-name"> 1865 @{ 1866 var previewImageUrl = host + "/Admin/Public/getimage.ashx?Image=" + image + "&amp;Resolution=75&amp;Compression=70&amp;Width=500&amp;Height=500&amp;Crop=5&amp;fillcanvas=true&amp;AlternativeImage=" + defaultImage; 1867 string fallBackImage = $"/Admin/Public/getimage.ashx?Image={image}&amp;Resolution=75&amp;Compression=70&amp;Width=500&amp;Height=500&amp;Crop=5&fillcanvas=true"; 1868 var preImage = "data:image/gif;base64,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"; 1869 } 1870 <a href="@productLink" class="js-product-title js-gtm-product" data-name="@HttpUtility.HtmlAttributeEncode(i.Name)" data-id="@HttpUtility.HtmlAttributeEncode(i.Id)"> 1871 <img src="@preImage" data-src="@previewImageUrl" data-fallback-image-url="@fallBackImage" alt="@HttpUtility.HtmlAttributeEncode(i.Name)" class="img-responsive b-lazy" style="width: 15px; height: 15px; display:inline-block;border:1px solid #8ec13c;" /> 1872 </a> 1873 1874 <a href="@productLink" class="js-product-title js-gtm-product" data-name="@HttpUtility.HtmlAttributeEncode(i.Name)" data-id="@HttpUtility.HtmlAttributeEncode(i.Id)">@i.Name</a> 1875 1876 @if (Converter.ToBoolean(helperService.GetFieldValue("NewProduct", i.ProductFields))) 1877 { 1878 <span class="label label-warning">@Translate("Smartpage:NewProduct", "NEW")</span> 1879 } 1880 @if (Converter.ToBoolean(helperService.GetFieldValue("Bestseller", i.ProductFields))) 1881 { 1882 <span class="label label-warning">@Translate("Smartpage:Bestseller", "BESTSELLER")</span> 1883 } 1884 @if (!string.IsNullOrEmpty(Converter.ToString(helperService.GetFieldValue("NavCompanyCode", i.ProductFields)))) 1885 { 1886 var flagImgPath = "/Admin/Images/Flags/Small/flag_" + Converter.ToString(helperService.GetFieldValue("NavCompanyCode", i.ProductFields)) + ".png"; 1887 <img src='@flagImgPath' alt='@Converter.ToString(helperService.GetFieldValue("NavCompanyCode", i.ProductFields))' title='@Converter.ToString(helperService.GetFieldValue("NavCompanyCode", i.ProductFields))' /> 1888 } 1889 1890 </h2> 1891 1892 <div class="shortdescription"> 1893 @AddedToCart(i, "standard") 1894 <p style="margin:0;">@i.ShortDescription</p> 1895 @ListStockStatus(i, "list") 1896 </div> 1897 1898 <div class="manufacturer-website hidden-sm hidden-xs"> 1899 @RenderManufacturer(manufacturerId, manufacturerName, manufacturerWebsiteUrl) <br /> 1900 </div> 1901 <div class="col-md-1 col-sm-5"> 1902 @if (Converter.ToInt32(helperService.GetFieldValue("LeadDays", i.ProductFields)) > 0) 1903 { 1904 <div class="row"> 1905 <div class="col-sm-12 col-md-12 col-lg-9 product-lead-days"> 1906 <span class="label label-warning">@Translate("Smartpage:Ecom.LeadDaysMessage", "Lead days") @Converter.ToInt32(helperService.GetFieldValue("LeadDays", i.ProductFields))</span> 1907 </div> 1908 </div> 1909 } 1910 </div> 1911 <div class="potsize text-right hidden-sm hidden-xs "> 1912 @FormatDiameter(Converter.ToString(helperService.GetFieldValue("ProductPotSize", i.ProductFields)) + " cm ") 1913 </div> 1914 <div class="hidden-md hidden-lg"> 1915 @FormatDiameter(Converter.ToString(helperService.GetFieldValue("ProductPotSize", i.ProductFields))) cm 1916 @RenderManufacturer(manufacturerId, manufacturerName, manufacturerWebsiteUrl) <br /> 1917 </div> 1918 </div> 1919 <div class="clearfix visible-sm"></div> 1920 <div class="col-md-4 col-sm-6"> 1921 @if (isLoggedIn) 1922 { 1923 <div class="product-price"> 1924 <table class="table"> 1925 1926 <tbody> 1927 <tr> 1928 <td> 1929 @Translate("Pcs", "Stk") 1930 </td> 1931 <td> 1932 1 &times; 1933 @productInfo.ColliSize 1934 </td> 1935 <td> 1936 <span class="js-colli-per-layer">@productInfo.ColliPerLayer</span> 1937 &times; @productInfo.ColliSize 1938 </td> 1939 <td> 1940 <span class="js-colli-per-cc">@productInfo.ColliPerCc</span> 1941 &times; @productInfo.ColliSize 1942 </td> 1943 </tr> 1944 @if (!DisablePrices()) 1945 { 1946 <tr> 1947 <td> 1948 @Translate("price", "Pris") 1949 </td> 1950 <td class="js-product-field-price js-product-field-price-colli"> 1951 @if (DisplayPricesInclVat()) 1952 { 1953 if (Converter.ToDouble(priceInformation.Prices.PricePerColliUnit.PriceWithVAT) > 0) 1954 { 1955 @:@priceInformation.Prices.PricePerColliUnit.PriceWithVAT.ToString("0.00") 1956 } 1957 1958 } 1959 else 1960 { 1961 if (Converter.ToDouble(priceInformation.Prices.PricePerColliUnit.PriceWithoutVAT) > 0) 1962 { 1963 @:@priceInformation.Prices.PricePerColliUnit.PriceWithoutVAT.ToString("0.00") 1964 } 1965 } 1966 </td> 1967 <td class="js-product-field-price js-product-field-price-layer"> 1968 @if (DisplayPricesInclVat()) 1969 { 1970 if (Converter.ToDouble(priceInformation.Prices.PricePerLayerUnit.PriceWithVAT) > 0) 1971 { 1972 @:@priceInformation.Prices.PricePerLayerUnit.PriceWithVAT.ToString("0.00") 1973 } 1974 } 1975 else 1976 { 1977 if (Converter.ToDouble(priceInformation.Prices.PricePerLayerUnit.PriceWithoutVAT) > 0) 1978 { 1979 @:@priceInformation.Prices.PricePerLayerUnit.PriceWithoutVAT.ToString("0.00") 1980 } 1981 } 1982 </td> 1983 <td class="js-product-field-price js-product-field-price-cc"> 1984 @if (DisplayPricesInclVat()) 1985 { 1986 if (Converter.ToDouble(priceInformation.Prices.PricePerCcUnit.PriceWithVAT) > 0) 1987 { 1988 @:@priceInformation.Prices.PricePerCcUnit.PriceWithVAT.ToString("0.00") 1989 } 1990 } 1991 else 1992 { 1993 if (Converter.ToDouble(priceInformation.Prices.PricePerCcUnit.PriceWithoutVAT) > 0) 1994 { 1995 @:@priceInformation.Prices.PricePerCcUnit.PriceWithoutVAT.ToString("0.00") 1996 } 1997 } 1998 </td> 1999 </tr> 2000 } 2001 </tbody> 2002 </table> 2003 </div> 2004 } 2005 </div> 2006 <br class="hidden-sm hidden-md hidden-lg" /> 2007 <div class="col-md-3 col-sm-6"> 2008 @if (isLoggedIn && product.VariantCount == 0) 2009 { 2010 2011 var loopCounter = productLoopCounter + baseLoopCounter; 2012 var nameProductLoopCounter = "ProductLoopCounter" + loopCounter; 2013 var nameProductIdCounter = "ProductID" + loopCounter; 2014 var nameVariantIdCounter = "VariantID" + loopCounter; 2015 var nameUnitIdCounter = "UnitID" + loopCounter; 2016 var namewishListIdCounter = "wishListID" + loopCounter; 2017 var priceRetailValue = productInfo.CustomerRetailPrice; 2018 var priceRetail = new PriceCalculated(new PriceRaw(priceRetailValue, Dynamicweb.Ecommerce.Common.Context.Currency)); 2019 var retailPriceValue = DisplayPricesInclVat() ? Converter.ToString(priceRetail.PriceWithVAT) : Converter.ToString(priceRetail.PriceWithoutVAT); 2020 retailPriceValue = Converter.ToInt32(retailPriceValue) == 0 ? "" : FormatPrice(retailPriceValue); 2021 2022 <input type="hidden" value='@loopCounter' name='@nameProductLoopCounter'> 2023 <input type="hidden" class="js-product-id" value='@i.Id' name="@nameProductIdCounter"> 2024 <input type="hidden" value="" name="@nameVariantIdCounter"> 2025 <input type="hidden" value="" name="@nameUnitIdCounter"> 2026 <input type="hidden" value="0" name="@namewishListIdCounter"> 2027 if (Converter.ToInt32(helperService.GetFieldValue("LeadDays", i.ProductFields)) > 0) 2028 { 2029 <input class="js-leadday-amount" type="hidden" value="@Converter.ToInt32(helperService.GetFieldValue("LeadDays", i.ProductFields))" name="SpLeadDaysOnProduct_@i.Id" /> 2030 <input class="js-available-from-date" type="hidden" value="@(AvailableDeliveryDay(Converter.ToInt32(helperService.GetFieldValue("LeadDays", i.ProductFields))))" name="SpAvailableFromDate_@i.Id" /> 2031 } 2032 2033 if (!string.IsNullOrEmpty(Converter.ToString(Pageview.Area.Item["GoogleTagManager"]))) 2034 { 2035 string specifier = "G"; 2036 CultureInfo culture = CultureInfo.CreateSpecificCulture("en-US"); 2037 var googleImpression = new GoogleImpression() 2038 { 2039 name = HttpUtility.JavaScriptStringEncode(i.Name), 2040 id = HttpUtility.JavaScriptStringEncode(i.Id), 2041 price = HttpUtility.JavaScriptStringEncode(priceInformation.Prices.PricePerColliUnit.PriceWithoutVAT.ToString(specifier, culture)), 2042 url = HttpUtility.JavaScriptStringEncode(productLink), 2043 currency = HttpUtility.JavaScriptStringEncode(Dynamicweb.Ecommerce.Common.Context.Currency.Code), 2044 list = string.IsNullOrEmpty(HttpContext.Current.Request["q"]) ? "Product List" : "Search results", 2045 position = loopCounter, 2046 brand = HttpUtility.JavaScriptStringEncode(manufacturerName) 2047 }; 2048 <input type="hidden" value='@Newtonsoft.Json.JsonConvert.SerializeObject(googleImpression)' class="js-gtm-productdata" /> 2049 2050 } 2051 2052 if (isDeliverable) 2053 { 2054 <div class="row"> 2055 @renderToolTip() 2056 <div class="col-xs-3 js-quantity-tooltip" data-placement="right" data-toggle="popover" data-trigger="manual"> 2057 @{ 2058 var quantityFieldName = "Quantity" + loopCounter; 2059 bool isServiceProduct = product.Type == Dynamicweb.Ecommerce.Products.ProductType.Service; 2060 2061 var placeholder = minQty > 0 ? String.Format("min. {0}", minQty) : minQty.ToString(); 2062 2063 <div class="product-list-number"> 2064 <input type="number" min="0" name='@quantityFieldName' tabindex='@loopCounter' data-is-service="@isServiceProduct" data-stock-status='@i.StockLevel' class="form-control js-quantity js-gtm-quantity text-right" placeholder="@placeholder" /> 2065 </div> 2066 } 2067 </div> 2068 2069 <div class="col-xs-9"> 2070 @foreach (var o in product.OrderLineFields) 2071 { 2072 var inputName = "EcomOrderLineFieldInput_" + o.Name + loopCounter; 2073 string placeholderText = o.Name; 2074 switch (o.SystemName) 2075 { 2076 case "OrderLineComment": 2077 if (EnableComments()) 2078 { 2079 placeholderText = Translate("LineComment", "Comment"); 2080 <input type="text" class="form-control" maxlength="80" name="@inputName" placeholder="@placeholderText" /> 2081 } 2082 break; 2083 case "OrderLineColliSize": 2084 <input type="hidden" name="@inputName" value='@productInfo.ColliSize' /> 2085 break; 2086 case "OrderLineColliPerLayer": 2087 <input type="hidden" name="@inputName" value='@productInfo.ColliPerLayer' /> 2088 break; 2089 case "OrderLineColliPerCC": 2090 <input type="hidden" name="@inputName" value='@productInfo.ColliPerCc' /> 2091 break; 2092 case "OrderLineRetailPrice": 2093 placeholderText = Translate("Smartpage:eCom:CustomerSpecificInfo.RetailPrice", "Add retail price"); 2094 <div class="hidden"> 2095 <input type="text" id="js-retail-price-@loopCounter" class="form-control js-retail-price-input js-product-field-replace text-right" data-replace-target=".js-product-field-retail-price" name="@inputName" value='@retailPriceValue' placeholder="@placeholderText" /> 2096 </div> 2097 break; 2098 case "OrderLineItemNumber": 2099 placeholderText = Translate("Smartpage:eCom:CustomerSpecificInfo.ItemNumber", "Item no."); 2100 <div class="hidden"> 2101 <input type="text" id="js-item-number-@loopCounter" class="form-control js-product-field-replace text-right" data-replace-target=".js-product-field-item-number" name="@inputName" value='@productInfo.CustomerItemNumber.Trim()' placeholder="@placeholderText" /> 2102 </div> 2103 break; 2104 case "OrderLineEAN": 2105 placeholderText = Translate("Deres_EAN_nummer-short", "EAN"); 2106 2107 <div class="hidden"> 2108 <div class="editable" data-placeholder="my placeholder"> 2109 <input type="text" id="js-ean-number-@loopCounter" class="form-control js-product-field-replace text-right" data-replace-target=".js-product-field-ean" name="@inputName" value='@productInfo.EAN.Trim()' placeholder="@placeholderText" /> 2110 </div> 2111 </div> 2112 2113 break; 2114 default: 2115 <text>@inputName</text> 2116 break; 2117 } 2118 } 2119 </div> 2120 </div> 2121 } 2122 2123 2124 <div class="row"> 2125 <div class="hidden-xs col-sm-3 hidden-md hidden-lg"></div> 2126 @* If product has lead day *@ 2127 @if (Converter.ToInt32(helperService.GetFieldValue("LeadDays", i.ProductFields)) > 0 && Converter.ToString(helperService.GetFieldValue("SpAvailableFrom", i.ProductFields)) == string.Empty) 2128 { 2129 <div class="col-sm-9 col-md-12 col-lg-offset-3 col-lg-9 product-editable-area"> 2130 <p>@Translate("Smartpage:Ecom.LeadDaysWarning", "Available on") <span class="label label-warning">@(AvailableDeliveryDay(Converter.ToInt32(helperService.GetFieldValue("LeadDays", i.ProductFields))))</span></p> 2131 </div> 2132 } 2133 @* If 'Available from' is in the future *@ 2134 else if (Converter.ToString(helperService.GetFieldValue("SpAvailableFrom", i.ProductFields)) != string.Empty && Dynamicweb.Ecommerce.Common.Context.Cart.OrderFieldValues.GetOrderFieldValue("DeadlineTime") != null && availableFrom > CalenderHelper.ParseDateTime(Dynamicweb.Ecommerce.Common.Context.Cart.OrderFieldValues.GetOrderFieldValue("DeadlineTime").Value)) 2135 { 2136 <div class="col-sm-9 col-md-12 col-lg-offset-3 col-lg-9 product-editable-area"> 2137 <p>@Translate("Smartpage:Ecom.AvailableFromWarning", "Available from") <span class="label label-warning">@(helperService.GetFieldValue("SpAvailableFrom", i.ProductFields))</span></p> 2138 </div> 2139 } 2140 @* If there is no prices *@ 2141 else if (!priceInformation.ArePricesAvailable(product.AutoId, Dynamicweb.Security.UserManagement.User.GetCurrentExtranetUser()?.CustomerNumber)) 2142 { 2143 <div class="col-sm-9 col-md-12 col-lg-offset-3 col-lg-9 product-editable-area"> 2144 <p><span class="label label-warning">@(Translate("Smartpage:Ecom.NoPricesOnProductWarning", "Prices are being generated"))</span></p> 2145 </div> 2146 } 2147 @* If there is no valid prices *@ 2148 else if (Dynamicweb.Ecommerce.Common.Context.Cart.OrderFieldValues.GetOrderFieldValue("DeadlineTime") != null && Dynamicweb.Ecommerce.Common.Context.Cart.OrderFieldValues.GetOrderFieldValue("DeadlineTime").Value != null && priceInformation.ArePricesValidInTheFuture(product.AutoId, CalenderHelper.ParseDateTime(Dynamicweb.Ecommerce.Common.Context.Cart.OrderFieldValues.GetOrderFieldValue("DeadlineTime").Value), Dynamicweb.Security.UserManagement.User.GetCurrentExtranetUser()?.CustomerNumber)) 2149 { 2150 <div class="col-sm-9 col-md-12 col-lg-offset-3 col-lg-9 product-editable-area"> 2151 <p>@Translate("Smartpage:Ecom.PricesValidFrom", "Prices available on") <span class="label label-warning">@(priceInformation.GetValidFromDate(product.AutoId, CalenderHelper.ParseDateTime(Dynamicweb.Ecommerce.Common.Context.Cart.OrderFieldValues.GetOrderFieldValue("DeadlineTime").Value), Dynamicweb.Security.UserManagement.User.GetCurrentExtranetUser()?.CustomerNumber))</span></p> 2152 </div> 2153 } 2154 @* If there is no valid prices *@ 2155 else if (Dynamicweb.Ecommerce.Common.Context.Cart.OrderFieldValues.GetOrderFieldValue("DeadlineTime") != null && Dynamicweb.Ecommerce.Common.Context.Cart.OrderFieldValues.GetOrderFieldValue("DeadlineTime").Value != null && priceInformation.ArePricesExpired(product.AutoId, CalenderHelper.ParseDateTime(Dynamicweb.Ecommerce.Common.Context.Cart.OrderFieldValues.GetOrderFieldValue("DeadlineTime").Value), Dynamicweb.Security.UserManagement.User.GetCurrentExtranetUser()?.CustomerNumber)) 2156 { 2157 <div class="col-sm-9 col-md-12 col-lg-offset-3 col-lg-9 product-editable-area"> 2158 <p><span class="label label-warning">@(Translate("Smartpage:Ecom.NoPricesFoundOnDeliveryDate", "No prices found on Delivery Date"))</span></p> 2159 </div> 2160 } 2161 </div> 2162 2163 } 2164 </div> 2165 </div> 2166 } 2167 </div> 2168 2169 </div> 2170 2171 <input type="submit" value="Add to basket" class="sr-only" /> 2172 2173 @if (isLoggedIn) 2174 { 2175 @SnippetStart("SmartpageAddToBasket") 2176 <button class="btn btn-primary btn-block btn-lg js-submit-form" data-form-selector=".js-basket-add">@Translate("Smartpage:eCom.AddToCart", "Læg i kurven")</button> 2177 @SnippetEnd("SmartpageAddToBasket") 2178 } 2179 </form> 2180 } 2181 2182 @inherits ViewModelTemplate<ProductListViewModel> 2183 @using Dynamicweb; 2184 @using Dynamicweb.Core; 2185 @using Dynamicweb.Environment; 2186 @using Dynamicweb.Rendering; 2187 @using Dynamicweb.Ecommerce.ProductCatalog; 2188 @using System.Linq; 2189 @using Gasa.ProductInformation; 2190 @using Gasa.PriceInformation; 2191 @using Gasa.ProductInformation.Helpers; 2192 @using Dynamicweb.Ecommerce.Prices; 2193 @using Gasa.Calendar; 2194 2195 @helper RenderTilesView() 2196 { 2197 <form method="post" class="js-basket-add js-set-tabindex row js-product-form-container" autocomplete="false" data-submit-url='@Pageview.Area.Item["JsonCart"]'> 2198 <input type="hidden" name="CartCmd" value="addmulti" /> 2199 <input type="hidden" name="Spleadday-accepted" class="js-leadday-accepted" value="false" /> 2200 <input type="hidden" name="Spleadday-declined" class="js-leadday-declined" value="false" /> 2201 @{ 2202 2203 string pageNum = Dynamicweb.Context.Current.Request["PageNum"]; 2204 var isLoggedIn = Dynamicweb.Security.UserManagement.User.IsExtranetUserLoggedIn(); 2205 var pagenum = 1; 2206 var defaultImage = !string.IsNullOrWhiteSpace(Converter.ToString(Pageview.Area.Item["DefaultImage"])) ? Converter.ToString(Pageview.Area.Item["DefaultImage"]) : "/Files/images/default-image.png"; 2207 2208 if (Dynamicweb.Context.Current.Request.GetInt32("pagenum") > 0) 2209 { 2210 pagenum = Dynamicweb.Context.Current.Request.GetInt32("pagenum"); 2211 } 2212 2213 var baseLoopCounter = Model.PageSize * (pagenum - 1); 2214 2215 int productLoopCounter = 0; 2216 2217 var productService = Dynamicweb.Ecommerce.Services.Products; 2218 var helperService = new CustomProductFieldHelpers(); 2219 string currentPageLink = "/Default.aspx?ID=" + GetPageIdByNavigationTag("SpProducts"); 2220 string host = Converter.ToBoolean(Pageview.Area.Item["CDNActivate"]) ? Converter.ToString(Pageview.Area.Item["CDNUrl"]) : string.Empty; 2221 } 2222 <div class="col-xs-12"> 2223 <div class="product-grid grid-group js-grid-group"> 2224 @foreach (ProductViewModel i in Model.Products) 2225 { 2226 productLoopCounter++; 2227 var manufacturerName = i.Manufacturer.Name; 2228 var manufacturerWebsiteUrl = i.Manufacturer.Web; 2229 var manufacturerId = i.Manufacturer.Id; 2230 2231 var product = productService.GetProductById(i.Id, i.VariantId, Dynamicweb.Ecommerce.Common.Context.LanguageID, false); 2232 var productInfo = new ProductInformation(product, Dynamicweb.Security.UserManagement.User.GetCurrentExtranetUser()?.CustomerNumber); 2233 var priceInformation = new PriceInformation(product, productInfo); 2234 2235 string productLink = currentPageLink + "&amp;GroupId=" + product.PrimaryGroupId + "&amp;ProductID=" + product.Id; 2236 2237 var hasMultipleImages = i.ImagePatternImages.Count > 1; 2238 var hasThumbs = hasMultipleImages ? "has-bullets" : ""; 2239 2240 var images = i.ImagePatternImages; 2241 string image = defaultImage; 2242 2243 if (images.Any()) 2244 { 2245 image = images.FirstOrDefault().Value; 2246 } 2247 2248 int minQty = Converter.ToInt32(helperService.GetFieldValue("MinimumPurchaseQuantityLimit", i.ProductFields)); 2249 if (minQty == 0) 2250 { 2251 switch (Converter.ToString(helperService.GetFieldValue("MinimumPurchaseQuantity", i.ProductFields)).ToLower().Trim()) 2252 { 2253 case "layer": 2254 minQty = productInfo.ColliPerLayer; 2255 break; 2256 case "cc": 2257 minQty = productInfo.ColliPerCc; 2258 break; 2259 default: 2260 minQty = 1; 2261 break; 2262 } 2263 } 2264 2265 DateTime availableFrom = DateTime.MinValue; 2266 bool isDeliverable = Converter.ToDouble(priceInformation.Prices.PricePerColliUnit.Price) > 0 && DateTime.TryParseExact(Converter.ToString(helperService.GetFieldValue("SpAvailableFrom", i.ProductFields)), "dd-MM-yyyy", System.Globalization.CultureInfo.InvariantCulture, System.Globalization.DateTimeStyles.None, out availableFrom) && Dynamicweb.Ecommerce.Common.Context.Cart.OrderFieldValues.GetOrderFieldValue("DeadlineTime") != null && availableFrom <= CalenderHelper.ParseDateTime(Dynamicweb.Ecommerce.Common.Context.Cart.OrderFieldValues.GetOrderFieldValue("DeadlineTime").Value); 2267 string cssIDSelector = "js-" + i.Id; 2268 2269 string productClass = "grid-group-item col-xs-12 col-sm-6 col-md-4 col-lg-3 clearfix js-product js-grid-product"; 2270 if (!product.Active) 2271 { 2272 productClass += " in-active"; 2273 } 2274 2275 <div class="@productClass" data-min-quantity='@minQty' id="@cssIDSelector" data-page-num="@pageNum" data-has-multiple-images="@hasMultipleImages"> 2276 @FavoriteHelper(i, "tiles-view") 2277 <div class="grid-group-item-img"> 2278 @{ 2279 var previewImageUrl = host + "/Admin/Public/getimage.ashx?Image=" + image + "&amp;Resolution=75&amp;Compression=70&amp;Width=500&amp;Height=500&amp;Crop=5&amp;fillcanvas=True"; 2280 string fallBackImage = $"/Admin/Public/getimage.ashx?Image={image}&amp;Resolution=75&amp;Compression=70&amp;Width=500&amp;Height=500&amp;Crop=5&fillcanvas=true"; 2281 var preImage = "data:image/gif;base64,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"; 2282 } 2283 <a href="#" class="ms-layer ms-btn fullscreen-btn js-show-fullscreen" data-modal-target="@("ModalFull" + i.Id)" data-slider-target="@("ModalFullSlider" + i.Id)" data-offset-x="10" data-offset-y="15" data-type="button" data-duration="500"><i class="glyphicon glyphicon-fullscreen"></i></a> 2284 <a href="@productLink" class="js-product-title js-gtm-product" data-name="@HttpUtility.HtmlAttributeEncode(i.Name)" data-id="@HttpUtility.HtmlAttributeEncode(i.Id)"> 2285 <img src="@preImage" data-src="@previewImageUrl" data-fallback-image-url="@fallBackImage" alt="@HttpUtility.HtmlAttributeEncode(i.Name)" class="img-responsive b-lazy" /> 2286 </a> 2287 @if (images.Count > 1) 2288 { 2289 <span class="label label-info label-amount-pictures"><i class="glyphicon glyphicon-picture"></i> @images.Count</span> 2290 } 2291 2292 @AddedToCart(i, "absolute") 2293 </div> 2294 2295 <div class="item-description-gallery-view"> 2296 <h2> 2297 <a href="@productLink" class="js-product-title js-gtm-product" data-name="@HttpUtility.HtmlAttributeEncode(i.Name)" data-id="@HttpUtility.HtmlAttributeEncode(i.Id)">@i.Name</a> 2298 @if (Converter.ToBoolean(helperService.GetFieldValue("NewProduct", i.ProductFields))) 2299 { 2300 <span class="label label-warning">@Translate("Smartpage:NewProduct", "NEW")</span> 2301 } 2302 @if (Converter.ToBoolean(helperService.GetFieldValue("Bestseller", i.ProductFields))) 2303 { 2304 <span class="label label-warning">@Translate("Smartpage:Bestseller", "BESTSELLER")</span> 2305 } 2306 @if (!string.IsNullOrEmpty(Converter.ToString(helperService.GetFieldValue("NavCompanyCode", i.ProductFields)))) 2307 { 2308 var flagImgPath = "/Admin/Images/Flags/Small/flag_" + Converter.ToString(helperService.GetFieldValue("NavCompanyCode", i.ProductFields)) + ".png"; 2309 <img src='@flagImgPath' alt='@Converter.ToString(helperService.GetFieldValue("NavCompanyCode", i.ProductFields))' title='@Converter.ToString(helperService.GetFieldValue("NavCompanyCode", i.ProductFields))' /> 2310 } 2311 2312 </h2> 2313 <div class="product-description"> 2314 @ListStockStatus(i, "tiles") 2315 @i.ShortDescription 2316 </div> 2317 <div class="product-unit"> 2318 &Oslash; @FormatDiameter(Converter.ToString(helperService.GetFieldValue("ProductPotSize", i.ProductFields)) + " cm H: " + product.Height) cm <br /> 2319 @RenderManufacturer(manufacturerId, manufacturerName, manufacturerWebsiteUrl) 2320 </div> 2321 2322 </div> 2323 2324 <div class="row space-bottom"> 2325 <div class="col-sm-12 col-md-12 col-lg-9 product-lead-days space-bottom"> 2326 @if (Converter.ToInt32(helperService.GetFieldValue("LeadDays", i.ProductFields)) > 0) 2327 { 2328 <span class="label label-warning">@Translate("Smartpage:Ecom.LeadDaysMessage", "Lead days") @Converter.ToInt32(helperService.GetFieldValue("LeadDays", i.ProductFields))</span> 2329 } 2330 else 2331 { 2332 <span class="label">&nbsp;</span> 2333 } 2334 </div> 2335 </div> 2336 <div class="product-grid-price"> 2337 @if (isLoggedIn) 2338 { 2339 <div class="product-price"> 2340 <table class="table"> 2341 <thead> 2342 <tr> 2343 <td>&nbsp;</td> 2344 <th> 2345 <div class="pictogram"> 2346 <div class="pictogram-box"></div> 2347 </div> 2348 </th> 2349 <th> 2350 <div class="pictogram"> 2351 <div class="pictogram-layer"></div> 2352 </div> 2353 </th> 2354 <th> 2355 <div class="pictogram"> 2356 <div class="pictogram-container"></div> 2357 </div> 2358 </th> 2359 </tr> 2360 </thead> 2361 <tbody> 2362 <tr> 2363 <td> 2364 @Translate("Pcs", "Stk") 2365 </td> 2366 <td> 2367 1 &times; 2368 @productInfo.ColliSize 2369 </td> 2370 <td> 2371 <span class="js-colli-per-layer">@productInfo.ColliPerLayer</span> 2372 &times; @productInfo.ColliSize 2373 </td> 2374 <td> 2375 <span class="js-colli-per-cc">@productInfo.ColliPerCc</span> 2376 &times; @productInfo.ColliSize 2377 </td> 2378 </tr> 2379 2380 @if (!DisablePrices()) 2381 { 2382 <tr> 2383 <td> 2384 @Translate("price", "Pris") 2385 </td> 2386 <td class="js-product-field-price js-product-field-price-colli"> 2387 @if (DisplayPricesInclVat()) 2388 { 2389 if (Converter.ToDouble(priceInformation.Prices.PricePerColliUnit.PriceWithVAT) > 0) 2390 { 2391 @:@priceInformation.Prices.PricePerColliUnit.PriceWithVAT.ToString("0.00") 2392 } 2393 2394 } 2395 else 2396 { 2397 if (Converter.ToDouble(priceInformation.Prices.PricePerColliUnit.PriceWithoutVAT) > 0) 2398 { 2399 @:@priceInformation.Prices.PricePerColliUnit.PriceWithoutVAT.ToString("0.00") 2400 } 2401 } 2402 </td> 2403 <td class="js-product-field-price js-product-field-price-layer"> 2404 @if (DisplayPricesInclVat()) 2405 { 2406 if (Converter.ToDouble(priceInformation.Prices.PricePerLayerUnit.PriceWithVAT) > 0) 2407 { 2408 @:@priceInformation.Prices.PricePerLayerUnit.PriceWithVAT.ToString("0.00") 2409 } 2410 } 2411 else 2412 { 2413 if (Converter.ToDouble(priceInformation.Prices.PricePerLayerUnit.PriceWithoutVAT) > 0) 2414 { 2415 @:@priceInformation.Prices.PricePerLayerUnit.PriceWithoutVAT.ToString("0.00") 2416 } 2417 } 2418 </td> 2419 <td class="js-product-field-price js-product-field-price-cc"> 2420 @if (DisplayPricesInclVat()) 2421 { 2422 if (Converter.ToDouble(priceInformation.Prices.PricePerCcUnit.PriceWithVAT) > 0) 2423 { 2424 @:@priceInformation.Prices.PricePerCcUnit.PriceWithVAT.ToString("0.00") 2425 } 2426 } 2427 else 2428 { 2429 if (Converter.ToDouble(priceInformation.Prices.PricePerCcUnit.PriceWithoutVAT) > 0) 2430 { 2431 @:@priceInformation.Prices.PricePerCcUnit.PriceWithoutVAT.ToString("0.00") 2432 } 2433 } 2434 </td> 2435 </tr> 2436 } 2437 </tbody> 2438 </table> 2439 </div> 2440 <div class="row"> 2441 <div class="editable-area-wrap-tile"> 2442 @if (isLoggedIn) 2443 { 2444 var loopCounter = productLoopCounter + baseLoopCounter; 2445 bool isServiceProduct = product.Type == Dynamicweb.Ecommerce.Products.ProductType.Service; 2446 var nameProductLoopCounter = "ProductLoopCounter" + loopCounter; 2447 var nameProductIdCounter = "ProductID" + loopCounter; 2448 var nameVariantIdCounter = "VariantID" + loopCounter; 2449 var nameUnitIdCounter = "UnitID" + loopCounter; 2450 var namewishListIdCounter = "wishListID" + loopCounter; 2451 var quantityFieldName = "Quantity" + loopCounter; 2452 var priceRetailValue = productInfo.CustomerRetailPrice; 2453 var priceRetail = new PriceCalculated(new PriceRaw(priceRetailValue, Dynamicweb.Ecommerce.Common.Context.Currency)); 2454 var retailPriceValue = DisplayPricesInclVat() ? Converter.ToString(priceRetail.PriceWithVAT) : Converter.ToString(priceRetail.PriceWithoutVAT); 2455 retailPriceValue = Converter.ToInt32(retailPriceValue) == 0 ? "" : FormatPrice(retailPriceValue); 2456 2457 <input type="hidden" value='@loopCounter' name='@nameProductLoopCounter'> 2458 <input type="hidden" class="js-product-id" value='@i.Id' name="@nameProductIdCounter"> 2459 <input type="hidden" value="" name="@nameVariantIdCounter"> 2460 <input type="hidden" value="" name="@nameUnitIdCounter"> 2461 <input type="hidden" value="0" name="@namewishListIdCounter"> 2462 if (Converter.ToInt32(helperService.GetFieldValue("LeadDays", i.ProductFields)) > 0) 2463 { 2464 <input class="js-leadday-amount" type="hidden" value="@Converter.ToInt32(helperService.GetFieldValue("LeadDays", i.ProductFields))" name="SpLeadDaysOnProduct_@i.Id" /> 2465 <input class="js-available-from-date" type="hidden" value="@(AvailableDeliveryDay(Converter.ToInt32(helperService.GetFieldValue("LeadDays", i.ProductFields))))" name="SpAvailableFromDate_@i.Id" /> 2466 } 2467 if (!string.IsNullOrEmpty(Converter.ToString(Pageview.Area.Item["GoogleTagManager"]))) 2468 { 2469 string specifier = "G"; 2470 CultureInfo culture = CultureInfo.CreateSpecificCulture("en-US"); 2471 var googleImpression = new GoogleImpression() 2472 { 2473 name = HttpUtility.JavaScriptStringEncode(i.Name), 2474 id = HttpUtility.JavaScriptStringEncode(i.Id), 2475 price = HttpUtility.JavaScriptStringEncode(priceInformation.Prices.PricePerColliUnit.PriceWithoutVAT.ToString(specifier, culture)), 2476 url = HttpUtility.JavaScriptStringEncode(productLink), 2477 currency = HttpUtility.JavaScriptStringEncode(Dynamicweb.Ecommerce.Common.Context.Currency.Code), 2478 list = string.IsNullOrEmpty(HttpContext.Current.Request["q"]) ? "Product List" : "Search results", 2479 position = loopCounter, 2480 brand = HttpUtility.JavaScriptStringEncode(manufacturerName) 2481 }; 2482 <input type="hidden" value='@Newtonsoft.Json.JsonConvert.SerializeObject(googleImpression)' class="js-gtm-productdata" /> 2483 } 2484 2485 <!-- ::::::product-editable-area::::::: --> 2486 2487 if (EnableDisplayOfGrossMargin() && isDeliverable) 2488 { 2489 var pricePerColliUnit = priceInformation.Prices.PricePerColliUnit; 2490 double customerSalesPrice = DisplayPricesInclVat() ? pricePerColliUnit.PriceWithVAT : pricePerColliUnit.PriceWithoutVAT; 2491 2492 <div class="col-xs-12 product-editable-area"> 2493 <i class="js-product-field-gross-margin text-muted"> 2494 <span class="pull-left">@Translate("Smartpage:eCom:CustomerSpecificInfo.GrossMargin", "Gross margin")</span> 2495 <span class="pull-right js-gross-margin-value"> 2496 @if (priceRetail.Price > 0) 2497 { 2498 @GetGrossMargin(priceRetail.Price, customerSalesPrice); 2499 } 2500 else 2501 { 2502 @Translate("Smartpage:ecom:CustomerSpecificInfo.GrossMargin.NA", "N/A") 2503 } 2504 </span> 2505 </i> 2506 </div> 2507 } 2508 2509 if (EnableCustomerRetailPrice() && isDeliverable) 2510 { 2511 var formattedRetailPrice = DisplayPricesInclVat() ? priceRetail.PriceWithVATFormatted : priceRetail.PriceWithoutVATFormatted; 2512 formattedRetailPrice = Converter.ToDouble(formattedRetailPrice) == 0.00 ? "" : formattedRetailPrice; 2513 <div class="col-xs-12 product-editable-area"> 2514 2515 @if (EnableEditableRetailPrice() && isDeliverable && !String.IsNullOrEmpty(Converter.ToString(priceRetailValue))) 2516 { 2517 <div class="product-selectable-edit pull-right"> 2518 <i class="glyphicon glyphicon-edit js-product-fields-edit product-fields-edit" data-source="#js-retail-price-@loopCounter"></i> 2519 </div> 2520 } 2521 <div class="js-product-field-retail-price"> 2522 <span class="pull-left">@Translate("Smartpage:eCom:CustomerSpecificInfo.RetailPrice", "Retail price")</span> 2523 <span class="pull-right">@retailPriceValue</span> 2524 </div> 2525 </div> 2526 } 2527 2528 2529 if (EnableCustomerItemNumber()) 2530 { 2531 <div class="col-xs-12 product-editable-area"> 2532 2533 @if (EnableEditableItemNumber() && isDeliverable) 2534 { 2535 <div class="product-selectable-edit pull-right"> 2536 <i class="glyphicon glyphicon-edit js-product-fields-edit product-fields-edit" data-source="#js-item-number-@loopCounter"></i> 2537 </div> 2538 } 2539 <div class="js-product-field-item-number text-left"> 2540 <span class="pull-left">@Translate("Smartpage:eCom:CustomerSpecificInfo.ItemNumber", "Item no.")</span> 2541 <span class="pull-right">@productInfo.CustomerItemNumber</span> 2542 </div> 2543 </div> 2544 } 2545 2546 <div class="col-xs-12 product-editable-area push-last-row"> 2547 @if (EnableEditableBarcode() && isDeliverable) 2548 { 2549 <div class="pull-right product-selectable-edit"> 2550 <i class="glyphicon glyphicon-edit pull-right js-product-fields-edit product-fields-edit" data-source="#js-ean-number-@loopCounter"></i> 2551 </div> 2552 } 2553 @if (EnableCustomerBarcode() && !String.IsNullOrEmpty(productInfo.EAN)) 2554 { 2555 <div class="js-product-field-ean text-left"> 2556 <span class="pull-left">@Translate("Deres_EAN_nummer", "EAN")</span> 2557 <span class="pull-right">@productInfo.EAN</span> 2558 </div> 2559 } 2560 </div> 2561 2562 <!-- ::::::product-editable-area::::::: --> 2563 2564 if (isDeliverable) 2565 { 2566 var placeholder = minQty > 0 ? String.Format("min. {0}", minQty) : minQty.ToString(); 2567 2568 <div class="col-xs-4 js-quantity-tooltip" data-placement="top" data-toggle="popover" data-trigger="manual" style="padding-right:0;"> 2569 @renderToolTip() 2570 <div class="form-group gallery-list-number"> 2571 <input type="number" min="0" data-is-service="@isServiceProduct" data-stock-status='@i.StockLevel' name='@quantityFieldName' tabindex='@loopCounter' class="form-control text-right js-quantity js-gtm-quantity" placeholder="@placeholder" /> 2572 </div> 2573 </div> 2574 foreach (Dynamicweb.Ecommerce.Orders.OrderLineField o in SortOrderLineFields(product.OrderLineFields)) 2575 { 2576 var inputName = "EcomOrderLineFieldInput_" + o.Name + loopCounter; 2577 string placeholderText = o.Name; 2578 2579 switch (o.SystemName) 2580 { 2581 case "OrderLineComment": 2582 if (EnableComments()) 2583 { 2584 placeholderText = Translate("LineComment", "Comment"); 2585 <div class="col-xs-8"> 2586 <div class="form-group"> 2587 <input type="text" class="form-control" name='@inputName' maxlength="80" placeholder='@placeholderText' /> 2588 </div> 2589 </div> 2590 } 2591 break; 2592 case "OrderLineColliSize": 2593 <input type="hidden" name="@inputName" value='@productInfo.ColliSize' /> 2594 break; 2595 case "OrderLineColliPerLayer": 2596 <input type="hidden" name="@inputName" value='@productInfo.ColliPerLayer' /> 2597 break; 2598 case "OrderLineColliPerCC": 2599 <input type="hidden" name="@inputName" value='@productInfo.ColliPerCc' /> 2600 break; 2601 case "OrderLineEAN": 2602 placeholderText = Translate("Deres_EAN_nummer-short", "EAN"); 2603 <div class="hidden"> 2604 <input type="text" class="form-control js-product-field-replace text-right" id="js-ean-number-@loopCounter" data-replace-target=".js-product-field-ean" name="@inputName" value='@productInfo.EAN.Trim()' placeholder="@placeholderText" /> 2605 </div> 2606 break; 2607 case "OrderLineRetailPrice": 2608 placeholderText = Translate("Smartpage:eCom:CustomerSpecificInfo.RetailPrice", "Add retail price"); 2609 <div class="hidden"> 2610 <input type="text" id="js-retail-price-@loopCounter" class="form-control js-product-field-replace js-retail-price-input text-right" data-replace-target=".js-product-field-retail-price" name="@inputName" value='@retailPriceValue' placeholder="@placeholderText" /> 2611 </div> 2612 break; 2613 case "OrderLineItemNumber": 2614 placeholderText = Translate("Smartpage:eCom:CustomerSpecificInfo.ItemNumber", "Item no."); 2615 <div class="hidden"> 2616 <input type="text" id="js-item-number-@loopCounter" class="form-control js-product-field-replace text-right" data-replace-target=".js-product-field-item-number" name="@inputName" value='@productInfo.CustomerItemNumber.Trim()' placeholder="@placeholderText" /> 2617 </div> 2618 break; 2619 } 2620 } 2621 } 2622 2623 2624 @* If product has lead day *@ 2625 if (Converter.ToInt32(helperService.GetFieldValue("LeadDays", i.ProductFields)) > 0 && Converter.ToString(helperService.GetFieldValue("SpAvailableFrom", i.ProductFields)) == string.Empty) 2626 { 2627 <div class="col-sm-12 text-center product-not-available"> 2628 <p>@Translate("Smartpage:Ecom.LeadDaysWarning", "Available on") <span class="label label-warning">@(AvailableDeliveryDay(Converter.ToInt32(helperService.GetFieldValue("LeadDays", i.ProductFields))))</span></p> 2629 </div> 2630 } 2631 @* If 'Available from' is in the future *@ 2632 else if (Converter.ToString(helperService.GetFieldValue("SpAvailableFrom", i.ProductFields)) != string.Empty && Dynamicweb.Ecommerce.Common.Context.Cart.OrderFieldValues.GetOrderFieldValue("DeadlineTime") != null && availableFrom > CalenderHelper.ParseDateTime(Dynamicweb.Ecommerce.Common.Context.Cart.OrderFieldValues.GetOrderFieldValue("DeadlineTime").Value)) 2633 { 2634 <div class="col-sm-12 text-center product-not-available"> 2635 <p>@Translate("Smartpage:Ecom.AvailableFromWarning", "Available from") <span class="label label-warning">@(helperService.GetFieldValue("SpAvailableFrom", i.ProductFields))</span></p> 2636 </div> 2637 } 2638 @* If there is no prices *@ 2639 else if (!priceInformation.ArePricesAvailable(product.AutoId, Dynamicweb.Security.UserManagement.User.GetCurrentExtranetUser()?.CustomerNumber)) 2640 { 2641 <div class="col-sm-12 text-center product-not-available"> 2642 <p><span class="label label-warning">@(Translate("Smartpage:Ecom.NoPricesOnProductWarning", "Prices are being generated"))</span></p> 2643 </div> 2644 } 2645 @* If there is no valid prices *@ 2646 else if (Dynamicweb.Ecommerce.Common.Context.Cart.OrderFieldValues.GetOrderFieldValue("DeadlineTime") != null && Dynamicweb.Ecommerce.Common.Context.Cart.OrderFieldValues.GetOrderFieldValue("DeadlineTime").Value != null && priceInformation.ArePricesValidInTheFuture(product.AutoId, CalenderHelper.ParseDateTime(Dynamicweb.Ecommerce.Common.Context.Cart.OrderFieldValues.GetOrderFieldValue("DeadlineTime").Value), Dynamicweb.Security.UserManagement.User.GetCurrentExtranetUser()?.CustomerNumber)) 2647 { 2648 <div class="col-sm-12 text-center product-not-available"> 2649 <p>@Translate("Smartpage:Ecom.PricesValidFrom", "Prices available on") <span class="label label-warning">@(priceInformation.GetValidFromDate(product.AutoId, CalenderHelper.ParseDateTime(Dynamicweb.Ecommerce.Common.Context.Cart.OrderFieldValues.GetOrderFieldValue("DeadlineTime").Value), Dynamicweb.Security.UserManagement.User.GetCurrentExtranetUser()?.CustomerNumber))</span></p> 2650 </div> 2651 } 2652 @* If there is no valid prices *@ 2653 else if (Dynamicweb.Ecommerce.Common.Context.Cart.OrderFieldValues.GetOrderFieldValue("DeadlineTime") != null && Dynamicweb.Ecommerce.Common.Context.Cart.OrderFieldValues.GetOrderFieldValue("DeadlineTime").Value != null && priceInformation.ArePricesExpired(product.AutoId, CalenderHelper.ParseDateTime(Dynamicweb.Ecommerce.Common.Context.Cart.OrderFieldValues.GetOrderFieldValue("DeadlineTime").Value), Dynamicweb.Security.UserManagement.User.GetCurrentExtranetUser()?.CustomerNumber)) 2654 { 2655 <div class="col-sm-12 text-center product-not-available"> 2656 <p><span class="label label-warning">@(Translate("Smartpage:Ecom.NoPricesFoundOnDeliveryDate", "No prices found on Delivery Date"))</span></p> 2657 </div> 2658 } 2659 2660 } 2661 </div> 2662 </div> 2663 } 2664 </div> 2665 <div class="clearfix"></div> 2666 <div id="@("ModalFull" + i.Id)" class="modal fade" tabindex="-1" role="dialog"> 2667 <div class="modal-dialog"> 2668 <div class="modal-content"> 2669 <div class="modal-header"> 2670 <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">&times;</span></button> 2671 <h4 class="modal-title">@i.Name</h4> 2672 </div> 2673 <div class="modal-body"> 2674 <div class="row"> 2675 <div class="col-sm-12"> 2676 @RenderImages("ModalFullSlider" + i.Id, i) 2677 </div> 2678 </div> 2679 </div> 2680 </div><!--/.modal-content --> 2681 </div> <!-- /.modal-dialog --> 2682 </div> <!-- /.modal --> 2683 </div> 2684 } 2685 </div> 2686 </div> 2687 2688 <input type="submit" value="Add to basket" class="sr-only" /> 2689 @if (isLoggedIn) 2690 { 2691 @SnippetStart("SmartpageAddToBasket") 2692 <button class="btn btn-primary btn-block btn-lg js-submit-form" data-form-selector=".js-basket-add">@Translate("Smartpage:eCom.AddToCart", "Læg i kurven")</button> 2693 @SnippetEnd("SmartpageAddToBasket") 2694 } 2695 </form> 2696 } 2697 2698 @helper RenderImages(string container, ProductViewModel pvm) 2699 { 2700 var defaultImage = !string.IsNullOrWhiteSpace(Converter.ToString(Pageview.Area.Item["DefaultImage"])) ? Converter.ToString(Pageview.Area.Item["DefaultImage"]) : "/Files/images/default-image.png"; 2701 var hasMultipleImages = pvm.ImagePatternImages.Count > 1; 2702 2703 var images = pvm.ImagePatternImages; 2704 string imageUrl = defaultImage; 2705 2706 bool isCdnActive = Converter.ToBoolean(Pageview.Area.Item["CDNActivate"]); 2707 2708 if (images.Any()) 2709 { 2710 imageUrl = images.First().Value; 2711 } 2712 2713 string cdnHost = ""; 2714 if (isCdnActive) 2715 { 2716 cdnHost = Converter.ToString(Pageview.Area.Item["CDNUrl"]); 2717 } 2718 2719 <div class="ms-showcase2-template ms-showcase2-vertical"> 2720 <div class="master-slider ms-skin-light-5" id="@container"> 2721 @{ 2722 var imagesLoop = pvm.ImagePatternImages; 2723 } 2724 2725 @if (imagesLoop.Any()) 2726 { 2727 int count = 0; 2728 foreach (var image in imagesLoop) 2729 { 2730 count++; 2731 string loopUrl = image.Value; 2732 string currentImageUrl = cdnHost + "/Admin/Public/getimage.ashx?Image=" + loopUrl + "&amp;Resolution=75&amp;Compression=70&amp;Width=720&amp;Width=480&amp;Crop=5&amp;AlternativeImage=" + defaultImage; 2733 string fallBackImage = $"/Admin/Public/getimage.ashx?Image={loopUrl}&amp;Resolution=75&amp;Compression=70&amp;Width=720&amp;Width=480&amp;Crop=5&amp;AlternativeImage={defaultImage}"; 2734 string currentThumbUrl = cdnHost + "/Admin/Public/getimage.ashx?Image=" + loopUrl + "&amp;Compression=90&amp;Width=63&amp&Height=42&amp;Crop=5"; 2735 string isActiveClass = count == 1 ? "active" : ""; 2736 <div class="ms-slide js-slide-elm" data-slide-no='@count'> 2737 <img src="@currentImageUrl" data-src="@currentImageUrl" data-fallback-image-url="@fallBackImage" alt="@HttpUtility.HtmlAttributeEncode(pvm.Name) @count" class="b-lazy" /> 2738 @if (container == "product-show") 2739 { 2740 <a href="#" class="ms-layer ms-btn fullscreen-btn js-show-fullscreen" data-offset-x="10" data-offset-y="15" data-type="button" data-duration="500"><i class="glyphicon glyphicon-fullscreen"></i></a> 2741 } 2742 2743 </div> 2744 } 2745 } 2746 else 2747 { 2748 string currentImageUrl = cdnHost + "/Admin/Public/getimage.ashx?Image=" + imageUrl + "&amp;Resolution=75&amp;Compression=70&amp;Width=720&amp;Width=480&amp;Crop=5&amp;AlternativeImage=" + defaultImage; 2749 <div class="ms-slide js-slide-elm" data-slide-no='1'> 2750 <img src="@currentImageUrl" data-src="@currentImageUrl" alt="@HttpUtility.HtmlAttributeEncode(pvm.Name)" /> 2751 @if (container == "product-show") 2752 { 2753 <a href="#" class="ms-layer ms-btn fullscreen-btn js-show-fullscreen" data-offset-x="10" data-offset-y="15" data-type="button" data-duration="500"><i class="glyphicon glyphicon-fullscreen"></i></a> 2754 } 2755 2756 </div> 2757 } 2758 </div> 2759 </div> 2760 } 2761 2762 2763 @{ 2764 string listLink = LinkHelper.ReplaceQueryString("viewmode", "list"); 2765 string gridLink = LinkHelper.ReplaceQueryString("viewmode", "grid"); 2766 string photoLink = LinkHelper.ReplaceQueryString("viewmode", "photo"); 2767 string quicklistLink = LinkHelper.ReplaceQueryString("viewmode", "quicklist"); 2768 2769 2770 string urlParamView = Dynamicweb.Context.Current.Request.GetString("viewmode"); 2771 Cookie cookieViewMode = Dynamicweb.Environment.CookieManager.GetCookie("viewmode"); 2772 string cookieValue = String.Empty; 2773 2774 string currentQuery = "/Default.aspx?" + System.Web.HttpContext.Current.Request.QueryString.ToString(); 2775 var queryString = "?" + System.Web.HttpContext.Current.Request.QueryString.ToString(); 2776 2777 2778 string productEmptySortUrl = LinkHelper.ReplaceQueryString(queryString, "sortby", ""); 2779 string productNameURL = LinkHelper.ReplaceQueryString(queryString, "sortby", "productname"); 2780 string productNameLinkAsc = LinkHelper.ReplaceQueryString(productNameURL, "sortorder", "asc"); 2781 string productNameLinkDesc = LinkHelper.ReplaceQueryString(productNameURL, "sortorder", "desc"); 2782 2783 2784 var isNameAscSelected = (currentQuery.ToLower().Contains("&sortby=productname") && currentQuery.ToLower().Contains("&sortorder=asc")); 2785 var isNameDescSelected = (currentQuery.ToLower().Contains("&sortby=productname") && currentQuery.ToLower().Contains("&sortorder=desc")); 2786 2787 string potSizeURL = LinkHelper.ReplaceQueryString(queryString, "sortby", "CustomField_ProductPotSize"); 2788 string potSizeLinkAsc = LinkHelper.ReplaceQueryString(potSizeURL, "sortorder", "asc"); 2789 string potSizeLinkDesc = LinkHelper.ReplaceQueryString(potSizeURL, "sortorder", "desc"); 2790 2791 var isPotSizeAscSelected = (currentQuery.ToLower().Contains("&sortby=customfield_productpotsize") && currentQuery.ToLower().Contains("&sortorder=asc")); 2792 var isPotSizeDescSelected = (currentQuery.ToLower().Contains("&sortby=customfield_productpotsize") && currentQuery.ToLower().Contains("&sortorder=desc")); 2793 2794 2795 var currentUser = Dynamicweb.Frontend.PageView.Current().User; 2796 2797 var excelField = currentUser?.CustomFieldValues.Where(x => x.CustomField.SystemName == "AccessUser_ProductFieldExport").FirstOrDefault(); 2798 2799 bool enableExcelExport = !string.IsNullOrEmpty(Converter.ToString(excelField?.Value)); 2800 var excelDownloadUrl = LinkHelper.ReplaceQueryString("excel", "true") + "&pagesize=10000"; 2801 var baseURL = "/Files/Templates/Designs/" + Pageview.Layout.Design.Name.TrimEnd('/'); //GetString("Template:DesignBaseUrl").TrimEnd('/'); 2802 2803 bool isMobile = Converter.ToBoolean(Pageview.GlobalTags.GetTagByName("Global:Device.IsMobile").Value); 2804 2805 var helperService = new CustomProductFieldHelpers(); 2806 } 2807 2808 @if (cookieViewMode != null) 2809 { 2810 cookieValue = cookieViewMode.Value; 2811 } 2812 2813 @{ 2814 string viewMode = urlParamView == "grid" ? "grid" : urlParamView == "list" ? "list" : urlParamView == "photo" ? "photo" : urlParamView == "quicklist" ? "quicklist" : 2815 cookieValue == "grid" ? "grid" : cookieValue == "list" ? "list" : cookieValue == "photo" ? "photo" : cookieValue == "quicklist" ? "quicklist" : String.Empty; 2816 2817 if (String.IsNullOrEmpty(viewMode)) 2818 { 2819 viewMode = Converter.ToString(Pageview.Area.Item["DefaultProductView"]); 2820 } 2821 else 2822 { 2823 Dynamicweb.Environment.CookieManager.SetCookie("viewmode", viewMode, DateTime.Now.AddDays(30)); 2824 } 2825 2826 if (String.IsNullOrEmpty(viewMode) || isMobile) 2827 { 2828 viewMode = "grid"; 2829 } 2830 } 2831 2832 @RenderSearch() 2833 2834 <div class="clearfix"></div> 2835 2836 @PricesWithVATStatus("top") 2837 2838 <div class="page-header"> 2839 <h1 class="page-header-h1 pull-left col-sm-3"> 2840 @{ 2841 string groupId = System.Web.HttpContext.Current.Request["GroupId"]; 2842 string currentParagraphHeader = Pageview.CurrentParagraph.Header; 2843 2844 if (!string.IsNullOrEmpty(groupId)) 2845 { 2846 var group = Dynamicweb.Ecommerce.Services.ProductGroups.GetGroup(groupId); 2847 if (group != null) 2848 { 2849 @group.Name 2850 } 2851 else 2852 { 2853 @currentParagraphHeader 2854 } 2855 } 2856 else 2857 { 2858 @currentParagraphHeader 2859 } 2860 } 2861 </h1> 2862 <div class="col-sm-9"> 2863 <div class="row"> 2864 @if (!isMobile) 2865 { 2866 <div class="hidden-xs col-sm-5 col-md-3"> 2867 <div class="filter-product-list"> 2868 <select class="form-control js-select-filter-products select-filter-products"> 2869 <option value="@productEmptySortUrl" data-label-select="true">@Translate("Smartpage:ProductList.Filter.Text", "Sort by")</option> 2870 <option value='@productNameLinkAsc' selected='@isNameAscSelected'>@Translate("Smartpage:ProductList.Filter.ProductName.Asc", "Alphabetical A-Z")</option> 2871 <option value='@productNameLinkDesc' selected='@isNameDescSelected'>@Translate("Smartpage:ProductList.Filter.ProductName.Desc", "Alphabetical Z-A")</option> 2872 <option value='@potSizeLinkAsc' selected='@isPotSizeAscSelected'>@Translate("Smartpage:ProductList.Filter.PotSize.Asc", "Pot size ascending")</option> 2873 <option value='@potSizeLinkDesc' selected='@isPotSizeDescSelected'>@Translate("Smartpage:ProductList.Filter.PotSize.Desc", "Pot size descending")</option> 2874 </select> 2875 </div> 2876 </div> 2877 } 2878 2879 @if (viewMode == "list" || viewMode == "quicklist") 2880 { 2881 <div class="hidden-xs hidden-sm"> 2882 <div class="col-md-offset-1 col-md-1 text-right list-dia"> 2883 &Oslash; 2884 </div> 2885 <div class="col-md-4"> 2886 <div class="product-price row"> 2887 <table class="table table-pictogram"> 2888 <thead> 2889 <tr> 2890 <td>&nbsp;</td> 2891 <th> 2892 <div class="pictogram"> 2893 <div class="pictogram-box"></div> 2894 </div> 2895 </th> 2896 <th> 2897 <div class="pictogram"> 2898 <div class="pictogram-layer"></div> 2899 </div> 2900 </th> 2901 <th> 2902 <div class="pictogram"> 2903 <div class="pictogram-container"></div> 2904 </div> 2905 </th> 2906 </tr> 2907 </thead> 2908 </table> 2909 </div> 2910 </div> 2911 </div> 2912 } 2913 2914 @if (!isMobile) 2915 { 2916 <div class="viewmode pull-right"> 2917 @if (enableExcelExport) 2918 { 2919 <a href="@excelDownloadUrl" class="btn btn-default" title='@Translate("Smartpage:eCom.ExcelExport", "Download as Excel-file")'><img src="@baseURL/Assets/Images/Excel-icon-grey.png" alt='@Translate("Smartpage:ProductList.DownloadAsExcel","Hent som excel")' /></a> 2920 } 2921 <div class="btn-group" role="group"> 2922 @{ 2923 var listActiveLink = String.Empty; 2924 if (viewMode == "list") 2925 { 2926 listActiveLink = "active"; 2927 } 2928 <a class="js-listview js-view-change js-tooltips listview-link view-link btn btn-default @listActiveLink" href="@listLink" data-toggle="tooltip" data-placement="top" data-container=".viewmode" title='@Translate("Smartpage:ProductList.Tooltip.ViewMode.List", "View as list")'><i class="glyphicon glyphicon-list"></i></a> 2929 } 2930 @{ 2931 listActiveLink = String.Empty; 2932 if (viewMode == "grid") 2933 { 2934 listActiveLink = "active"; 2935 } 2936 <a class="js-gridview js-view-change js-tooltips gridview-link view-link btn btn-default @listActiveLink" href="@gridLink" data-toggle="tooltip" data-placement="top" data-container=".viewmode" title='@Translate("Smartpage:ProductList.Tooltip.ViewMode.Grid", "View as grid")'><i class="glyphicon glyphicon-th-large"></i></a> 2937 } 2938 @{ 2939 listActiveLink = String.Empty; 2940 if (viewMode == "photo") 2941 { 2942 listActiveLink = "active"; 2943 } 2944 <a class="js-photoview js-view-change js-tooltips photoview-link view-link btn btn-default @listActiveLink" href="@photoLink" data-toggle="tooltip" data-placement="top" data-container=".viewmode" title='@Translate("Smartpage:ProductList.Tooltip.ViewMode.Photos","View as photos")'><i class="glyphicon glyphicon-th-list"></i></a> 2945 } 2946 @{ 2947 listActiveLink = String.Empty; 2948 if (viewMode == "quicklist") 2949 { 2950 listActiveLink = "active"; 2951 } 2952 <a class="js-quicklistview js-view-change js-tooltips quicklistview-link view-link btn btn-default @listActiveLink" href="@quicklistLink" data-toggle="tooltip" data-placement="top" data-container=".viewmode" title='@Translate("Smartpage:ProductList.Tooltip.ViewMode.Quicklist","View as quick list")'><i class="glyphicon glyphicon-align-justify"></i></a> 2953 } 2954 </div> 2955 </div> 2956 } 2957 2958 </div> 2959 2960 </div> 2961 <div class="clearfix"></div> 2962 </div> 2963 <div class="border-bottom-box"> 2964 <div class="clearfix"></div> 2965 <div class="productlistnavigation navigation-top hidden"> 2966 2967 <span class="productcount"> 2968 @Model.TotalProductsCount 2969 @Translate("SmartPage:Product.Paging.ProductsFound", "produkter fundet") 2970 </span> 2971 2972 <span class="pagenavigation pull-right js-product-pagination" data-url="@System.Web.HttpContext.Current.Request.RawUrl"> 2973 @{ 2974 string groupIdQueryParameter = string.IsNullOrEmpty(Dynamicweb.Context.Current.Request["GroupID"]) 2975 ? string.Empty 2976 : "&amp;GroupID=" + Dynamicweb.Context.Current.Request["GroupID"]; 2977 string currentPageLink = "/Default.aspx?ID=" + Pageview.Page.ID + groupIdQueryParameter; 2978 2979 string currentPageNumber = string.IsNullOrWhiteSpace(HttpContext.Current.Request["PageNum"]) ? "1" : HttpContext.Current.Request["PageNum"]; 2980 2981 if (Converter.ToInt32(currentPageNumber) > Model.PageCount) 2982 { 2983 currentPageLink = Dynamicweb.Environment.Helpers.LinkHelper.ReplaceQueryString(Dynamicweb.Context.Current.Request.Url.PathAndQuery, "PageNum", Converter.ToString(Converter.ToInt32(currentPageNumber) - 1)); 2984 <a class="prevpage js-prev-page" href="@currentPageLink">@Translate("SmartPage:Product.Paging.Previous", "Forrige")</a> 2985 } 2986 if (Converter.ToInt32(currentPageNumber) < Model.PageCount) 2987 { 2988 currentPageLink = Dynamicweb.Environment.Helpers.LinkHelper.ReplaceQueryString(Dynamicweb.Context.Current.Request.Url.PathAndQuery, "PageNum", Converter.ToString(Converter.ToInt32(currentPageNumber) + 1)); 2989 if (!currentPageLink.Contains("LayoutTemplate")) 2990 { 2991 currentPageLink += "&LayoutTemplate=NoLayout.html"; 2992 } 2993 <a class="nextpage js-next-page" href="@currentPageLink">@Translate("SmartPage:Product.Paging.Next", "Næste")</a> 2994 } 2995 } 2996 <br /> 2997 </span> 2998 </div> 2999 <div class="col-sm-3"> 3000 @if (isMobile) 3001 { 3002 <div class="row"> 3003 <div class="col-xs-12 filter-product-list"> 3004 <select class="form-control js-select-filter-products select-filter-products"> 3005 <option value="@productEmptySortUrl" data-label-select="true">@Translate("Smartpage:ProductList.Filter.Text", "Sort by")</option> 3006 <option value='@productNameLinkAsc' @isNameAscSelected>@Translate("Smartpage:ProductList.Filter.ProductName.Asc", "Alphabetical A-Z")</option> 3007 <option value='@productNameLinkDesc' @isNameDescSelected>@Translate("Smartpage:ProductList.Filter.ProductName.Desc", "Alphabetical Z-A")</option> 3008 <option value='@potSizeLinkAsc' @isPotSizeAscSelected>@Translate("Smartpage:ProductList.Filter.PotSize.Asc", "Pot size ascending")</option> 3009 <option value='@potSizeLinkDesc' @isPotSizeDescSelected>@Translate("Smartpage:ProductList.Filter.PotSize.Desc", "Pot size descending")</option> 3010 </select> 3011 </div> 3012 </div> 3013 } 3014 3015 @inherits ViewModelTemplate<ProductListViewModel> 3016 @using Dynamicweb; 3017 @using Dynamicweb.Frontend; 3018 @using Dynamicweb.Rendering; 3019 @using Dynamicweb.Ecommerce.ProductCatalog; 3020 @using System.Linq; 3021 @using Dynamicweb.Core; 3022 3023 @using Dynamicweb.Modules.UserManagement; 3024 3025 3026 @{ 3027 var designBaseUrl = "/Files/Templates/Designs/" + Pageview.Layout.Design.Name.TrimEnd('/');//GetString("Template:DesignBaseUrl").TrimEnd('/'); 3028 var user = Dynamicweb.Security.UserManagement.User.GetCurrentExtranetUser(); 3029 3030 } 3031 3032 <form name="EcomSearch" class="form-filters js-form-filters" method="get" action='@SearchEngineFriendlyURLs.GetFriendlyUrl(Converter.ToInt32(Pageview.Page.ID))'> 3033 @*<input type="hidden" name="ID" value='@Converter.ToInt32(Pageview.Page.ID)' />*@ 3034 @* start - enable ajax loading *@ 3035 <input type="hidden" id="js-ajax-filter-enabled" value="true" /> 3036 @* end - enable ajax loading *@ 3037 @if (!string.IsNullOrEmpty(Dynamicweb.Context.Current.Request["SortBy"])) 3038 { 3039 <input type="hidden" name="SortBy" value='@Dynamicweb.Context.Current.Request["SortBy"]' /> 3040 } 3041 @if (!string.IsNullOrEmpty(Dynamicweb.Context.Current.Request["SortOrder"])) 3042 { 3043 <input type="hidden" name="SortOrder" value='@Dynamicweb.Context.Current.Request["SortOrder"]' /> 3044 } 3045 @if (!string.IsNullOrEmpty(Dynamicweb.Context.Current.Request["GroupID"])) 3046 { 3047 <input type="hidden" name="GroupID" value='@Dynamicweb.Context.Current.Request["GroupID"]' /> 3048 } 3049 @if (!string.IsNullOrEmpty(Dynamicweb.Context.Current.Request["q"])) 3050 { 3051 <input type="hidden" name="q" value='@Dynamicweb.Context.Current.Request["q"]' /> 3052 } 3053 3054 3055 <input type="submit" class="sr-only"> 3056 3057 <div class="filter-range"> 3058 <h3>@Translate("Potsize", "Pot size")</h3> 3059 @{ 3060 var potsizes = HttpContext.Current.Request.QueryString.GetValues("potsize"); 3061 if (potsizes == null) // Try to get from post instead 3062 { 3063 potsizes = HttpContext.Current.Request.Form.GetValues("potsize"); 3064 } 3065 var potsizeMin = 0; 3066 var potsizeMax = 0; 3067 if (potsizes != null) 3068 { 3069 if (potsizes.Length == 1) 3070 { 3071 potsizes = potsizes.First().Split(','); 3072 } 3073 3074 if (potsizes.Length == 2) 3075 { 3076 potsizeMin = Converter.ToInt32(potsizes.First()); 3077 potsizeMax = Converter.ToInt32(potsizes.Last()); 3078 } 3079 } 3080 } 3081 <div class="row filter-range-inputs"> 3082 <div class="col-xs-4"> 3083 <label>@Translate("Smartpage:Min", "min")</label> 3084 <input type="number" class="form-control js-min-value" name="potsize" data-is-minimum="true" value='@potsizeMin' /> 3085 </div> 3086 <div class="col-xs-4 pull-right"> 3087 <label>@Translate("Smartpage:Max", "max")</label> 3088 @{ 3089 if (potsizeMax == 0 || potsizeMax == 9999) 3090 { 3091 potsizeMax = 99; 3092 } 3093 } 3094 <input type="number" class="form-control js-max-value" data-system-max="9999" data-visual-max="@potsizeMax" name="potsize" value='@potsizeMax' /> 3095 </div> 3096 <br /> 3097 </div> 3098 <div class="filter-range-slider js-filter-range-slider"> 3099 <input id="slider-input" type="text" value="@(potsizeMin + "-" + potsizeMax)" data-slider-min='0' data-slider-max='@potsizeMax' data-slider-value='[@potsizeMin,@potsizeMax]' class="sr-only" /> 3100 <div class="clearfix"></div> 3101 <div class="min-value pull-left">0</div> 3102 <div class="max-value pull-right">@potsizeMax+</div> 3103 </div> 3104 </div> 3105 3106 <div class="clearfix"></div> 3107 3108 <div class="filter-range"> 3109 <h3>@Translate("Height", "Height")</h3> 3110 @{ 3111 var heights = HttpContext.Current.Request.QueryString.GetValues("height"); 3112 if (heights == null) // Try to get from post instead 3113 { 3114 heights = HttpContext.Current.Request.Form.GetValues("height"); 3115 } 3116 var heightMin = 0; 3117 var heightMax = 0; 3118 if (heights != null) 3119 { 3120 if (heights.Length == 1) 3121 { 3122 heights = heights.First().Split(','); 3123 } 3124 3125 if (heights.Length == 2) 3126 { 3127 heightMin = Converter.ToInt32(heights.First()); 3128 heightMax = Converter.ToInt32(heights.Last()); 3129 } 3130 } 3131 } 3132 <div class="row filter-range-inputs"> 3133 <div class="col-xs-4"> 3134 <label>@Translate("Smartpage:Min", "min")</label> 3135 <input type="number" class="form-control js-min-value" name="height" data-is-minimum="true" value='@heightMin' /> 3136 </div> 3137 <div class="col-xs-4 pull-right"> 3138 <label>@Translate("Smartpage:Max", "max")</label> 3139 @{ 3140 if (heightMax == 0 || heightMax == 9999) 3141 { 3142 heightMax = 300; 3143 } 3144 } 3145 <input type="number" class="form-control js-max-value" data-system-max="9999" data-visual-max="@heightMax" name="height" value='@heightMax' /> 3146 </div> 3147 <br /> 3148 </div> 3149 <div class="filter-range-slider js-filter-range-slider"> 3150 <input id="slider-input" type="text" value="@(heightMin + "-" + heightMax)" data-slider-min='0' data-slider-max='200' data-slider-value='[@heightMin,@heightMax]' class="sr-only" /> 3151 <div class="clearfix"></div> 3152 <div class="min-value pull-left">0</div> 3153 <div class="max-value pull-right">@heightMax+</div> 3154 </div> 3155 </div> 3156 3157 <div class="clearfix"></div> 3158 3159 @{ 3160 3161 if (Model != null && Model.FacetGroups != null) 3162 { 3163 var facets = Model.FacetGroups.FirstOrDefault(); 3164 var colors = facets.Facets.FirstOrDefault(g => g.QueryParameter == "color"); 3165 if (colors != null && colors.Options.Any()) 3166 { 3167 <div class="filter-color filter-container clearfix"> 3168 <h3>@Translate("Color", "Color")</h3> 3169 <ul class="list-unstyled"> 3170 @foreach (var i in colors.Options) 3171 { 3172 <li class="col-md-6 col-sm-12"> 3173 <label class="filter-color-item row"> 3174 <input type="checkbox" class="js-select-filter-option" name='@colors.QueryParameter' value='@i.Value' checked='@i.Selected' /> 3175 &nbsp; 3176 @{ 3177 if (i.Value != "XXXXXX") 3178 { 3179 var backgroundColor = "#" + i.Value; 3180 <span class="filter-color" style="background-color: @backgroundColor" title='@i.Label'> 3181 &nbsp; 3182 </span> 3183 } 3184 else 3185 { 3186 <span class="filter-color" title='@i.Label'> 3187 <img src="/Files/images/multi-color.png" class="img-responsive" title='@i.Label' alt='@i.Label' /> 3188 </span> 3189 } 3190 } 3191 &nbsp;<span>(@i.Count)</span> 3192 </label> 3193 </li> 3194 } 3195 </ul> 3196 </div> 3197 } 3198 3199 var categories = facets.Facets.FirstOrDefault(g => g.QueryParameter == "category"); 3200 3201 if (categories != null && categories.Options.Any()) 3202 { 3203 var totalResults = categories.OptionResultTotalCount; 3204 <h3>@Translate("Filters.Categories", "Categories")</h3> 3205 if (totalResults < 10) 3206 { 3207 // show checkboxes 3208 foreach (var i in categories.Options) 3209 { 3210 3211 var isselected = i.Selected ? "checked" : ""; 3212 var inputID = i.Value; 3213 <div class="checkbox"> 3214 <label> 3215 <input type='checkbox' name='@categories.QueryParameter' class='js-select-filter-option' value='@i.Value' @isselected /> @i.Label (@i.Count) 3216 </label> 3217 </div> 3218 } 3219 } 3220 else 3221 { 3222 // show select 3223 <select class="select2 js-select-filter-option js-select2-filter" name='@categories.QueryParameter' multiple="multiple" data-placeholder="@Translate("Smartpage:Ecom.SelectCategory", "Select category...")"> 3224 @foreach (var i in categories.Options) 3225 { 3226 var isselected = i.Selected ? "selected" : ""; 3227 <option class='js-select-filter-option' value='@i.Value' @isselected>@i.Label (@i.Count)</option> 3228 } 3229 </select> 3230 } 3231 3232 } 3233 3234 var productColors = facets.Facets.FirstOrDefault(pc => pc.QueryParameter == "prodColor"); 3235 3236 3237 if(productColors != null && productColors.Options.Any()) 3238 { 3239 <h3>@Translate("Color", "Color")</h3> 3240 <select class="select2 js-select-filter-option js-select2-filter" name='@productColors.QueryParameter' multiple="multiple" data-placeholder="@Translate("selectcolor", "Select color")"> 3241 @foreach (var i in productColors.Options) 3242 { 3243 var isselected = i.Selected ? "selected" : ""; 3244 <option class='js-select-filter-option' value='@i.Value' @isselected>@i.Label (@i.Count)</option> 3245 } 3246 </select> 3247 } 3248 3249 var productThemes = facets.Facets.FirstOrDefault(pc => pc.QueryParameter == "theme"); 3250 3251 if(productThemes != null && productThemes.Options.Any()) 3252 { 3253 <h3>@Translate("Theme", "Theme")</h3> 3254 <select class="select2 js-select-filter-option js-select2-filter" name='@productThemes.QueryParameter' multiple="multiple" data-placeholder="@Translate("selecttheme", "Select theme")"> 3255 @foreach (var i in productThemes.Options) 3256 { 3257 var isselected = i.Selected ? "selected" : ""; 3258 <option class='js-select-filter-option' value='@i.Value' @isselected>@i.Label (@i.Count)</option> 3259 } 3260 </select> 3261 } 3262 3263 var productStages = facets.Facets.FirstOrDefault(pc => pc.QueryParameter == "stage"); 3264 3265 if(productStages != null && productStages.Options.Any()) 3266 { 3267 <h3>@Translate("Stage", "Stage")</h3> 3268 <select class="select2 js-select-filter-option js-select2-filter" name='@productStages.QueryParameter' multiple="multiple" data-placeholder="@Translate("selectstage", "Select stage")"> 3269 @foreach (var i in productStages.Options) 3270 { 3271 var isselected = i.Selected ? "selected" : ""; 3272 <option class='js-select-filter-option' value='@i.Value' @isselected>@i.Label (@i.Count)</option> 3273 } 3274 </select> 3275 } 3276 3277 var productTypeCodes = facets.Facets.FirstOrDefault(pc => pc.QueryParameter == "typecode"); 3278 3279 if(productTypeCodes != null && productTypeCodes.Options.Any()) 3280 { 3281 <h3>@Translate("TypeCode", "TypeCode")</h3> 3282 <select class="select2 js-select-filter-option js-select2-filter" name='@productTypeCodes.QueryParameter' multiple="multiple" data-placeholder="@Translate("selecttypecode", "Select typecode")"> 3283 @foreach (var i in productTypeCodes.Options) 3284 { 3285 var isselected = i.Selected ? "selected" : ""; 3286 <option class='js-select-filter-option' value='@i.Value' @isselected>@i.Label (@i.Count)</option> 3287 } 3288 </select> 3289 } 3290 //LBE 06-05-2024, Commented out because of Germany cant live with - in th naming 3291 /*var productColorLeaves = facets.Facets.FirstOrDefault(pc => pc.QueryParameter == "colorleaves"); 3292 3293 if(productColorLeaves != null && productColorLeaves.Options.Any()) 3294 { 3295 <h3>@Translate("ColorLeaves", "Leave colors")</h3> 3296 <select class="select2 js-select-filter-option js-select2-filter" name='@productColorLeaves.QueryParameter' multiple="multiple" data-placeholder="@Translate("selectcolorleaves", "Select leaf color(s)")"> 3297 @foreach (var i in productColorLeaves.Options) 3298 { 3299 var isselected = i.Selected ? "selected" : ""; 3300 <option class='js-select-filter-option' value='@i.Value' @isselected>@i.Label (@i.Count)</option> 3301 } 3302 </select> 3303 } 3304 3305 var productCommonName = facets.Facets.FirstOrDefault(pc => pc.QueryParameter == "commonname"); 3306 3307 if(productCommonName != null && productCommonName.Options.Any()) 3308 { 3309 <h3>@Translate("CommonName", "Common name")</h3> 3310 <select class="select2 js-select-filter-option js-select2-filter" name='@productCommonName.QueryParameter' multiple="multiple" data-placeholder="@Translate("selectcommonname", "Select common name(s)")"> 3311 @foreach (var i in productCommonName.Options) 3312 { 3313 var isselected = i.Selected ? "selected" : ""; 3314 <option class='js-select-filter-option' value='@i.Value' @isselected>@i.Label (@i.Count)</option> 3315 } 3316 </select> 3317 } 3318 3319 var productPotType = facets.Facets.FirstOrDefault(pc => pc.QueryParameter == "pottype"); 3320 3321 if(productPotType != null && productPotType.Options.Any()) 3322 { 3323 <h3>@Translate("PotType", "Pot type")</h3> 3324 <select class="select2 js-select-filter-option js-select2-filter" name='@productPotType.QueryParameter' multiple="multiple" data-placeholder="@Translate("selectpottype", "Select pot type(s)")"> 3325 @foreach (var i in productPotType.Options) 3326 { 3327 var isselected = i.Selected ? "selected" : ""; 3328 <option class='js-select-filter-option' value='@i.Value' @isselected>@i.Label (@i.Count)</option> 3329 } 3330 </select> 3331 } 3332 3333 var productBrand = facets.Facets.FirstOrDefault(pc => pc.QueryParameter == "brand"); 3334 3335 if(productBrand != null && productBrand.Options.Any()) 3336 { 3337 <h3>@Translate("Brand", "Brand")</h3> 3338 <select class="select2 js-select-filter-option js-select2-filter" name='@productBrand.QueryParameter' multiple="multiple" data-placeholder="@Translate("selectbrand", "Select brand(s)")"> 3339 @foreach (var i in productBrand.Options) 3340 { 3341 var isselected = i.Selected ? "selected" : ""; 3342 <option class='js-select-filter-option' value='@i.Value' @isselected>@i.Label (@i.Count)</option> 3343 } 3344 </select> 3345 }*/ 3346 3347 var productLightings = facets.Facets.FirstOrDefault(pc => pc.QueryParameter == "lighting"); 3348 if(productLightings != null && productLightings.Options.Any()) 3349 { 3350 3351 <h3>@Translate("Lighting", "Lighting")</h3> 3352 if(productLightings.OptionResultTotalCount > 10) 3353 { 3354 // show checkboxes 3355 foreach (var i in productLightings.Options) 3356 { 3357 3358 var isselected = i.Selected ? "checked" : ""; 3359 var inputID = i.Value; 3360 <div class="checkbox"> 3361 <label> 3362 <input type='checkbox' name='@productLightings.QueryParameter' class='js-select-filter-option' value='@i.Value' @isselected /> @i.Label (@i.Count) 3363 </label> 3364 </div> 3365 } 3366 } 3367 else 3368 { 3369 3370 <select class="select2 js-select-filter-option js-select2-filter" name='@productLightings.QueryParameter' multiple="multiple" data-placeholder="@Translate("selectlighting", "Select lighting")"> 3371 @foreach (var i in productLightings.Options) 3372 { 3373 var isselected = i.Selected ? "selected" : ""; 3374 <option class='js-select-filter-option' value='@i.Value' @isselected>@i.Label (@i.Count)</option> 3375 } 3376 </select> 3377 } 3378 } 3379 if (EnableManufacturerFiltering()) 3380 { 3381 var manufacturers = facets.Facets.FirstOrDefault(g => g.QueryParameter == "manuid"); 3382 if (manufacturers != null) 3383 { 3384 var dwManufacturers = Dynamicweb.Ecommerce.Common.Context.Manufacturers; 3385 var manufacturersResults = manufacturers.OptionResultTotalCount; 3386 3387 <div class="filter-manufacturer filter-container clearfix"> 3388 <h3>@Translate("Grower", "Grower")</h3> 3389 3390 @if (manufacturersResults < 10) 3391 { 3392 foreach (var i in manufacturers.Options) 3393 { 3394 3395 bool isChecked = i.Selected; 3396 var inputID = i.Value; 3397 <div class="checkbox"> 3398 <label> 3399 <input type='checkbox' name='@manufacturers.QueryParameter' class='js-select-filter-option' value='@i.Value' checked="@isChecked" /> @i.Label (@i.Count) 3400 </label> 3401 </div> 3402 } 3403 3404 } 3405 else 3406 { 3407 <select class="select2 js-select-filter-option js-select2-filter" name='@manufacturers.QueryParameter' multiple="multiple" data-placeholder="@Translate("Smartpage:Ecom.SelectGrower", "Select grower...")"> 3408 @foreach (var i in manufacturers.Options) 3409 { 3410 var isselected = i.Selected ? "selected" : ""; 3411 var manufacturer = dwManufacturers.FirstOrDefault(m => m.Id == i.Value); 3412 var manufacturerLink = ""; 3413 if (manufacturer != null && !string.IsNullOrEmpty(manufacturer.Web)) 3414 { 3415 manufacturerLink = manufacturer.Web; 3416 if (!manufacturerLink.StartsWith("http", StringComparison.InvariantCultureIgnoreCase)) 3417 { 3418 manufacturerLink = "http://" + manufacturerLink; 3419 } 3420 } 3421 var manufacturerDescription = i.Label + "/" + i.Value; 3422 @*<pre>@string.Join("\n", i.Values.Select(e => string.Format("{0}: {1}", e.Key, System.Web.HttpUtility.HtmlEncode(e.Value))).ToArray())</pre>*@ 3423 3424 <option value='@i.Value' data-link="@manufacturerLink" @isselected>@manufacturerDescription (@i.Count)</option> 3425 } 3426 </select> 3427 } 3428 </div> 3429 } 3430 } 3431 3432 var news = facets.Facets.FirstOrDefault(g => g.QueryParameter == "new"); 3433 if (news != null && news.Options.Any(i => Dynamicweb.Core.Converter.ToBoolean(i.Value))) 3434 { 3435 <div class="clearfix"></div> 3436 <div class="filter-color filter-container"> 3437 <h3>@Translate("Smartpage:NewProduct", "New")</h3> 3438 <ul class="list-unstyled"> 3439 @foreach (var i in news.Options) 3440 { 3441 if (Dynamicweb.Core.Converter.ToBoolean(i.Value)) 3442 { 3443 <li class="col-md-6 col-sm-12"> 3444 <label class="filter-color-item row"> 3445 <input type="checkbox" class="js-select-filter-option" name='@news.QueryParameter' value='@i.Value' checked='@i.Selected' /> 3446 &nbsp;<span title='@i.Value'> 3447 @Translate("show all", "Show all")&nbsp;(@i.Count) 3448 </span> 3449 </label> 3450 </li> 3451 } 3452 } 3453 </ul> 3454 </div> 3455 } 3456 } 3457 } 3458 </form> 3459 3460 3461 @*@Snippet Start("StyleSheet") 3462 <link href="@designBaseUrl/Assets/plugins/bootstrap-slider/dist/css/bootstrap-slider.min.css" rel="stylesheet" /> 3463 <link href="@designBaseUrl/Assets/plugins/selectize.js/dist/css/selectize.css" rel="stylesheet" /> 3464 <link href="@designBaseUrl/Assets/plugins/selectize.js/dist/css/selectize.bootstrap3.css" rel="stylesheet" /> 3465 <link href="@designBaseUrl/Assets/plugins/select2/select2-3.5.4/select2.css" rel="stylesheet" /> 3466 @Snippet End("StyleSheet")*@ 3467 3468 <div class="clearfix">&nbsp;</div> 3469 </div> 3470 <div class="col-sm-9"> 3471 <div class="js-products border-left row"> 3472 @if (Model.TotalProductsCount == 0) 3473 { 3474 <div class="col-sm-12"> 3475 @Translate("Smartpage:eCom.SearchNoProducts", "Ingen produkter matcher dine søgekriterier") 3476 </div> 3477 } 3478 else 3479 { 3480 if (viewMode == "list" || String.IsNullOrEmpty(viewMode)) 3481 { 3482 @RenderListView() 3483 } 3484 else if (viewMode == "grid") 3485 { 3486 @RenderTilesView() 3487 } 3488 else if (viewMode == "photo") 3489 { 3490 @RenderPhotoView() 3491 } 3492 else if (viewMode == "quicklist") 3493 { 3494 @RenderQuicklistView() 3495 } 3496 } 3497 3498 </div> 3499 </div> 3500 <div class="clearfix"></div> 3501 </div> 3502 <div class="productlistnavigation navigation-bottom"> 3503 <span class="productcount"> 3504 @Model.TotalProductsCount 3505 @Translate("SmartPage:Product.Paging.ProductsFound", "produkter fundet") 3506 </span> 3507 3508 @{ 3509 currentPageNumber = string.IsNullOrWhiteSpace(HttpContext.Current.Request["PageNum"]) ? "1" : HttpContext.Current.Request["PageNum"]; 3510 if (Converter.ToInt32(currentPageNumber) <= Model.PageCount && Model.PageCount > 0) 3511 { 3512 <input type="hidden" class="current-page js-current-page-number" value='@currentPageNumber' /> 3513 } 3514 } 3515 3516 </div> 3517 3518 <div class="clearfix"></div> 3519 @PricesWithVATStatus("bottom") 3520 3521 3522 <div id="js-list-modal-full" class="modal fade product-list-modal" tabindex="-1" role="dialog"> 3523 <div class="modal-dialog"> 3524 <div class="modal-content"> 3525 <div class="modal-header"> 3526 <button type="button" class="close custom-close-modal" onclick="$('#js-list-modal-full').modal('hide');"><span aria-hidden="true">&times;</span></button> 3527 <h4 class="modal-title js-modal-title"></h4> 3528 </div> 3529 <div class="modal-body"> 3530 <div class="row"> 3531 <div class="col-sm-12"> 3532 <img src="" class="js-modal-image" /> 3533 </div> 3534 </div> 3535 </div> 3536 </div> 3537 </div> 3538 </div> 3539