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 + "&GroupId=" + product.PrimaryGroupId + "&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 + "&Resolution=75&Compression=70&Width=500&Height=500&Crop=5&fillcanvas=true";
726 string fallBackImage = $"/Admin/Public/getimage.ashx?Image={image}&Resolution=75&Compression=70&Width=500&Height=500&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 ×
801 @productInfo.ColliSize
802 </td>
803 <td>
804 <span class="js-colli-per-layer">@productInfo.ColliPerLayer</span>
805 × @productInfo.ColliSize
806 </td>
807 <td>
808 <span class="js-colli-per-cc">@productInfo.ColliPerCc</span>
809 × @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 + "&GroupId=" + product.PrimaryGroupId + "&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 + "&Resolution=75&Compression=70&Width=500&Height=500&Crop=5&fillcanvas=true";
1335 string fallBackImage = $"/Admin/Public/getimage.ashx?Image={image}&Resolution=75&Compression=70&Width=500&Height=500&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 Ø @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> </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 ×
1416 @productInfo.ColliSize
1417 </td>
1418 <td>
1419 <span class="js-colli-per-layer">@productInfo.ColliPerLayer</span>
1420 × @productInfo.ColliSize
1421 </td>
1422 <td>
1423 <span class="js-colli-per-cc">@productInfo.ColliPerCc</span>
1424 × @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">×</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 + "&GroupId=" + product.PrimaryGroupId + "&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 + "&Resolution=75&Compression=70&Width=500&Height=500&Crop=5&fillcanvas=true&AlternativeImage=" + defaultImage;
1867 string fallBackImage = $"/Admin/Public/getimage.ashx?Image={image}&Resolution=75&Compression=70&Width=500&Height=500&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 ×
1933 @productInfo.ColliSize
1934 </td>
1935 <td>
1936 <span class="js-colli-per-layer">@productInfo.ColliPerLayer</span>
1937 × @productInfo.ColliSize
1938 </td>
1939 <td>
1940 <span class="js-colli-per-cc">@productInfo.ColliPerCc</span>
1941 × @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 + "&GroupId=" + product.PrimaryGroupId + "&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 + "&Resolution=75&Compression=70&Width=500&Height=500&Crop=5&fillcanvas=True";
2280 string fallBackImage = $"/Admin/Public/getimage.ashx?Image={image}&Resolution=75&Compression=70&Width=500&Height=500&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 Ø @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"> </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> </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 ×
2368 @productInfo.ColliSize
2369 </td>
2370 <td>
2371 <span class="js-colli-per-layer">@productInfo.ColliPerLayer</span>
2372 × @productInfo.ColliSize
2373 </td>
2374 <td>
2375 <span class="js-colli-per-cc">@productInfo.ColliPerCc</span>
2376 × @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">×</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 + "&Resolution=75&Compression=70&Width=720&Width=480&Crop=5&AlternativeImage=" + defaultImage;
2733 string fallBackImage = $"/Admin/Public/getimage.ashx?Image={loopUrl}&Resolution=75&Compression=70&Width=720&Width=480&Crop=5&AlternativeImage={defaultImage}";
2734 string currentThumbUrl = cdnHost + "/Admin/Public/getimage.ashx?Image=" + loopUrl + "&Compression=90&Width=63&&Height=42&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 + "&Resolution=75&Compression=70&Width=720&Width=480&Crop=5&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 Ø
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> </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 : "&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
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
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 <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 <span title='@i.Value'>
3447 @Translate("show all", "Show all") (@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"> </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">×</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