Error executing template "Designs/Default/eCom/ProductCatalog/ProductList.cshtml"
System.Exception: No valid SMTP host found. Please specify a valid SMTP host in Control Panel. Errors: ggexc01.gg.priv: System.Net.Mail.SmtpException: Failure sending mail. ---> System.Net.WebException: Unable to connect to the remote server ---> System.Net.Sockets.SocketException: No connection could be made because the target machine actively refused it 10.30.3.44:25
   at System.Net.Sockets.Socket.DoConnect(EndPoint endPointSnapshot, SocketAddress socketAddress)
   at System.Net.ServicePoint.ConnectSocketInternal(Boolean connectFailure, Socket s4, Socket s6, Socket& socket, IPAddress& address, ConnectSocketState state, IAsyncResult asyncResult, Exception& exception)
   --- End of inner exception stack trace ---
   at System.Net.ServicePoint.GetConnection(PooledStream PooledStream, Object owner, Boolean async, IPAddress& address, Socket& abortSocket, Socket& abortSocket6)
   at System.Net.PooledStream.Activate(Object owningObject, Boolean async, GeneralAsyncDelegate asyncCallback)
   at System.Net.ConnectionPool.GetConnection(Object owningObject, GeneralAsyncDelegate asyncCallback, Int32 creationTimeout)
   at System.Net.Mail.SmtpConnection.GetConnection(ServicePoint servicePoint)
   at System.Net.Mail.SmtpClient.GetConnection()
   at System.Net.Mail.SmtpClient.Send(MailMessage message)
   --- End of inner exception stack trace ---
   at System.Net.Mail.SmtpClient.Send(MailMessage message)
   at Dynamicweb.Mailing.EmailHandler.SendUsingSmptProtocol(MailMessage mailMessage, SmtpSender sender, List`1 hostList)
   at Dynamicweb.Mailing.EmailHandler.SendUsingSmptProtocol(MailMessage mailMessage, SmtpSender sender, List`1 hostList)
   at Dynamicweb.Mailing.EmailHandler.TryToSendEmail(MailMessage mailMessage, Boolean isFirstError, Boolean wasSent, List`1 hostList, ILogger systemSMTPLogger, SmtpSender sender)
   at Dynamicweb.Mailing.EmailHandler.Send(MailMessage mailMessage, Boolean logging, Boolean throwException, String username, String password, Int32 port, Boolean useSsl, String host)
   at Dynamicweb.Mailing.EmailHandler.Send(MailMessage mailMessage, Boolean logging, Boolean throwException)
   at Dynamicweb.Mailing.EmailHandler.Send(MailMessage mailMessage)
   at Dynamicweb.eCommerce.LiveIntegration.Logger.SendMail(String message) in C:\Repos\GasaGroup-Dynamicweb\DynamicwebLiveIntegrationProject1.0.0.2\Dynamicweb.eCommerce.LiveIntegration\Logger.cs:line 291
   at Dynamicweb.eCommerce.LiveIntegration.Logger.SendLog(String lastError, Boolean isLastErrorInLog) in C:\Repos\GasaGroup-Dynamicweb\DynamicwebLiveIntegrationProject1.0.0.2\Dynamicweb.eCommerce.LiveIntegration\Logger.cs:line 205
   at Dynamicweb.eCommerce.LiveIntegration.Logger.Log(ErrorLevel errorLevel, String logLine) in C:\Repos\GasaGroup-Dynamicweb\DynamicwebLiveIntegrationProject1.0.0.2\Dynamicweb.eCommerce.LiveIntegration\Logger.cs:line 118
   at Dynamicweb.eCommerce.LiveIntegration.Connector.IsWebServiceConnectionAvailable() in C:\Repos\GasaGroup-Dynamicweb\DynamicwebLiveIntegrationProject1.0.0.2\Dynamicweb.eCommerce.LiveIntegration\Connector.cs:line 168
   at Dynamicweb.eCommerce.LiveIntegration.NotificationSubscribers.PageOnGlobalTagsObserver.OnNotify(String notification, NotificationArgs args) in C:\Repos\GasaGroup-Dynamicweb\DynamicwebLiveIntegrationProject1.0.0.2\Dynamicweb.eCommerce.LiveIntegration\NotificationSubscribers\PageOnGlobalTagsObserver.cs:line 40
   at Dynamicweb.Extensibility.Notifications.NotificationManager.Notify(String notification, NotificationArgs eventArgs)
   at Dynamicweb.Frontend.PageView.GetGlobalTemplateTags()
   at CompiledRazorTemplates.Dynamic.RazorEngine_ab50bb04cda84e2ea0193613e5c80159.Execute() in E:\Dynamicweb.net\Solutions\Webshop\Files\Templates\Designs\Default\eCom\ProductCatalog\ProductList.cshtml:line 2803
   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,R0lGODlhEAAQAPQAAP///wAAAPDw8IqKiuDg4EZGRnp6egAAAFhYWCQkJKysrL6+vhQUFJycnAQEBDY2NmhoaAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH/C05FVFNDQVBFMi4wAwEAAAAh/hpDcmVhdGVkIHdpdGggYWpheGxvYWQuaW5mbwAh+QQJCgAAACwAAAAAEAAQAAAFdyAgAgIJIeWoAkRCCMdBkKtIHIngyMKsErPBYbADpkSCwhDmQCBethRB6Vj4kFCkQPG4IlWDgrNRIwnO4UKBXDufzQvDMaoSDBgFb886MiQadgNABAokfCwzBA8LCg0Egl8jAggGAA1kBIA1BAYzlyILczULC2UhACH5BAkKAAAALAAAAAAQABAAAAV2ICACAmlAZTmOREEIyUEQjLKKxPHADhEvqxlgcGgkGI1DYSVAIAWMx+lwSKkICJ0QsHi9RgKBwnVTiRQQgwF4I4UFDQQEwi6/3YSGWRRmjhEETAJfIgMFCnAKM0KDV4EEEAQLiF18TAYNXDaSe3x6mjidN1s3IQAh+QQJCgAAACwAAAAAEAAQAAAFeCAgAgLZDGU5jgRECEUiCI+yioSDwDJyLKsXoHFQxBSHAoAAFBhqtMJg8DgQBgfrEsJAEAg4YhZIEiwgKtHiMBgtpg3wbUZXGO7kOb1MUKRFMysCChAoggJCIg0GC2aNe4gqQldfL4l/Ag1AXySJgn5LcoE3QXI3IQAh+QQJCgAAACwAAAAAEAAQAAAFdiAgAgLZNGU5joQhCEjxIssqEo8bC9BRjy9Ag7GILQ4QEoE0gBAEBcOpcBA0DoxSK/e8LRIHn+i1cK0IyKdg0VAoljYIg+GgnRrwVS/8IAkICyosBIQpBAMoKy9dImxPhS+GKkFrkX+TigtLlIyKXUF+NjagNiEAIfkECQoAAAAsAAAAABAAEAAABWwgIAICaRhlOY4EIgjH8R7LKhKHGwsMvb4AAy3WODBIBBKCsYA9TjuhDNDKEVSERezQEL0WrhXucRUQGuik7bFlngzqVW9LMl9XWvLdjFaJtDFqZ1cEZUB0dUgvL3dgP4WJZn4jkomWNpSTIyEAIfkECQoAAAAsAAAAABAAEAAABX4gIAICuSxlOY6CIgiD8RrEKgqGOwxwUrMlAoSwIzAGpJpgoSDAGifDY5kopBYDlEpAQBwevxfBtRIUGi8xwWkDNBCIwmC9Vq0aiQQDQuK+VgQPDXV9hCJjBwcFYU5pLwwHXQcMKSmNLQcIAExlbH8JBwttaX0ABAcNbWVbKyEAIfkECQoAAAAsAAAAABAAEAAABXkgIAICSRBlOY7CIghN8zbEKsKoIjdFzZaEgUBHKChMJtRwcWpAWoWnifm6ESAMhO8lQK0EEAV3rFopIBCEcGwDKAqPh4HUrY4ICHH1dSoTFgcHUiZjBhAJB2AHDykpKAwHAwdzf19KkASIPl9cDgcnDkdtNwiMJCshACH5BAkKAAAALAAAAAAQABAAAAV3ICACAkkQZTmOAiosiyAoxCq+KPxCNVsSMRgBsiClWrLTSWFoIQZHl6pleBh6suxKMIhlvzbAwkBWfFWrBQTxNLq2RG2yhSUkDs2b63AYDAoJXAcFRwADeAkJDX0AQCsEfAQMDAIPBz0rCgcxky0JRWE1AmwpKyEAIfkECQoAAAAsAAAAABAAEAAABXkgIAICKZzkqJ4nQZxLqZKv4NqNLKK2/Q4Ek4lFXChsg5ypJjs1II3gEDUSRInEGYAw6B6zM4JhrDAtEosVkLUtHA7RHaHAGJQEjsODcEg0FBAFVgkQJQ1pAwcDDw8KcFtSInwJAowCCA6RIwqZAgkPNgVpWndjdyohACH5BAkKAAAALAAAAAAQABAAAAV5ICACAimc5KieLEuUKvm2xAKLqDCfC2GaO9eL0LABWTiBYmA06W6kHgvCqEJiAIJiu3gcvgUsscHUERm+kaCxyxa+zRPk0SgJEgfIvbAdIAQLCAYlCj4DBw0IBQsMCjIqBAcPAooCBg9pKgsJLwUFOhCZKyQDA3YqIQAh+QQJCgAAACwAAAAAEAAQAAAFdSAgAgIpnOSonmxbqiThCrJKEHFbo8JxDDOZYFFb+A41E4H4OhkOipXwBElYITDAckFEOBgMQ3arkMkUBdxIUGZpEb7kaQBRlASPg0FQQHAbEEMGDSVEAA1QBhAED1E0NgwFAooCDWljaQIQCE5qMHcNhCkjIQAh+QQJCgAAACwAAAAAEAAQAAAFeSAgAgIpnOSoLgxxvqgKLEcCC65KEAByKK8cSpA4DAiHQ/DkKhGKh4ZCtCyZGo6F6iYYPAqFgYy02xkSaLEMV34tELyRYNEsCQyHlvWkGCzsPgMCEAY7Cg04Uk48LAsDhRA8MVQPEF0GAgqYYwSRlycNcWskCkApIyEAOwAAAAAAAAAAAA=="; 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