Error executing template "Designs/Default/eCom/ProductCatalog/ProductList.cshtml"
System.ArgumentException: An item with the same key has already been added.
at System.ThrowHelper.ThrowArgumentException(ExceptionResource resource)
at System.Collections.Generic.Dictionary`2.Insert(TKey key, TValue value, Boolean add)
at Dynamicweb.Rendering.Translation.Source.GetTranslationSource(String designName, String moduleName, String cultureName)
at Dynamicweb.Rendering.Template.TranslateText(String text, String defaultValue, String cultureName)
at Dynamicweb.Rendering.TemplateBase`1.Translate(String text, String defaultValue)
at CompiledRazorTemplates.Dynamic.RazorEngine_314168f031e64d489542a6782ca37780.<RenderSearch>b__50_0(TextWriter __razor_helper_writer) in E:\Dynamicweb.net\Solutions\Webshop\Files\Templates\Designs\Default\eCom\ProductCatalog\ProductList.cshtml:line 607
at CompiledRazorTemplates.Dynamic.RazorEngine_314168f031e64d489542a6782ca37780.Execute() in E:\Dynamicweb.net\Solutions\Webshop\Files\Templates\Designs\Default\eCom\ProductCatalog\ProductList.cshtml:line 2832
at RazorEngine.Templating.TemplateBase.RazorEngine.Templating.ITemplate.Run(ExecuteContext context, TextWriter reader)
at RazorEngine.Templating.RazorEngineService.RunCompile(ITemplateKey key, TextWriter writer, Type modelType, Object model, DynamicViewBag viewBag)
at RazorEngine.Templating.RazorEngineServiceExtensions.<>c__DisplayClass16_0.<RunCompile>b__0(TextWriter writer)
at RazorEngine.Templating.RazorEngineServiceExtensions.WithWriter(Action`1 withWriter)
at Dynamicweb.Rendering.RazorTemplateRenderingProvider.Render(Template template)
at Dynamicweb.Rendering.TemplateRenderingService.Render(Template template)
at Dynamicweb.Rendering.Template.RenderRazorTemplate()
1 @inherits ViewModelTemplate<ProductListViewModel>
2 @using Dynamicweb;
3 @using Dynamicweb.Core;
4 @using Dynamicweb.Environment;
5 @using Dynamicweb.Environment.Helpers;
6 @using Dynamicweb.Rendering;
7 @using Dynamicweb.Ecommerce.ProductCatalog;
8 @using System.Linq;
9 @using Cookie = Dynamicweb.Environment.Cookie;
10 @using Gasa.ProductInformation.Helpers;
11
12 @using Dynamicweb.Ecommerce.Orders;
13 @using System.Globalization;
14 @using Dynamicweb.Security.UserManagement;
15 @using Dynamicweb.Security.UserManagement.Common.CustomFields;
16 @using Dynamicweb;
17 @using Dynamicweb.Core;
18 @using Dynamicweb.Environment;
19 @using Dynamicweb.Environment.Helpers;
20 @using Dynamicweb.Rendering;
21 @using Dynamicweb.Ecommerce.ProductCatalog;
22 @using System.Linq;
23 @using Gasa.ProductInformation;
24 @using Gasa.Calendar;
25
26 @* Note that this file will be inserted directly into another one by Dynamicweb IncludeFile
27 before evaluating the Razor code, so keep the syntax right *@
28
29
30 @* global functions *@
31
32 @functions {
33 bool checkIfFileExists(string imgURL)
34 {
35 return System.IO.File.Exists(System.Web.HttpContext.Current.Server.MapPath(imgURL));
36 }
37 string FormatDiameter(string value)
38 {
39 if (string.IsNullOrEmpty(value))
40 {
41 return value;
42 }
43
44 Decimal d;
45 if (Decimal.TryParse(value, out d))
46 {
47 return Converter.ToDouble(value).ToString("0.0", Dynamicweb.Frontend.PageView.Current().Area.CultureInfo.NumberFormat);
48 //return d.ToString("0.0", Base.GetCulture(true));
49 }
50
51 return value;
52 }
53
54 string FormatPrice(string value)
55 {
56 if (string.IsNullOrEmpty(value))
57 {
58 return value;
59 }
60
61 Decimal d;
62 if (Decimal.TryParse(value, out d))
63 {
64 return Converter.ToDouble(value).ToString("0.00", Dynamicweb.Frontend.PageView.Current().Area.CultureInfo.NumberFormat);
65 }
66
67 return value;
68 }
69
70 string AvailableDeliveryDay(int leadDays)
71 {
72 DateTime today = DateTime.Now.Date;
73 DateTime availableDate = today;
74 DateTime deliveryDate = CalenderHelper.ParseDateTime(Dynamicweb.Ecommerce.Common.Context.Cart.OrderFieldValues.GetOrderFieldValue("DeadlineTime").Value);
75 TimeSpan daysDifference = deliveryDate - today;
76 CultureInfo localLanguage = System.Threading.Thread.CurrentThread.CurrentCulture;
77 string result;
78
79 int leadWeekendDays = 0;
80
81
82 // check how many weekends within lead days
83 for (var i = 0; i < leadDays; i++)
84 {
85 if (availableDate.AddDays(i).DayOfWeek == DayOfWeek.Saturday)
86 {
87 leadWeekendDays++;
88 }
89 else if (availableDate.AddDays(i).DayOfWeek == DayOfWeek.Sunday)
90 {
91 leadWeekendDays++;
92 }
93 }
94
95 // check how many weekends after lead weekdays
96 for (var i = 0; i < leadWeekendDays; i++)
97 {
98 if (availableDate.AddDays(leadDays + i).DayOfWeek == DayOfWeek.Saturday)
99 {
100 leadWeekendDays++;
101 }
102 else if (availableDate.AddDays(leadDays + i).DayOfWeek == DayOfWeek.Sunday)
103 {
104 leadWeekendDays++;
105 }
106 }
107
108 var leadDaysTotal = leadWeekendDays + leadDays;
109
110 availableDate = availableDate.AddDays(leadDaysTotal);
111
112 if (daysDifference.TotalDays >= leadDaysTotal && availableDate <= deliveryDate)
113 {
114 result = null;
115 }
116 else
117 {
118 result = availableDate.ToString("dd-MM-yyyy", localLanguage);
119 }
120 //result=daysDifference.TotalDays.ToString();
121 return result;
122 }
123
124 /*
125 bool EnableEditing()
126 {
127 return EnableEditableBarcode();
128 }
129 */
130
131 bool? _enableManufacturerPage;
132 bool EnableManufacturerPage()
133 {
134 if (!_enableManufacturerPage.HasValue)
135 {
136 if (Pageview.Page.PropertyItem != null && Converter.ToBoolean(Pageview.Page.PropertyItem["EnableManufacturer"]))
137 {
138 _enableManufacturerPage = true;
139 }
140 else
141 {
142 _enableManufacturerPage = false;
143 }
144 }
145 return _enableManufacturerPage.Value;
146 }
147
148 ///* generic validation of custom user fields */
149 //bool? returnCustomUserFieldValidation(string CustomerUserFieldString)
150 //{
151 // return GetCustomUserField<bool>(user, CustomerUserFieldString);
152 //}
153
154
155 bool? _displayPricesInclVat;
156 bool DisplayPricesInclVat()
157 {
158 if (!_displayPricesInclVat.HasValue)
159 {
160 _displayPricesInclVat = GetCustomUserField<bool>("AccessUser_DisplayPricesInclVat");
161 }
162 return _displayPricesInclVat.Value;
163 }
164
165 bool? _enableEditableItemNumber;
166 bool EnableEditableItemNumber()
167 {
168 if (!_enableEditableItemNumber.HasValue)
169 {
170 _enableEditableItemNumber = GetCustomUserField<bool>("AccessUser_EnableEditableItemNumber");
171 }
172 return _enableEditableItemNumber.Value;
173 }
174
175 //AccessUser_EnableManufacturerFiltering
176 bool? _enableManufacturerFiltering;
177 bool EnableManufacturerFiltering(bool chkEnableManufacturerPageEnableManufacturerPage = true)
178 {
179 if (chkEnableManufacturerPageEnableManufacturerPage && !EnableManufacturerPage())
180 return false;
181
182 if (!_enableManufacturerFiltering.HasValue)
183 {
184 _enableManufacturerFiltering = GetCustomUserField<bool>("AccessUser_EnableManufacturerFiltering");
185 }
186 return _enableManufacturerFiltering.Value;
187 }
188
189 bool? _enableCustomerItemNumber;
190 bool EnableCustomerItemNumber()
191 {
192 if (!_enableCustomerItemNumber.HasValue)
193 {
194 _enableCustomerItemNumber = GetCustomUserField<bool>("AccessUser_EnableCustomerItemNumber");
195 }
196 return _enableCustomerItemNumber.Value;
197 }
198
199 bool? _enableEditableRetailPrice;
200 bool EnableEditableRetailPrice()
201 {
202 if (!_enableEditableRetailPrice.HasValue)
203 {
204 _enableEditableRetailPrice = GetCustomUserField<bool>("AccessUser_EnableEditableRetailPrice");
205 }
206 return _enableEditableRetailPrice.Value;
207 }
208
209 bool? _enableEditableBarcode;
210 bool EnableEditableBarcode()
211 {
212 if (!_enableEditableBarcode.HasValue)
213 {
214 _enableEditableBarcode = GetCustomUserField<bool>("AccessUser_EnableEditableBarcode");
215 }
216 return _enableEditableBarcode.Value;
217 }
218
219 bool? _enableCustomerRetailPrice;
220 bool EnableCustomerRetailPrice()
221 {
222 if (!_enableCustomerRetailPrice.HasValue)
223 {
224 _enableCustomerRetailPrice = GetCustomUserField<bool>("AccessUser_EnableCustomerRetailPrice");
225 }
226 return _enableCustomerRetailPrice.Value;
227 }
228
229 bool? _enableCustomerBarcode;
230 bool EnableCustomerBarcode()
231 {
232 if (!_enableCustomerBarcode.HasValue)
233 {
234 _enableCustomerBarcode = GetCustomUserField<bool>("AccessUser_EnableCustomerBarcode");
235 }
236 return _enableCustomerBarcode.Value;
237
238 }
239
240 bool? _enableComments;
241 bool EnableComments()
242 {
243 if (!_enableComments.HasValue)
244 {
245 _enableComments = GetCustomUserField<bool>("AccessUser_EnableCommentOnLine");
246 }
247 return _enableComments.Value;
248 }
249
250 bool? _enableMinimumCCQuantity;
251 bool EnableMinimumCCQuantity()
252 {
253 if (!_enableMinimumCCQuantity.HasValue)
254 {
255 _enableMinimumCCQuantity = GetCustomUserField<bool>("AccessUser_EnableMinimumCCQuantity");
256 }
257 return _enableMinimumCCQuantity.Value;
258 }
259 bool? _enableFullCCCheck;
260 bool EnableFullCCCheck()
261 {
262 if (!_enableFullCCCheck.HasValue)
263 {
264 _enableFullCCCheck = GetCustomUserField<bool>("AccessUser_EnableFullCCCheck");
265 }
266 return _enableFullCCCheck.Value;
267 }
268
269 bool? _enableDisplayGrossMargin;
270 bool EnableDisplayOfGrossMargin()
271 {
272 if (DisablePrices())
273 return false;
274
275 if (!_enableDisplayGrossMargin.HasValue)
276 {
277 _enableDisplayGrossMargin = GetCustomUserField<bool>("AccessUser_DisplayGrossMargin");
278 }
279 return _enableDisplayGrossMargin.Value;
280 }
281
282 string GetGrossMargin(double retailPrice, double salesPrice)
283 {
284 var resultValue = ((retailPrice - salesPrice) * 100) / retailPrice;
285 return Converter.ToString(Math.Round(resultValue, 2)) + "%";
286 }
287
288
289 double? _minimumCCQuantity;
290 double MinimumCCQuantity(string flag = "")
291 {
292 if (!_minimumCCQuantity.HasValue)
293 {
294 _minimumCCQuantity = GetCustomUserField<double>("AccessUser_MinimumCCQuantity" + flag.ToUpper());
295 }
296 return _minimumCCQuantity.Value;
297 }
298
299 bool? _disablePrices;
300 bool DisablePrices()
301 {
302 if (!_disablePrices.HasValue)
303 {
304 _disablePrices = GetCustomUserField<bool>("AccessUser_DisablePrices");
305 }
306 return _disablePrices.Value;
307 }
308
309 double? _fullCCCheckDeviation;
310 double FullCCCheckDeviation()
311 {
312 if (!_fullCCCheckDeviation.HasValue)
313 {
314 _fullCCCheckDeviation = GetCustomUserField<double>("AccessUser_FullCCCheckDeviation");
315 }
316
317 return _fullCCCheckDeviation.Value;
318 }
319
320 //bool HasReachedMinimumQuantity()
321 //{
322 // if (!EnableMinimumCCQuantity())
323 // {
324 // return true;
325 // }
326
327 // var orderlinesGroupByCode = GetLoop("OrderLines").GroupBy(o => o.GetString("Ecom:Product:Field.NavCompanyCode"))
328 // .Select(o => new {
329 // Flag = o.FirstOrDefault().GetString("Ecom:Product:Field.NavCompanyCode"),
330 // CCRate = o.Sum(f => f.GetInteger("Ecom:Order:OrderLine.Quantity") * f.GetDouble("CustomerSpecificProductInformation.CCRate"))
331 // });
332
333 // if (orderlinesGroupByCode.Count() == orderlinesGroupByCode.Where(o => o.CCRate >= MinimumCCQuantity(o.Flag)).Count())
334 // {
335 // return true;
336 // }
337
338 // return false;
339 //}
340
341 //bool HasPassedFullCCCheckDeviationCheck()
342 //{
343 // if (!EnableFullCCCheck())
344 // {
345 // return true;
346 // }
347
348 // var orderlinesGroupByCode = GetLoop("OrderLines").GroupBy(o => o.GetString("Ecom:Product:Field.NavCompanyCode"))
349 // .Select(o => new { CCRate = o.Sum(f => f.GetInteger("Ecom:Order:OrderLine.Quantity") * f.GetDouble("CustomerSpecificProductInformation.CCRate")) });
350
351 // if (orderlinesGroupByCode.Count() == orderlinesGroupByCode.Where(o => (o.CCRate % 1) == 0 || LessOrEqual((o.CCRate % 1), FullCCCheckDeviation()) || LessOrEqual(Math.Abs(1 - (o.CCRate % 1)), FullCCCheckDeviation())).Count())
352 // {
353 // return true;
354 // }
355
356 // return false;
357 //}
358
359 //AE: Workaround for comparing doubles
360 bool LessOrEqual(double d1, double d2)
361 {
362 return d1 < d2 || Math.Abs(d1 - d2) <= 0.0000001;
363 }
364
365 /*
366 bool DisableComments()
367 {
368 User user = User.get_Current(PagePermissionLevels.Frontend);
369
370 return GetCustomField<bool>(user, "AccessUser_EnableCommentOnLine");
371 }
372 */
373 //static T GetCustomOrderLineField<T>(OrderLine orderLine, string customSystemFieldName)
374 //{
375 // OrderLineFieldValue myFieldValue =
376 // orderLine.OrderLineFieldValues.FirstOrDefault(cfv => cfv.OrderLineFieldSystemName == customSystemFieldName);
377
378 // if (myFieldValue != null)
379 // {
380 // return (T)Convert.ChangeType(myFieldValue.Value, typeof(T));
381 // }
382
383 // // Return default(T) which means you'll return null
384 // return default(T);
385 //}
386
387 //static T GetCustomOrderLineField<T>(LoopItem orderLine, string customSystemFieldName)
388 //{
389 // var template =
390 // orderLine.GetLoop("Order.OrderLineFields").FirstOrDefault(o => o.GetString("Ecom:Order:OrderLine.OrderLineField.SystemName") == customSystemFieldName);
391
392 // if (template != null)
393 // {
394 // return (T)Convert.ChangeType(template.GetValue("Ecom:Order:OrderLine.OrderLineField.Value.Clean"), typeof(T));
395 // }
396
397 // // Return default(T) which means you'll return null
398 // return default(T);
399 //}
400
401 Dynamicweb.Security.UserManagement.User _user = null;
402 T GetCustomUserField<T>(string customSystemFieldName)
403 {
404 if (_user == null)
405 {
406 _user = Dynamicweb.Security.UserManagement.User.GetCurrentExtranetUser();
407 }
408
409 if (_user != null)
410 {
411 CustomFieldValue myFieldValue = _user.CustomFieldValues.FirstOrDefault(cfv => cfv.CustomField.SystemName == customSystemFieldName);
412
413 try
414 {
415 if (myFieldValue != null)
416 {
417 return (T)Convert.ChangeType(myFieldValue.Value, typeof(T));
418 }
419 }
420 catch (Exception)
421 {
422 return default(T);
423 }
424 }
425
426 // Return default(T) which means you'll return null
427 return default(T);
428 }
429
430
431 ICollection<Dynamicweb.Ecommerce.Orders.OrderLineField> SortOrderLineFields(ICollection<Dynamicweb.Ecommerce.Orders.OrderLineField> loop)
432 {
433 return loop
434 .OrderByDescending(o => o.SystemName == "OrderLineComment")
435 .ThenByDescending(o => o.SystemName == "OrderLineRetailPrice")
436 .ThenByDescending(o => o.SystemName == "OrderLineItemNumber")
437 .ThenByDescending(o => o.SystemName == "OrderLineEAN").ToList();
438 }
439
440 bool IsInCart(ProductViewModel product)
441 {
442 var cart = Dynamicweb.Ecommerce.Common.Context.Cart;
443 if (cart != null)
444 {
445 foreach (var ol in cart.OrderLines)
446 {
447 if (ol.ProductId == product.Id)
448 {
449 return true;
450 }
451 }
452 }
453 return false;
454 }
455
456 string GetProductInfoValue(ProductInformation productInfo, string key)
457 {
458 if (productInfo.Values != null)
459 {
460 object value;
461 if (productInfo.Values.TryGetValue(key, out value))
462 {
463 if (!string.IsNullOrEmpty(Converter.ToString(value)))
464 {
465 return Converter.ToString(value);
466 }
467 }
468 }
469 return string.Empty;
470 }
471
472 }
473
474
475 @* html helpers section *@
476
477
478 @helper renderToolTip()
479 {
480 var jsSuggestionStock = "<span class='js-suggestion-stock'></span>";
481 <div class="hide js-tooltip-content quantity-tooltip-content">
482 <h4 class="title">
483 @Translate("Smartpage:Product.PackageSizeCeiled", "Antallet vil blive opskrevet til") <span class="js-package-size-quantity"></span> <a href="#" data-toggle="tooltip" data-placement="top" class="js-package-size-single package-size-single" title='@Translate("Smartpage:Product.PackageSizeCeiled.singleProduct.Text", "Det ønskede antal vare stemmer ikke overens med kollistørrelsen")'><i class="glyphicon glyphicon-info-sign"></i></a>
484 </h4>
485 <button class="btn btn-xs btn-info js-package-size-cancel" data-toggle="clickover"><i class="glyphicon glyphicon-remove"></i></button>
486 <button class="btn btn-xs btn-primary js-package-size-ok" data-toggle="clickover"><i class="glyphicon glyphicon-ok"></i></button>
487 </div>
488
489 <div class="hide js-tooltip-smaller-quantity quantity-tooltip-content">
490 <h4 class="title">
491 @Translate("Smartpage:Popover.OutOfStockText.LessQuantity", "Varen blev ikke tilføjet til kurven, forsøg med et mindre antal")
492 </h4>
493 <button class="btn btn-xs btn-info js-close-out-of-stock" data-toggle="clickover"><i class="glyphicon glyphicon-ok"></i></button>
494 </div>
495
496 <div class="hide js-tooltip-stock-content quantity-tooltip-content">
497 <h4 class="title">
498 @Translate("Smartpage:Popover.OutOfStockText", "Varen blev ikke tilføjet til kurven, fordi vi har ikke flere på lager")
499 </h4>
500 <button class="btn btn-xs btn-info js-close-out-of-stock" data-toggle="clickover"><i class="glyphicon glyphicon-ok"></i></button>
501 </div>
502
503 <div class="hide js-tooltip-stock-suggestion quantity-tooltip-content">
504 <h4 class="title">
505 @Translate("Smartpage:Popover.OutOfStockText.Suggestion", String.Format("Vi har kun {0} på lager. Vil du ændre antal?", jsSuggestionStock))
506 </h4>
507 <button class="btn btn-xs btn-info js-cancel-out-of-stock" data-toggle="clickover"><i class="glyphicon glyphicon-remove"></i></button>
508 <button class="btn btn-xs btn-info js-accept-out-of-stock" data-toggle="clickover"><i class="glyphicon glyphicon-ok"></i></button>
509 </div>
510 }
511
512
513 @helper AddedToCart(ProductViewModel i, string cssClass)
514 {
515 var cart = Dynamicweb.Ecommerce.Common.Context.Cart;
516 string cssIsInCart = !IsInCart(i) ? "hide" : "";
517
518 <span class='label label-success js-in-cart in-cart @cssClass @cssIsInCart'><i class="glyphicon glyphicon-shopping-cart"></i> @Translate("Smartpage:AddedInCart", "added")</span>
519 }
520
521 @helper SingleAddedToCart(ProductViewModel product)
522 {
523 string cssIsInCart = !IsInCart(product) ? "hide" : "";
524 <span class='label label-success in-cart js-in-cart product @cssIsInCart'><i class="glyphicon glyphicon-shopping-cart"></i> @Translate("Smartpage:AddedInCart", "added")</span>
525 }
526
527 @helper SingleStockStatus(ProductViewModel product)
528 {
529 bool outOfStock = product.StockLevel <= 0;
530 bool isServiceProduct = Dynamicweb.Ecommerce.Services.Products.GetProductById(product.Id, product.VariantId, Dynamicweb.Ecommerce.Common.Context.LanguageID, false).Type == Dynamicweb.Ecommerce.Products.ProductType.Service;
531
532 <div class='stock-status single-product'>
533 @if (outOfStock && !isServiceProduct)
534 {
535 <span class="label label-danger js-out-of-stock">@Translate("Smartpage:OutOfStock", "Ikke på lager")</span>
536 }
537 </div>
538 }
539
540 @helper ListStockStatus(ProductViewModel i, string currentViewMode)
541 {
542 bool outOfStock = i.StockLevel <= 0;
543 bool isServiceProduct = Dynamicweb.Ecommerce.Services.Products.GetProductById(i.Id, i.VariantId, Dynamicweb.Ecommerce.Common.Context.LanguageID, false).Type == Dynamicweb.Ecommerce.Products.ProductType.Service;
544
545 <div class='stock-status @currentViewMode'>
546 @if (outOfStock && !isServiceProduct)
547 {
548 <span class="label label-danger js-out-of-stock">@Translate("Smartpage:OutOfStock", "Ikke på lager")</span>
549 }
550 @if (!isServiceProduct && !outOfStock) {
551 <span class='label label-success'>@i.StockLevel @Translate("GASA.LeftOnStock", "left on stock")</span>
552 }
553 </div>
554 }
555
556
557 @helper PricesWithVATStatus(string positionCSS) {
558 if (DisplayPricesInclVat())
559 {
560 <p class='vat-message text-muted text-center @positionCSS'>@Translate("Smartpage:PricesIncludeVAT.Message", "Alle priser er inkl. Moms")</p>
561 }
562 else
563 {
564 <p class='vat-message text-muted text-center @positionCSS'>@Translate("Smartpage:PricesDoNotIncludeVAT.Message", "Alle priser er ekskl. Moms")</p>
565 }
566 }
567
568 @helper RenderManufacturer(string manufacturerId, string manufacturerName, string manufacturerWebsiteUrl)
569 {
570 if (EnableManufacturerFiltering())
571 {
572 var name = manufacturerName + "/" + manufacturerId;
573 if (!string.IsNullOrEmpty(manufacturerWebsiteUrl))
574 {
575 <a class="manufacturer-info-link" href="@manufacturerWebsiteUrl" target="_blank">@name</a>
576 }
577 else
578 {
579 <span class="manufacturer-info">@name</span>
580 }
581 }
582 }
583 @inherits ViewModelTemplate<ProductListViewModel>
584 @using System.Web
585 @using Dynamicweb;
586 @using Dynamicweb.Rendering;
587 @using Dynamicweb.Ecommerce.ProductCatalog;
588
589 @helper RenderSearch()
590 {
591 @SnippetStart("NavigationGroups")
592
593 var originalLink = "/Default.aspx?ID=" + HttpContext.Current.Request["id"].ToString();
594
595 string groupId = System.Web.HttpContext.Current.Request["GroupId"];
596 string groupName = string.Empty;
597
598 if (!string.IsNullOrEmpty(groupId))
599 {
600 var group = Dynamicweb.Ecommerce.Services.ProductGroups.GetGroup(groupId);
601 if (group != null)
602 {
603 groupName = group.Name;
604 }
605 }
606
607 <button type="button" class="btn btn-default btn-square dropdown-toggle js-select-group-dropdown" id="js-search-filters" data-toggle="dropdown" aria-expanded="false" data-whole-site="false"><span class="js-text-label hidden-xs hidden-sm">@Translate("Smartpage:Search.Select.InCategory", "in") @groupName</span> <span class="caret"></span></button>
608 <ul class="dropdown-menu js-search-dropdown-menu" role="menu" id="js-search-filters">
609 <li><a class="js-search-group-choice" href='@originalLink' data-whole-site="true">@Translate("Smartpage:Search.WholeSite", "Whole site")</a></li>
610 <li><a class="js-search-group-choice" href='@("/Default.aspx?ID=" + Pageview.Page.ID + "&GroupId=" + groupId)' data-whole-site="false">@Translate("Smartpage:Search.Select.InCategory", "in") @groupName</a></li>
611 </ul>
612
613 @SnippetEnd("NavigationGroups")
614 }
615
616 @functions{
617 public class GoogleImpression
618 {
619 public string name { get; set; }
620 public string id { get; set; }
621 public string price { get; set; }
622 public string list { get; set; }
623 public string url { get; set; }
624 public string currency { get; set; }
625 public int position { get; set; }
626 public string brand { get; set; }
627 }
628 }
629
630 @inherits ViewModelTemplate<ProductListViewModel>
631 @using Dynamicweb;
632 @using Dynamicweb.Core;
633 @using Dynamicweb.Environment;
634 @using Dynamicweb.Rendering;
635 @using Dynamicweb.Ecommerce.ProductCatalog;
636 @using System.Linq;
637 @using Gasa.ProductInformation;
638 @using Gasa.PriceInformation;
639 @using Gasa.ProductInformation.Helpers;
640 @using Dynamicweb.Ecommerce.Prices;
641 @using Gasa.Calendar;
642
643 @helper RenderListView()
644 {
645
646 <form method="post" class="js-basket-add js-set-tabindex js-product-form-container" autocomplete="false" data-submit-url='@Pageview.Area.Item["JsonCart"]'>
647 <input type="hidden" name="CartCmd" value="addmulti" />
648 <input type="hidden" name="Spleadday-accepted" class="js-leadday-accepted" value="false" />
649 <input type="hidden" name="Spleadday-declined" class="js-leadday-declined" value="false" />
650 @{
651
652 int pageNum = Math.Max(Dynamicweb.Context.Current.Request.GetInt32("PageNum"), 1);
653 var isLoggedIn = Dynamicweb.Security.UserManagement.User.IsExtranetUserLoggedIn();
654 var defaultImage = !string.IsNullOrWhiteSpace(Converter.ToString(Pageview.Area.Item["DefaultImage"])) ? Converter.ToString(Pageview.Area.Item["DefaultImage"]) : "/Files/images/default-image.png";
655
656 var baseLoopCounter = Model.PageSize * (pageNum - 1);
657 int productLoopCounter = 0;
658
659 var productService = Dynamicweb.Ecommerce.Services.Products;
660 var helperService = new CustomProductFieldHelpers();
661 string currentPageLink = "/Default.aspx?ID=" + GetPageIdByNavigationTag("SpProducts");
662 string host = Converter.ToBoolean(Pageview.Area.Item["CDNActivate"]) ? Converter.ToString(Pageview.Area.Item["CDNUrl"]) : string.Empty;
663
664 CultureInfo culture = CultureInfo.CreateSpecificCulture("en-US");
665 }
666 <div class="clearfix"></div>
667 <div class="col-sm-12">
668
669 <div class="product-list list-group js-grid-group">
670
671 @foreach (var i in Model.Products)
672 {
673 productLoopCounter++;
674
675 var manufacturerName = i.Manufacturer.Name;
676 var manufacturerWebsiteUrl = i.Manufacturer.Web;
677 var manufacturerId = i.Manufacturer.Id;
678
679 var product = productService.GetProductById(i.Id, i.VariantId, Dynamicweb.Ecommerce.Common.Context.LanguageID, false);
680 var productInfo = new ProductInformation(product, Dynamicweb.Security.UserManagement.User.GetCurrentExtranetUser()?.CustomerNumber);
681 var priceInformation = new PriceInformation(product, productInfo);
682
683 string productLink = currentPageLink + "&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,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";
1869 }
1870 <a href="@productLink" class="js-product-title js-gtm-product" data-name="@HttpUtility.HtmlAttributeEncode(i.Name)" data-id="@HttpUtility.HtmlAttributeEncode(i.Id)">
1871 <img src="@preImage" data-src="@previewImageUrl" data-fallback-image-url="@fallBackImage" alt="@HttpUtility.HtmlAttributeEncode(i.Name)" class="img-responsive b-lazy" style="width: 15px; height: 15px; display:inline-block;border:1px solid #8ec13c;" />
1872 </a>
1873
1874 <a href="@productLink" class="js-product-title js-gtm-product" data-name="@HttpUtility.HtmlAttributeEncode(i.Name)" data-id="@HttpUtility.HtmlAttributeEncode(i.Id)">@i.Name</a>
1875
1876 @if (Converter.ToBoolean(helperService.GetFieldValue("NewProduct", i.ProductFields)))
1877 {
1878 <span class="label label-warning">@Translate("Smartpage:NewProduct", "NEW")</span>
1879 }
1880 @if (Converter.ToBoolean(helperService.GetFieldValue("Bestseller", i.ProductFields)))
1881 {
1882 <span class="label label-warning">@Translate("Smartpage:Bestseller", "BESTSELLER")</span>
1883 }
1884 @if (!string.IsNullOrEmpty(Converter.ToString(helperService.GetFieldValue("NavCompanyCode", i.ProductFields))))
1885 {
1886 var flagImgPath = "/Admin/Images/Flags/Small/flag_" + Converter.ToString(helperService.GetFieldValue("NavCompanyCode", i.ProductFields)) + ".png";
1887 <img src='@flagImgPath' alt='@Converter.ToString(helperService.GetFieldValue("NavCompanyCode", i.ProductFields))' title='@Converter.ToString(helperService.GetFieldValue("NavCompanyCode", i.ProductFields))' />
1888 }
1889
1890 </h2>
1891
1892 <div class="shortdescription">
1893 @AddedToCart(i, "standard")
1894 <p style="margin:0;">@i.ShortDescription</p>
1895 @ListStockStatus(i, "list")
1896 </div>
1897
1898 <div class="manufacturer-website hidden-sm hidden-xs">
1899 @RenderManufacturer(manufacturerId, manufacturerName, manufacturerWebsiteUrl) <br />
1900 </div>
1901 <div class="col-md-1 col-sm-5">
1902 @if (Converter.ToInt32(helperService.GetFieldValue("LeadDays", i.ProductFields)) > 0)
1903 {
1904 <div class="row">
1905 <div class="col-sm-12 col-md-12 col-lg-9 product-lead-days">
1906 <span class="label label-warning">@Translate("Smartpage:Ecom.LeadDaysMessage", "Lead days") @Converter.ToInt32(helperService.GetFieldValue("LeadDays", i.ProductFields))</span>
1907 </div>
1908 </div>
1909 }
1910 </div>
1911 <div class="potsize text-right hidden-sm hidden-xs ">
1912 @FormatDiameter(Converter.ToString(helperService.GetFieldValue("ProductPotSize", i.ProductFields)) + " cm ")
1913 </div>
1914 <div class="hidden-md hidden-lg">
1915 @FormatDiameter(Converter.ToString(helperService.GetFieldValue("ProductPotSize", i.ProductFields))) cm
1916 @RenderManufacturer(manufacturerId, manufacturerName, manufacturerWebsiteUrl) <br />
1917 </div>
1918 </div>
1919 <div class="clearfix visible-sm"></div>
1920 <div class="col-md-4 col-sm-6">
1921 @if (isLoggedIn)
1922 {
1923 <div class="product-price">
1924 <table class="table">
1925
1926 <tbody>
1927 <tr>
1928 <td>
1929 @Translate("Pcs", "Stk")
1930 </td>
1931 <td>
1932 1 ×
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