Error executing template "Designs/dcc/eCom/Product/dcc-b2b.cshtml"
System.NullReferenceException: Object reference not set to an instance of an object.
at System.Collections.Generic.Dictionary`2.Insert(TKey key, TValue value, Boolean add)
at Co3.DCC.Dw.Services.ProductService.GetConfigurationDetails(Product product, Boolean forceLoad) in C:\Data\Development\git\dcc-solution\Co3.DCC.Dynamicweb\Services\ProductService.cs:line 1145
at CompiledRazorTemplates.Dynamic.RazorEngine_561f52ef3b5b45ce97571ddd3088f6f4.Execute() in D:\dynamicweb.net\Solutions\foxwaysite.espresso4.dk\Files\Templates\Designs\dcc\eCom\Product\dcc-b2b.cshtml:line 1287
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.b__0(TextWriter writer)
at RazorEngine.Templating.RazorEngineServiceExtensions.WithWriter(Action`1 withWriter)
at Dynamicweb.Rendering.Template.RenderRazorTemplate()
1
2
3
4 @inherits RazorTemplateBase< RazorTemplateModel< Template > >
5 @inherits Co3.Espresso.Website.TemplateBases.Pages.PageBase
6 @using System
7 @using System.Collections.Generic
8 @using System.IO
9 @using Dynamicweb.Ecommerce.Prices;
10 @using Dynamicweb.Ecommerce.Products;
11 @using Co3.Espresso.Base.Extensions;
12 @using Co3.Espresso.Base.Models;
13 @using Co3.Espresso.Website.Models.FrontEnd
14 @using Co3.Espresso.Website.Services
15 @using Dynamicweb.Ecommerce.Common.eCom7
16 @using Dynamicweb.Rendering
17 @using System.Web
18 @using Dynamicweb.Admin.eComBackend
19 @using System.Linq;
20 @using System.Text.RegularExpressions;
21 @using System.Web.Razor.Parser.SyntaxTree
22 @using ProductService = Co3.Espresso.Website.Services.ProductService
23 @using Co3.DCC.Data.DAL.Models;
24 @using Co3.DCC.Dw.Models.FrontEnd
25 @using Dynamicweb.Ecommerce.Common
26 @using Dynamicweb.Ecommerce.Notifications
27 @using Dynamicweb.Frontend
28
29 @using System
30 @using System.Collections.Generic
31 @using System.Globalization
32 @using System.Linq
33 @using Co3.Espresso.Base.Extensions
34 @using Co3.Espresso.Website.Models.FrontEnd
35 @using Co3.Espresso.Website.Services
36 @using Dynamicweb.Ecommerce.CustomerCenter
37 @using Dynamicweb.Frontend
38 @using Dynamicweb.Rendering
39 @using Dynamicweb.Security.UserManagement
40 @using EcomContext = Dynamicweb.Ecommerce.Common.Context
41
42
43
44 @functions {
45
46 public static string GetStandardCollapseToggleTextExpand()
47 {
48 return "Se mere";
49 }
50
51 public static string GetStandardCollapseToggleTextCollapse()
52 {
53 return "Se mindre";
54 }
55
56 }
57
58
59 @helper ProductDescription(string sectionClasses = "e-section", bool sectionCollapse = false, string contentClasses = null, string heading = null, string content = null)
60 {
61 if ( string.IsNullOrEmpty( content ) == false )
62 {
63 ClassList headingClassList = new ClassList();
64 headingClassList.AddClasses( "col-12" );
65 ClassList contentClassList = new ClassList();
66 contentClassList.AddClasses( "col-12" );
67
68 @sectionStart( sectionClasses: sectionClasses, sectionCollapse: sectionCollapse, contentClasses: contentClasses )
69
70 if ( string.IsNullOrEmpty( heading ) == false )
71 {
72 <div class="@headingClassList">
73 <h2>@heading</h2>
74 </div>
75 }
76 <div class="@contentClassList">
77 @content
78 </div>
79
80 @sectionEnd()
81 }
82 }
83
84
85 @helper ProductVideo(string sectionClasses = "e-section", string contentClasses = null, string heading = null, string videoURL = null)
86 {
87 if ( string.IsNullOrEmpty( videoURL ) == false )
88 {
89 ClassList headingClassList = new ClassList();
90 headingClassList.AddClasses( "col-12" );
91 ClassList contentClassList = new ClassList();
92 contentClassList.AddClasses( "col-12" );
93
94
95 @sectionStart( sectionClasses: sectionClasses, contentClasses: contentClasses )
96
97 if ( string.IsNullOrEmpty( heading ) == false )
98 {
99 <div class="@headingClassList">
100 <h2>@heading</h2>
101 </div>
102 }
103
104 <div class="@contentClassList">
105 <div class="embed-responsive embed-responsive-16by9 mb-2">
106 <iframe class="embed-responsive-item" src="@videoURL" width="1080" height="608" frameborder="0" webkitallowfullscreen mozallowfullscreen allowfullscreen></iframe>
107 </div>
108 </div>
109 @sectionEnd()
110 }
111 }
112
113 @helper ProductRelatedProducts(string sectionClasses = "e-section", string contentClasses = null, string heading = null,
114 IEnumerable<RazorTemplateBase<RazorTemplateModel<Template>>.LoopItem> productLoop = null)
115 {
116 if ( productLoop != null && productLoop.Any() == true )
117 {
118 ClassList headingClassList = new ClassList();
119 headingClassList.AddClasses( "col-12" );
120 ClassList contentClassList = new ClassList();
121 contentClassList.AddClasses( "col-12" );
122
123 @sectionStart( sectionClasses: sectionClasses, contentClasses: contentClasses )
124
125 if ( string.IsNullOrEmpty( heading ) == false )
126 {
127 <div class="@headingClassList">
128 <h2 class="text-center">@heading</h2>
129 </div>
130 }
131
132
133 <div class="@contentClassList">
134 <div class="e-products mb-2">
135 <div class="row">
136 @{
137 string productlistItemClassList = ProductlistService.Instance.GetGridItemWidth( null ).ToResponsiveClasses();
138 }
139 @foreach ( RazorTemplateBase<RazorTemplateModel<Template>>.LoopItem product in productLoop )
140 {
141 @ProductlistItem( product, productlistItemClassList )
142 }
143 </div>
144 </div>
145 </div>
146
147 @sectionEnd()
148 }
149 }
150
151 @helper ProductlistItem(RazorTemplateBase<RazorTemplateModel<Template>>.LoopItem product, string productlistItemClassList = null)
152 {
153
154
155 if ( product != null )
156 {
157 dynamic productData = new
158 {
159 id = product.GetString( "Ecom:Product.ID" ),
160 url = ProductService.Instance.GetProductLink( product.GetString( "Ecom:Product.PrimaryOrFirstGroupID" ), product.GetString( "Ecom:Product.ID" ) ),
161 number = product.GetString( "Ecom:Product.Number" ),
162 name = product.GetString( "Ecom:Product.Name" ),
163 imageLarge = ImageService.Instance.GetImageURL( product.GetString( "Ecom:Product.ImageLarge.Clean" ), 240, 240, 5 ),
164 price = ProductService.Instance.GetPriceFormatted( product.GetDouble( "Ecom:Product.Price.Price" ) ),
165 descriptionShortExtra01 = product.GetString( "Ecom:Product:Field.DescriptionShortExtra01" ),
166 stock = new
167 {
168 id = product.GetString( "Ecom:Product:Stock.ID" ),
169 quantity = product.GetString( "Ecom:Product.Stock" ),
170 text = product.GetString( "Ecom:Product:Stock.Text" ),
171 delivery = product.GetString( "Ecom:Product:Stock.DeliveryText" )
172 }
173 };
174
175 <div class="@productlistItemClassList">
176 <div class="border-0 e-products-item js-e-products-item">
177 <div class="e-products-item-container">
178 <div class="e-products-item-image-container">
179 <a class="e-products-item-image-wrapper" href="@productData.url">
180 <img src="@productData.imageLarge" alt="" class="e-products-item-image">
181 </a>
182 </div>
183 <div class="e-products-item-text-container text-center">
184 <h3 class="e-products-item-name mb-0">
185 <a href="@productData.url">
186 @productData.name
187 </a>
188 </h3>
189 @if ( string.IsNullOrEmpty( productData.descriptionShortExtra01 ) == false )
190 {
191 <p class="e-products-item-text mb-0">
192 <a href="@productData.url">
193 @productData.descriptionShortExtra01
194 </a>
195 </p>
196 }
197 <p class="e-products-item-text mb-0">
198 <small class="e-products-item-price small text-muted">
199 <a href="@productData.url">
200 @productData.price
201 </a>
202 </small>
203 </p>
204 </div>
205 </div>
206 </div>
207 </div>
208 }
209 }
210
211
212 @helper sectionStart( string sectionClasses = "e-section", string contentClasses = null, bool sectionCollapse = false, string sectionId = null, string collapseToggleTextExpand = null, string collapseToggleTextCollapse = null, bool collapsetoggleHidden = false )
213 {
214 sectionId = string.IsNullOrEmpty( sectionId ) ? Guid.NewGuid().ToString( "N" ) : sectionId;
215 ClassList sectionClassList = new ClassList();
216 sectionClassList.AddClasses( sectionClasses );
217 ClassList contentClassList;
218
219 if ( contentClasses == null )
220 {
221 contentClassList = Co3.Espresso.Website.Services.PageService.Instance.GetResponsiveClassesFromPageItem( PageView.Current().Page.Item );
222 }
223 else
224 {
225 contentClassList = new ClassList();
226 contentClassList.AddClasses( contentClasses );
227 }
228
229 // TODO: Split collapse logic into separate helper function.
230 string collapseId = Guid.NewGuid().ToString( "N" );
231 ClassList collapseToggleClassList = new ClassList();
232 if ( sectionCollapse )
233 {
234 sectionClassList.AddClasses( "p-section-collapse js-p-section-collapse" );
235 collapseToggleClassList.AddClasses( contentClasses );
236 collapseToggleClassList.AddClasses( "p-section-collapse-toggle collapsed order-last text-center" );
237 contentClassList.AddClasses( "p-section-collapse-content collapse is-md" );
238 }
239
240 @:<section class="@sectionClassList" id="@sectionId">
241 @:<div class="container-fluid">
242 @:<div class="row">
243
244 // TODO: Split collapse logic into separate helper function.
245 if ( sectionCollapse )
246 {
247 <div class="@collapseToggleClassList" data-toggle="collapse" data-target="#@collapseId">
248 <button class="btn btn-primary p-section-collapse-toggle-btn" type="button">
249 <i class="material-icons p-section-collapse-toggle-icon">keyboard_arrow_down</i>
250 </button>
251 <small class="h4 p-section-collapse-toggle-text" data-expand-text="@( string.IsNullOrEmpty( collapseToggleTextExpand ) ? GetStandardCollapseToggleTextExpand() : collapseToggleTextExpand )" data-collapse-text="@( string.IsNullOrEmpty( collapseToggleTextCollapse ) ? GetStandardCollapseToggleTextCollapse() : collapseToggleTextCollapse )"></small>
252 </div>
253 }
254
255 @:<div class="@contentClassList" id="@collapseId">
256 @:<div class="row">
257 }
258
259 @helper sectionEnd()
260 {
261 @:</div>
262 @:</div>
263 @:</div>
264 @:</div>
265 @:</section>
266 }
267
268 @helper GetSvgFileData(string svgfile)
269 {
270 string rtnValue = svgfile;
271 if (!string.IsNullOrEmpty(svgfile))
272 {
273 string FilePath = svgfile;
274
275 if (System.IO.Path.GetExtension(FilePath) == ".svg")
276 {
277 System.Xml.XmlReaderSettings settings = new System.Xml.XmlReaderSettings();
278 settings.DtdProcessing = System.Xml.DtdProcessing.Ignore;
279 string svgFilePath = System.Web.HttpContext.Current.Server.MapPath(FilePath) ?? string.Empty;
280 if (System.IO.File.Exists(svgFilePath))
281 {
282 using (System.IO.StreamReader sr = new System.IO.StreamReader(svgFilePath))
283 {
284 using (System.Xml.XmlReader xr = System.Xml.XmlReader.Create(sr, settings))
285 {
286 bool done = false;
287 while (xr.Read() && !done)
288 {
289 if (xr.NodeType == System.Xml.XmlNodeType.Element && xr.Name == "svg")
290 {
291 rtnValue = xr.ReadOuterXml();
292 done = true;
293 }
294 }
295 }
296 }
297 }
298 }
299 }
300 @rtnValue;
301 }
302
303
304
305 @inherits Co3.Espresso.Website.TemplateBases.Pages.PageBase
306 @using System
307 @using System.Collections.Generic
308 @using System.Diagnostics
309 @using System.Linq
310 @using Co3.Espresso.Base.Extensions
311 @using Co3.Espresso.Website.Services
312 @using Co3.Espresso.Website.Models.FrontEnd
313 @using Dynamicweb.Frontend;
314 @using System.Text.RegularExpressions;
315 @using System.Web
316 @using Dynamicweb.Ecommerce.Common
317 @using Dynamicweb.Ecommerce.CustomerCenter
318 @using Dynamicweb.Security.UserManagement
319 @using Co3.DCC.Data.DAL.Models;
320 @using Dynamicweb.Ecommerce.Products
321 @using Co3.DCC.Dw.Models.FrontEnd
322 @using ProductService = Co3.Espresso.Website.Services.ProductService
323
324 @functions
325 {
326 public bool IsConfiguratorActive()
327 {
328 return true;
329 }
330
331 public List<dynamic> GetBomItems(LoopItem orderline)
332 {
333 List<dynamic> orderlineBOMItems = new List<dynamic>();
334 Product productObject = Co3.DCC.Dw.Services.ProductService.Instance.GetProductById(orderline.GetString("Ecom:Product.ID"));
335 ConfigurationDetails configurationDetails = new ConfigurationDetails();
336 if (productObject != null)
337 {
338 configurationDetails = Co3.DCC.Dw.Services.ProductService.Instance.GetConfigurationDetails(productObject);
339 }
340
341 int bomItemsSortCounter = 2;
342 int bomItemsSortCounterCustom = 0;
343
344 foreach (LoopItem bomitem in orderline.GetLoop("BOMItems"))
345 {
346
347 Dictionary<string, dynamic> bomOrderlineFields = new Dictionary<string, dynamic>();
348 if (bomitem.GetLoop("Order.OrderLineFields").Any())
349 {
350 foreach (LoopItem bomOrderlineField in bomitem.GetLoop("Order.OrderLineFields"))
351 {
352 bomOrderlineFields.Add(bomOrderlineField.GetString("Ecom:Order:OrderLine.OrderLineField.SystemName"), bomOrderlineField.GetString("Ecom:Order:OrderLine.OrderLineField.Value"));
353 }
354 }
355
356 string partName = bomitem.GetString("Ecom:Order:OrderLine.ProductName");
357
358 if (configurationDetails != null)
359 {
360 string bomPartNumber = bomitem.GetString("Ecom:Order:OrderLine.ProductNumber");
361 partName = configurationDetails.Items.ContainsKey(bomPartNumber) ? configurationDetails.Items[bomPartNumber].Description : bomitem.GetString("Ecom:Order:OrderLine.ProductName");
362 partName = ConfiguratorPartName(partName, true);
363 }
364
365 bool useCustomSort = false;
366 if (bomOrderlineFields.ContainsKey("SlotName"))
367 {
368 if (bomOrderlineFields["SlotName"].Equals(Co3.DCC.Data.Utilities.Constants.KEYBOARD_INTERNAL_CONFIGURATION_GROUP_ID))
369 {
370 useCustomSort = true;
371 bomItemsSortCounterCustom = 0;
372 }
373
374 if (bomOrderlineFields["SlotName"].Split('|')[0].Equals(Co3.DCC.Data.Utilities.Constants.MEMORY_CONFIGURATION_GROUP_ID))
375 {
376 useCustomSort = true;
377 bomItemsSortCounterCustom = 1;
378 }
379 }
380 Product bomProductObject = Co3.DCC.Dw.Services.ProductService.Instance.GetProductById(bomitem.GetString("Ecom:Product.ID"));
381 bool isBomItemDefault = true;
382
383 if (bomOrderlineFields.ContainsKey("IsDefault"))
384 {
385 Boolean.TryParse(bomOrderlineFields["IsDefault"], out isBomItemDefault);
386 }
387
388 if (bomitem.GetString("Ecom:Order:OrderLine.ProductID") == "PROD1")
389 {
390 isBomItemDefault = true;
391 }
392
393 orderlineBOMItems.Add(new
394 {
395 id = bomitem.GetString("Ecom:Order:OrderLine.ProductID"),
396 name = (bomOrderlineFields.ContainsKey("SlotName") && bomOrderlineFields["SlotName"] == "KEYBOARDS INTERNAL") ? Co3.DCC.Dw.Services.ProductService.Instance.GetCategoryValue(bomProductObject, "ItemAttributes", "Keyboard_Language") : partName,
397 number = bomitem.GetString("Ecom:Product.Number"),
398 isDefault = isBomItemDefault,
399 sort = useCustomSort ? bomItemsSortCounterCustom : bomItemsSortCounter,
400 price = Co3.DCC.Dw.Services.ProductService.Instance.GetPriceFormatted(bomitem.GetDouble("Ecom:Order:OrderLine.UnitPrice.PriceWithoutVAT.Value")),
401 priceClean = bomitem.GetDouble("Ecom:Order:OrderLine.UnitPrice.PriceWithoutVAT.Value"),
402 bomOrderlineFields = bomOrderlineFields
403 });
404 bomItemsSortCounter++;
405
406 }
407 return orderlineBOMItems;
408 }
409
410 public dynamic ObjProductListItemByDwProduct(Product product, User user = null, int productCounter = 0, int listId = 0)
411 {
412 bool isUserAuthenticated = user != null;
413 bool hasDirectSale = (bool) PageView.Current().Area.Item["HasDirectSales"];
414
415 IEnumerable<CustomerProductList> userFavoriteLists = Enumerable.Empty<CustomerProductList>();
416 if (user != null)
417 {
418 userFavoriteLists = CustomerProductList.GetAllProductLists(user.ID);
419 }
420 int cheapestPrice = 0;
421 int expensivePrice = 0;
422
423 string productId = product.Id;
424 Product productObject = product;
425 ProductPriceInfo ppi = Co3.DCC.Dw.Services.ProductService.Instance.GetProductPriceInfo(productObject);
426
427 string productLink = ProductService.Instance.GetProductLink(product.PrimaryGroupId, product.Id);
428
429 if (product.Active == false || product.IsActive == false)
430 {
431 productLink = SearchEngineFriendlyURLs.GetFriendlyUrl(Espresso.Area.Item.DiscontinuedProductDetailsUrl) + "?productid=" + productId;
432 }
433 else
434 {
435 productLink = SearchEngineFriendlyURLs.GetFriendlyUrl(productLink);
436 }
437
438 if (string.IsNullOrEmpty(productLink))
439 {
440 productLink = SearchEngineFriendlyURLs.GetFriendlyUrl(Espresso.Area.Item.FallbackDisplayPage) + "?productid=" + productId;
441 }
442
443 string condition = product.GetProductFieldValue<string>("Condition");
444 string conditionClass = "dcc-condition-" + Regex.Replace(condition, @"\s", String.Empty).ToLower().Trim().Replace(".", "");
445 string mainCategory = product.GetProductFieldValue<string>("InventoryPostingGroup");
446 string manufacturerCode = product.GetProductFieldValue<string>("GlobalDimension2Code");
447 bool stockCheck = product.Stock > 0 ? true : false;
448 bool isOutlet = productObject.GetProductFieldValue<bool>("Outlet");
449 bool isCallForPrice = productObject.GetProductFieldValue<bool>("WebCallForPrice");
450 bool isConfigurable = productObject.GetProductFieldValue<bool>("IsConfigurable");
451 string stockNumber;
452
453 IEnumerable<ProductRelatedGroup> relatedGroups = productObject.RelatedGroups;
454
455 ProductCollection warrantyRelatedProductCollection = new ProductCollection();
456
457 if (relatedGroups.FirstOrDefault(rg => rg.GroupId == "WARRANTY") != null)
458 {
459 warrantyRelatedProductCollection = relatedGroups.FirstOrDefault(rg => rg.GroupId == "WARRANTY").Products;
460 }
461
462 List<dynamic> warrantyRelatedProducts = new List<dynamic>();
463
464 foreach (Product relatedWarrentyProduct in warrantyRelatedProductCollection)
465 {
466 if (relatedWarrentyProduct.IsActive && relatedWarrentyProduct.Price.Price > 0)
467 {
468 warrantyRelatedProducts.Add(new
469 {
470 id = relatedWarrentyProduct.Id,
471 name = relatedWarrentyProduct.Name,
472 number = relatedWarrentyProduct.Number,
473 intPrice = relatedWarrentyProduct.Price.PriceWithoutVAT,
474 strPrice = relatedWarrentyProduct.Price.PriceWithoutVAT.ToString("N2"),
475 shortDescription = relatedWarrentyProduct.ShortDescription
476 });
477 }
478 }
479
480 if (warrantyRelatedProductCollection.Any())
481 {
482 isConfigurable = true;
483 }
484
485 if (manufacturerCode == "AMP" || manufacturerCode == "APC" || manufacturerCode == "TYCO" || manufacturerCode == "UPS")
486 {
487 stockNumber = product.Stock.ToString();
488 }
489 else
490 {
491 stockNumber = product.Stock.ToString();
492 }
493
494 bool noImage = string.IsNullOrEmpty(product.ImageLarge) ? true : false;
495
496 string imageCheck = "";
497
498 if (noImage)
499 {
500 imageCheck = "/Files/Templates/Designs/dcc/_assets/img/dcc-noimage.svg";
501 }
502 else
503 {
504 imageCheck = ImageService.Instance.GetImageURL(product.ImageLarge, 400, 400, 5);
505 }
506
507 List<string> productDescription = Co3.DCC.Dw.Services.ProductService.Instance.GetProductItemDescription(productObject);
508
509
510 List<dynamic> categoryFieldsNotebook = new List<dynamic>();
511 List<dynamic> categoryFieldsPc = new List<dynamic>();
512 List<dynamic> categoryFieldsServer = new List<dynamic>();
513 List<dynamic> categoryFieldsStorage = new List<dynamic>();
514 List<dynamic> categoryFieldsMonitor = new List<dynamic>();
515 List<dynamic> categoryFieldsOther = new List<dynamic>();
516
517 if (Espresso.Area.Item.MainCategoryFieldsNotebook != null)
518 {
519 List<DescriptionField> customCategoryFieldsNotebook = Co3.DCC.Dw.Services.ProductService.GetProductItemDescriptionByItemRelations(productObject, Espresso.Area.Item.MainCategoryFieldsNotebook);
520
521 foreach (DescriptionField descriptionField in customCategoryFieldsNotebook)
522 {
523 categoryFieldsNotebook.Add(new
524 {
525 value = descriptionField.Value.Replace("U0022", "\""),
526 header = Translate(String.Format("mainCategory_FieldLabel_{0}", descriptionField.Header), descriptionField.Header),
527 anchor = isConfigurable ? descriptionField.ConfigurationAnchor : string.Empty
528 });
529 }
530 }
531 if (Espresso.Area.Item.MainCategoryFieldsPC != null)
532 {
533 List<DescriptionField> customCategoryFieldsPc = Co3.DCC.Dw.Services.ProductService.GetProductItemDescriptionByItemRelations(productObject, Espresso.Area.Item.MainCategoryFieldsPC);
534 foreach (DescriptionField descriptionField in customCategoryFieldsPc)
535 {
536 categoryFieldsPc.Add(new
537 {
538 value = descriptionField.Value.Replace("U0022", "\""),
539 header = Translate(String.Format("mainCategory_FieldLabel_{0}", descriptionField.Header), descriptionField.Header),
540 anchor = isConfigurable ? descriptionField.ConfigurationAnchor : string.Empty
541 });
542 }
543 }
544 if (Espresso.Area.Item.MainCategoryFieldsServer != null)
545 {
546 List<DescriptionField> customCategoryFieldsServer = Co3.DCC.Dw.Services.ProductService.GetProductItemDescriptionByItemRelations(productObject, Espresso.Area.Item.MainCategoryFieldsServer);
547 foreach (DescriptionField descriptionField in customCategoryFieldsServer)
548 {
549 categoryFieldsServer.Add(new
550 {
551 value = descriptionField.Value.Replace("U0022", "\""),
552 header = Translate(String.Format("mainCategory_FieldLabel_{0}", descriptionField.Header), descriptionField.Header),
553 anchor = isConfigurable ? descriptionField.ConfigurationAnchor : string.Empty
554 });
555 }
556 }
557 if (Espresso.Area.Item.MainCategoryFieldsStorage != null)
558 {
559 List<DescriptionField> customCategoryFieldsStorage = Co3.DCC.Dw.Services.ProductService.GetProductItemDescriptionByItemRelations(productObject, Espresso.Area.Item.MainCategoryFieldsStorage);
560 foreach (DescriptionField descriptionField in customCategoryFieldsStorage)
561 {
562 categoryFieldsStorage.Add(new
563 {
564 value = descriptionField.Value.Replace("U0022", "\""),
565 header = Translate(String.Format("mainCategory_FieldLabel_{0}", descriptionField.Header), descriptionField.Header),
566 anchor = isConfigurable ? descriptionField.ConfigurationAnchor : string.Empty
567 });
568 }
569 }
570 if (Espresso.Area.Item.MainCategoryFieldsMonitor != null)
571 {
572 List<DescriptionField> customCategoryFieldsMonitor = Co3.DCC.Dw.Services.ProductService.GetProductItemDescriptionByItemRelations(productObject, Espresso.Area.Item.MainCategoryFieldsMonitor);
573 foreach (DescriptionField descriptionField in customCategoryFieldsMonitor)
574 {
575 categoryFieldsMonitor.Add(new
576 {
577 value = descriptionField.Value.Replace("U0022", "\""),
578 header = Translate(String.Format("mainCategory_FieldLabel_{0}", descriptionField.Header), descriptionField.Header),
579 anchor = isConfigurable ? descriptionField.ConfigurationAnchor : string.Empty
580 });
581 }
582 }
583 if (Espresso.Area.Item.MainCategoryFieldsOther != null)
584 {
585 List<DescriptionField> customCategoryFieldsOther = Co3.DCC.Dw.Services.ProductService.GetProductItemDescriptionByItemRelations(productObject, Espresso.Area.Item.MainCategoryFieldsOther);
586 foreach (DescriptionField descriptionField in customCategoryFieldsOther)
587 {
588 categoryFieldsOther.Add(new
589 {
590 value = descriptionField.Value.Replace("U0022", "\""),
591 header = Translate(String.Format("mainCategory_FieldLabel_{0}", descriptionField.Header), descriptionField.Header),
592 anchor = isConfigurable ? descriptionField.ConfigurationAnchor : string.Empty
593 });
594 }
595 }
596 if (product.Price.Price > expensivePrice)
597 {
598 expensivePrice = (int) product.Price.Price;
599 }
600 if (cheapestPrice != 0)
601 {
602 if (product.Price.Price < cheapestPrice)
603 {
604 cheapestPrice = (int) product.Price.Price;
605 }
606 }
607 else
608 {
609 cheapestPrice = (int) product.Price.Price;
610 }
611
612 List<dynamic> favoriteLists = new List<dynamic>();
613 if (user != null && userFavoriteLists != null)
614 {
615 foreach (CustomerProductList userFavoriteList in userFavoriteLists)
616 {
617 /*
618 * listId = listId == 0 ? userFavoriteList.ID : listId;
619 bool isProductInThisList = CustomerProductListProduct.IsProductInFavorites(productObject, listId);
620 */
621 bool isProductInThisList = false;
622 string addUrl = string.Format("{0}{4}CCAddToMyLists={1}&CCAddToListVariantID=&CCAddToListLanguageID={2}&CCAddToListID={3}&CCListType=List", productLink, product.Id, Dynamicweb.Ecommerce.Common.Context.Language.LanguageId, userFavoriteList.ID, (productLink.ToLower().Contains("default") == true ? "&" : "?"));
623 string removeUrl = string.Format("{0}{4}CCRemoveFromMyLists={1}&CCRemoveFromListVariantID=&CCRemoveFromListLanguageID={2}&CCListType=List&ListID={3}", productLink, product.Id, Dynamicweb.Ecommerce.Common.Context.Language.LanguageId, userFavoriteList.ID, (productLink.ToLower().Contains("default") == true ? "&" : "?"));
624
625 if (product.Active == false || product.IsActive == false)
626 {
627 addUrl = string.Format("{0}{4}CCAddToMyLists={1}&CCAddToListVariantID=&CCAddToListLanguageID={2}&CCAddToListID={3}&CCListType=List", HttpContext.Current.Request.Url, product.Id,
628 Dynamicweb.Ecommerce.Common.Context.Language.LanguageId,
629 userFavoriteList.ID,
630 "&" )
631 ;
632 removeUrl = string.Format("{0}{4}CCRemoveFromMyLists={1}&CCRemoveFromListVariantID=&CCRemoveFromListLanguageID={2}&CCListType=List&ListID={3}", HttpContext.Current.Request.Url, product.Id, Dynamicweb.Ecommerce.Common.Context.Language.LanguageId, userFavoriteList.ID, "&");
633 }
634 if (userFavoriteList.Products.Any(p => p.ProductId.Equals(product.Id)))
635 {
636 isProductInThisList = true;
637 listId = listId == 0 ? userFavoriteList.ID : listId;
638 }
639 favoriteLists.Add(new
640 {
641 id = userFavoriteList.ID,
642 name = userFavoriteList.Name,
643 isProductInThisList = isProductInThisList,
644 urlAdd = addUrl,
645 urlRemove = removeUrl
646 });
647 }
648 }
649
650 string stockETA = string.Empty;
651
652 if (Co3.DCC.Dw.Services.ProductService.Instance.IsNextPurchaseDateSet(productObject) == true)
653 {
654 double stockAmount = Co3.DCC.Dw.Services.ProductService.Instance.GetQtyAvailableOnStockPlus(productObject);
655 string stockAmountText = stockAmount.ToString();
656 string stockEtaDate = Co3.DCC.Dw.Services.ProductService.Instance.GetNextPurchaseDateFormatted(productObject);
657
658 if (stockAmount > 0)
659 {
660 stockETA = string.Format("{0} {1} {2}", stockAmountText, Translate("eCom Product - ETA - Expected in stock - Text", "forventet på lager"), stockEtaDate);
661 }
662
663 }
664
665 string remoteStockTranslationKey = string.Format("eCom Product - Remote Stock - Status - {0}", product.GetProductFieldValue<string>("RemoteStock"));
666
667
668 dynamic objProduct = new
669 {
670 id = product.Id,
671 autoId = productObject.AutoId,
672 index = productCounter,
673 url = productLink,
674 number = product.Number,
675 name = product.Name,
676 imageLarge = imageCheck,
677 price = Co3.DCC.Dw.Services.ProductService.Instance.GetPriceFormatted(product.Price.PriceWithoutVAT, (ppi != null && ppi.BeforePrice != null) ? ppi.BeforePrice.PriceAmount : 0, !isUserAuthenticated),
678 priceClean = product.Price.PriceWithoutVAT,
679 isBeforePrice = (ppi != null && ppi.BeforePrice != null) ? true : false,
680 beforePrice = (ppi != null && ppi.BeforePrice != null) ?
681 Co3.DCC.Dw.Services.ProductService.Instance.GetPriceFormatted(ppi.BeforePrice.PriceAmount) :
682 "",
683 isActive = product.Active || product.IsActive,
684 isCampaign = (ppi != null) ? ppi.IsCampaignPrice : false,
685 isOutlet = isOutlet,
686 isCallForPrice = isCallForPrice,
687 isNoPrice = (ppi != null && ppi.Price != null && ppi.Price.PriceAmount == 0),
688 isConfigurable = isConfigurable,
689 isConfiguratorActive = IsConfiguratorActive(),
690 isInCart = Dynamicweb.Ecommerce.Common.Context.Cart != null ? Dynamicweb.Ecommerce.Common.Context.Cart.ProductOrderLines.Any(ol =>ol.ProductId == product.Id) : false,
691 descriptionShortExtra01 = product.GetProductFieldValue<string>("DescriptionShortExtra01"),
692 stock = stockNumber,
693 a_stock = productObject.Stock,
694 stockCheck = stockCheck,
695 stockState = product.get_StockStatus(product.Language.LanguageId).ExpectedDeliveryText,
696 stockLabel = product.get_StockStatus(product.Language.LanguageId).Text,
697 remoteStock = string.IsNullOrEmpty(product.GetProductFieldValue<string>("RemoteStock")) == false ? Translate(remoteStockTranslationKey,product.GetProductFieldValue<string>("RemoteStock") ) : string.Empty,
698 stockETA = stockETA,
699 productDescription = productDescription,
700 categoryFieldsNotebook = categoryFieldsNotebook,
701 categoryFieldsPc = categoryFieldsPc,
702 categoryFieldsServer = categoryFieldsServer,
703 categoryFieldsStorage = categoryFieldsStorage,
704 categoryFieldsMonitor = categoryFieldsMonitor,
705 categoryFieldsOther = categoryFieldsOther,
706 simpleDesc = Co3.DCC.Dw.Services.ProductService.Instance.GetCategoryValue(productObject, "PIMItemDescription", "Description"),
707 noImage = noImage,
708 condition = Translate(String.Format("Product_Refurbished_Condition_{0}", condition), condition),
709 conditionClass = conditionClass,
710 mainCategory = mainCategory,
711 favoriteLists = favoriteLists,
712 isUserAuthenticated = isUserAuthenticated,
713 listId = listId,
714 hasDirectSale = hasDirectSale,
715 productWarning = productObject.GetProductFieldValue<string>("ProductWarning")
716 };
717 if (productObject != null)
718 {
719 return objProduct;
720 }
721 return null;
722 }
723
724
725 public dynamic ObjProductListItem( LoopItem product, User user = null, int productCounter = 0, int listId = 0 )
726 {
727 bool isUserAuthenticated = user != null;
728
729 bool hasDirectSale = (bool)PageView.Current().Area.Item["HasDirectSales"];
730
731 IEnumerable< CustomerProductList > userFavoriteLists = Enumerable.Empty< CustomerProductList >();
732 if ( user != null )
733 {
734 userFavoriteLists = CustomerProductList.GetAllProductLists( user.ID );
735 }
736 int cheapestPrice = 0;
737 int expensivePrice = 0;
738
739 string productId = product.GetString( "Ecom:Product.ID" );
740 Dynamicweb.Ecommerce.Products.Product productObject = Co3.DCC.Dw.Services.ProductService.Instance.GetProductById( productId );
741 ProductPriceInfo ppi = Co3.DCC.Dw.Services.ProductService.Instance.GetProductPriceInfo( productObject );
742
743 string productLink = ProductService.Instance.GetProductLink( product.GetString( "Ecom:Product.PrimaryOrFirstGroupID" ), product.GetString( "Ecom:Product.ID" ) );
744
745
746
747 if ( product.GetBoolean( "Ecom:Product.IsActive" ) == false )
748 {
749 productLink = SearchEngineFriendlyURLs.GetFriendlyUrl( Espresso.Area.Item.DiscontinuedProductDetailsUrl ) + "?productid="+ productId;
750 }
751 else
752 {
753 productLink = SearchEngineFriendlyURLs.GetFriendlyUrl( productLink );
754 }
755
756 if ( string.IsNullOrEmpty( productLink ) )
757 {
758 productLink = SearchEngineFriendlyURLs.GetFriendlyUrl( Espresso.Area.Item.FallbackDisplayPage ) + "?productid="+ productId;
759 }
760
761 string condition = product.GetString( "Ecom:Product:Field.Condition.Value.Clean" );
762 string conditionClass = "dcc-condition-" + Regex.Replace( condition, @"\s", String.Empty ).ToLower().Trim().Replace( ".", "" );
763 string mainCategory = product.GetString( "Ecom:Product:Field.InventoryPostingGroup.Value.Clean" );
764 string manufacturerCode = product.GetString( "Ecom:Product:Field.GlobalDimension2Code.Value.Clean" );
765 bool stockCheck = product.GetInteger( "Ecom:Product.Stock" ) > 0 ? true : false;
766 bool isOutlet = productObject.GetProductFieldValue< bool >( "Outlet" );
767 bool isCallForPrice = productObject.GetProductFieldValue< bool >( "WebCallForPrice" );
768 bool isConfigurable = productObject.GetProductFieldValue< bool >( "IsConfigurable" );
769 string stockNumber;
770
771 IEnumerable<ProductRelatedGroup> relatedGroups = productObject.RelatedGroups;
772
773 ProductCollection warrantyRelatedProductCollection = new ProductCollection();
774
775 if ( relatedGroups.FirstOrDefault( rg => rg.GroupId == "WARRANTY" ) != null )
776 {
777 warrantyRelatedProductCollection = relatedGroups.FirstOrDefault( rg => rg.GroupId == "WARRANTY" ).Products;
778 }
779
780 List<dynamic> warrantyRelatedProducts = new List<dynamic>();
781
782 foreach ( Product relatedWarrentyProduct in warrantyRelatedProductCollection )
783 {
784 if ( relatedWarrentyProduct.IsActive && relatedWarrentyProduct.Price.Price > 0 )
785 {
786 warrantyRelatedProducts.Add( new
787 {
788 id = relatedWarrentyProduct.Id,
789 name = relatedWarrentyProduct.Name,
790 number = relatedWarrentyProduct.Number,
791 intPrice = relatedWarrentyProduct.Price.PriceWithoutVAT,
792 strPrice = relatedWarrentyProduct.Price.PriceWithoutVAT.ToString( "N2" ),
793 shortDescription = relatedWarrentyProduct.ShortDescription
794 } );
795 }
796 }
797
798 if (warrantyRelatedProductCollection.Any())
799 {
800 isConfigurable = true;
801 }
802
803 if ( manufacturerCode == "AMP" || manufacturerCode == "APC" || manufacturerCode == "TYCO" || manufacturerCode == "UPS" )
804 {
805 stockNumber = product.GetDouble( "Ecom:Product.Stock" ).ToString();
806 }
807 else
808 {
809 stockNumber = product.GetDouble( "Ecom:Product.Stock" ).ToString();
810 }
811
812 bool noImage = string.IsNullOrEmpty( product.GetString( "Ecom:Product.ImageLarge.Clean" ) ) ? true : false;
813
814 string imageCheck = "";
815
816 if ( noImage )
817 {
818 imageCheck = "/Files/Templates/Designs/dcc/_assets/img/dcc-noimage.svg";
819 }
820 else
821 {
822 imageCheck = ImageService.Instance.GetImageURL( product.GetString( "Ecom:Product.ImageLarge.Clean" ), 400, 400, 5 );
823 }
824
825
826 List< string > productDescription = Co3.DCC.Dw.Services.ProductService.Instance.GetProductItemDescription( productObject );
827
828
829 List< dynamic > categoryFieldsNotebook = new List< dynamic >();
830 List< dynamic > categoryFieldsPc = new List< dynamic >();
831 List< dynamic > categoryFieldsServer = new List< dynamic >();
832 List< dynamic > categoryFieldsStorage = new List< dynamic >();
833 List< dynamic > categoryFieldsMonitor = new List< dynamic >();
834 List< dynamic > categoryFieldsOther = new List< dynamic >();
835
836 if ( Espresso.Area.Item.MainCategoryFieldsNotebook != null )
837 {
838 List< DescriptionField > customCategoryFieldsNotebook = Co3.DCC.Dw.Services.ProductService.GetProductItemDescriptionByItemRelations( productObject, Espresso.Area.Item.MainCategoryFieldsNotebook );
839
840 foreach ( DescriptionField descriptionField in customCategoryFieldsNotebook )
841 {
842 categoryFieldsNotebook.Add( new
843 {
844 value = descriptionField.Value.Replace( "U0022", "\"" ),
845 header = Translate( String.Format( "mainCategory_FieldLabel_{0}", descriptionField.Header ), descriptionField.Header ),
846 anchor = isConfigurable ? descriptionField.ConfigurationAnchor : string.Empty
847 } );
848 }
849 }
850 if ( Espresso.Area.Item.MainCategoryFieldsPC != null )
851 {
852 List< DescriptionField > customCategoryFieldsPc = Co3.DCC.Dw.Services.ProductService.GetProductItemDescriptionByItemRelations( productObject, Espresso.Area.Item.MainCategoryFieldsPC );
853 foreach ( DescriptionField descriptionField in customCategoryFieldsPc )
854 {
855 categoryFieldsPc.Add( new
856 {
857 value = descriptionField.Value.Replace( "U0022", "\"" ),
858 header = Translate( String.Format( "mainCategory_FieldLabel_{0}", descriptionField.Header ), descriptionField.Header ),
859 anchor = isConfigurable ? descriptionField.ConfigurationAnchor : string.Empty
860 } );
861 }
862 }
863 if ( Espresso.Area.Item.MainCategoryFieldsServer != null )
864 {
865 List< DescriptionField > customCategoryFieldsServer = Co3.DCC.Dw.Services.ProductService.GetProductItemDescriptionByItemRelations( productObject, Espresso.Area.Item.MainCategoryFieldsServer );
866 foreach ( DescriptionField descriptionField in customCategoryFieldsServer )
867 {
868 categoryFieldsServer.Add( new
869 {
870 value = descriptionField.Value.Replace( "U0022", "\"" ),
871 header = Translate( String.Format( "mainCategory_FieldLabel_{0}", descriptionField.Header ), descriptionField.Header ),
872 anchor = isConfigurable ? descriptionField.ConfigurationAnchor : string.Empty
873 } );
874 }
875 }
876 if ( Espresso.Area.Item.MainCategoryFieldsStorage != null )
877 {
878 List< DescriptionField > customCategoryFieldsStorage = Co3.DCC.Dw.Services.ProductService.GetProductItemDescriptionByItemRelations( productObject, Espresso.Area.Item.MainCategoryFieldsStorage );
879 foreach ( DescriptionField descriptionField in customCategoryFieldsStorage )
880 {
881 categoryFieldsStorage.Add( new
882 {
883 value = descriptionField.Value.Replace( "U0022", "\"" ),
884 header = Translate( String.Format( "mainCategory_FieldLabel_{0}", descriptionField.Header ), descriptionField.Header ),
885 anchor = isConfigurable ? descriptionField.ConfigurationAnchor : string.Empty
886 } );
887 }
888 }
889 if ( Espresso.Area.Item.MainCategoryFieldsMonitor != null )
890 {
891 List< DescriptionField > customCategoryFieldsMonitor = Co3.DCC.Dw.Services.ProductService.GetProductItemDescriptionByItemRelations( productObject, Espresso.Area.Item.MainCategoryFieldsMonitor );
892 foreach ( DescriptionField descriptionField in customCategoryFieldsMonitor )
893 {
894 categoryFieldsMonitor.Add( new
895 {
896 value = descriptionField.Value.Replace( "U0022", "\"" ),
897 header = Translate( String.Format( "mainCategory_FieldLabel_{0}", descriptionField.Header ), descriptionField.Header ),
898 anchor = isConfigurable ? descriptionField.ConfigurationAnchor : string.Empty
899 } );
900 }
901 }
902 if ( Espresso.Area.Item.MainCategoryFieldsOther != null )
903 {
904 List< DescriptionField > customCategoryFieldsOther = Co3.DCC.Dw.Services.ProductService.GetProductItemDescriptionByItemRelations( productObject, Espresso.Area.Item.MainCategoryFieldsOther );
905 foreach ( DescriptionField descriptionField in customCategoryFieldsOther )
906 {
907 categoryFieldsOther.Add( new
908 {
909 value = descriptionField.Value.Replace( "U0022", "\"" ),
910 header = Translate( String.Format( "mainCategory_FieldLabel_{0}", descriptionField.Header ), descriptionField.Header ),
911 anchor = isConfigurable ? descriptionField.ConfigurationAnchor : string.Empty
912 } );
913 }
914 }
915
916
917 if ( product.GetInteger( "Ecom:Product.Price.Price" ) > expensivePrice )
918 {
919 expensivePrice = product.GetInteger( "Ecom:Product.Price.Price" );
920 }
921 if ( cheapestPrice != 0 )
922 {
923 if ( product.GetInteger( "Ecom:Product.Price.Price" ) < cheapestPrice )
924 {
925 cheapestPrice = product.GetInteger( "Ecom:Product.Price.Price" );
926 }
927 }
928 else
929 {
930 cheapestPrice = product.GetInteger( "Ecom:Product.Price.Price" );
931 }
932
933 List< dynamic > favoriteLists = new List< dynamic >();
934 if ( user != null && userFavoriteLists != null )
935 {
936 foreach ( CustomerProductList userFavoriteList in userFavoriteLists )
937 {
938 /*
939 * listId = listId == 0 ? userFavoriteList.ID : listId;
940 bool isProductInThisList = CustomerProductListProduct.IsProductInFavorites(productObject, listId);
941 */
942 bool isProductInThisList = false;
943 string addUrl = string.Format( "{0}{4}CCAddToMyLists={1}&CCAddToListVariantID=&CCAddToListLanguageID={2}&CCAddToListID={3}&CCListType=List", productLink, product.GetString( "Ecom:Product.ID" ), Dynamicweb.Ecommerce.Common.Context.Language.LanguageId, userFavoriteList.ID, ( productLink.ToLower().Contains( "default" ) == true ? "&" : "?" ) );
944 string removeUrl = string.Format( "{0}{4}CCRemoveFromMyLists={1}&CCRemoveFromListVariantID=&CCRemoveFromListLanguageID={2}&CCListType=List&ListID={3}", productLink, product.GetString( "Ecom:Product.ID" ), Dynamicweb.Ecommerce.Common.Context.Language.LanguageId, userFavoriteList.ID, ( productLink.ToLower().Contains( "default" ) == true ? "&" : "?" ) );
945
946 if(product.GetBoolean( "Ecom:Product.IsActive" ) == false)
947 {
948 addUrl = string.Format( "{0}{4}CCAddToMyLists={1}&CCAddToListVariantID=&CCAddToListLanguageID={2}&CCAddToListID={3}&CCListType=List", HttpContext.Current.Request.Url, product.GetString( "Ecom:Product.ID" ), Dynamicweb.Ecommerce.Common.Context.Language.LanguageId, userFavoriteList.ID, "&" );
949 removeUrl = string.Format( "{0}{4}CCRemoveFromMyLists={1}&CCRemoveFromListVariantID=&CCRemoveFromListLanguageID={2}&CCListType=List&ListID={3}", HttpContext.Current.Request.Url, product.GetString( "Ecom:Product.ID" ), Dynamicweb.Ecommerce.Common.Context.Language.LanguageId, userFavoriteList.ID, "&" );
950 }
951 if ( userFavoriteList.Products.Any( p => p.ProductId.Equals( product.GetString( "Ecom:Product.ID" ) ) ) )
952 {
953 isProductInThisList = true;
954 listId = listId == 0 ? userFavoriteList.ID : listId;
955 }
956 favoriteLists.Add( new
957 {
958 id = userFavoriteList.ID,
959 name = userFavoriteList.Name,
960 isProductInThisList = isProductInThisList,
961 urlAdd = addUrl,
962 urlRemove = removeUrl
963 } );
964 }
965 }
966
967 string stockETA = string.Empty;
968
969 if ( Co3.DCC.Dw.Services.ProductService.Instance.IsNextPurchaseDateSet( productObject ) == true )
970 {
971 double stockAmount = Co3.DCC.Dw.Services.ProductService.Instance.GetQtyAvailableOnStockPlus( productObject );
972 string stockAmountText = stockAmount.ToString();
973 string stockEtaDate = Co3.DCC.Dw.Services.ProductService.Instance.GetNextPurchaseDateFormatted( productObject );
974
975 if ( stockAmount > 0 )
976 {
977 stockETA = string.Format( "{0} {1} {2}", stockAmountText, Translate( "eCom Product - ETA - Expected in stock - Text", "forventet på lager" ), stockEtaDate );
978 }
979
980
981 }
982
983 string remoteStockTranslationKey = string.Format("eCom Product - Remote Stock - Status - {0}", product.GetString("Ecom:Product:Field.RemoteStock"));
984
985
986 dynamic Product = new
987 {
988 id = product.GetString( "Ecom:Product.ID" ),
989 autoId = productObject.AutoId,
990 index = productCounter,
991 url = productLink,
992 number = product.GetString( "Ecom:Product.Number" ),
993 name = product.GetString( "Ecom:Product.Name" ),
994 imageLarge = imageCheck,
995 price = Co3.DCC.Dw.Services.ProductService.Instance.GetPriceFormatted( product.GetDouble( "Ecom:Product.Price.PriceWithoutVAT.Value" ), ( ppi != null && ppi.BeforePrice != null ) ? ppi.BeforePrice.PriceAmount : 0, !isUserAuthenticated ),
996 priceClean = product.GetDouble( "Ecom:Product.Price.PriceWithoutVAT.Value" ),
997 isBeforePrice = ( ppi != null && ppi.BeforePrice != null ) ? true : false,
998 beforePrice = ( ppi != null && ppi.BeforePrice != null ) ?
999 Co3.DCC.Dw.Services.ProductService.Instance.GetPriceFormatted( ppi.BeforePrice.PriceAmount ) :
1000 "",
1001 isActive = product.GetBoolean( "Ecom:Product.IsActive" ),
1002 isCampaign = ( ppi != null ) ? ppi.IsCampaignPrice : false,
1003 isOutlet = isOutlet,
1004 isCallForPrice = isCallForPrice,
1005 isNoPrice = (ppi != null && ppi.Price != null && ppi.Price.PriceAmount == 0),
1006 isConfigurable = isConfigurable,
1007 isConfiguratorActive = IsConfiguratorActive(),
1008 isInCart = product.GetBoolean( "Ecom:Product.IsInCart" ),
1009 descriptionShortExtra01 = product.GetString( "Ecom:Product:Field.DescriptionShortExtra01" ),
1010 stock = stockNumber,
1011 a_stock = productObject.Stock,
1012 stockCheck = stockCheck,
1013 stockState = product.GetString( "Ecom:Product:Stock.DeliveryText" ),
1014 stockLabel = product.GetString( "Ecom:Product:Stock.Text" ),
1015 remoteStock = string.IsNullOrEmpty(product.GetString("Ecom:Product:Field.RemoteStock")) == false ? Translate(remoteStockTranslationKey, product.GetString("Ecom:Product:Field.RemoteStock")) : string.Empty,
1016 stockETA = stockETA,
1017 productDescription = productDescription,
1018 categoryFieldsNotebook = categoryFieldsNotebook,
1019 categoryFieldsPc = categoryFieldsPc,
1020 categoryFieldsServer = categoryFieldsServer,
1021 categoryFieldsStorage = categoryFieldsStorage,
1022 categoryFieldsMonitor = categoryFieldsMonitor,
1023 categoryFieldsOther = categoryFieldsOther,
1024 simpleDesc = Co3.DCC.Dw.Services.ProductService.Instance.GetCategoryValue( productObject, "PIMItemDescription", "Description" ),
1025 noImage = noImage,
1026 condition = Translate( String.Format( "Product_Refurbished_Condition_{0}", condition ), condition ),
1027 conditionClass = conditionClass,
1028 mainCategory = mainCategory,
1029 favoriteLists = favoriteLists,
1030 isUserAuthenticated = isUserAuthenticated,
1031 listId = listId,
1032 hasDirectSale = hasDirectSale,
1033 productWarning = productObject.GetProductFieldValue<string>("ProductWarning")
1034 };
1035 if ( productObject != null )
1036 {
1037 return Product;
1038 }
1039 return null;
1040
1041 }
1042
1043 public dynamic DCCProductListItemData( IEnumerable< RazorTemplateBase< RazorTemplateModel< Template > >.LoopItem > productLoop, User user, int productTrim = 0,bool isAddMulti = false, int listId = 0 )
1044 {
1045
1046 dynamic JSON = new
1047 {
1048 products = new List< dynamic >(),
1049 isAddMulti = isAddMulti
1050 };
1051
1052 if ( productLoop != null && productLoop.Any() == true )
1053 {
1054
1055
1056 int productCounter = 0;
1057
1058 foreach ( RazorTemplateBase< RazorTemplateModel< Template > >.LoopItem product in productLoop )
1059 {
1060 if ( product != null )
1061 {
1062 if ( productTrim > 0 )
1063 {
1064 if ( productCounter < productTrim )
1065 {
1066 if ( ObjProductListItem( product, user, productCounter, listId ) != null )
1067 {
1068 JSON.products.Add( ObjProductListItem( product, user, productCounter, listId ) );
1069 }
1070
1071 }
1072
1073 }
1074 else
1075 {
1076 if ( ObjProductListItem( product, user, productCounter, listId ) != null )
1077 {
1078 JSON.products.Add( ObjProductListItem( product, user, productCounter, listId ) );
1079 }
1080 }
1081 productCounter++;
1082 }
1083
1084 }
1085 }
1086 return JSON;
1087 }
1088
1089 public string ConfiguratorPartName(string partName, bool translateOther = false)
1090 {
1091 string returnValue = partName;
1092 string translationKey = string.Empty;
1093
1094
1095
1096 if ( partName == Co3.DCC.Data.Utilities.Constants.ECOMMERCE_PRODUCT_OSLANGUAGE_MX_PRODUCTNUMBER )
1097 {
1098 translationKey = string.Format( "DCC - Configurator - List - OS Language - {0} - Label", Co3.DCC.Data.Utilities.Constants.ECOMMERCE_PRODUCT_OSLANGUAGE_MX_PRODUCTNUMBER );
1099 partName = Translate( translationKey, string.Format( "{0} (Dansk / Svensk / Finsk / Norsk / Engelsk)", Co3.DCC.Data.Utilities.Constants.ECOMMERCE_PRODUCT_OSLANGUAGE_MX_PRODUCTNUMBER ) );
1100 }
1101 if ( partName == Co3.DCC.Data.Utilities.Constants.ECOMMERCE_PRODUCT_OSLANGUAGE_MH_PRODUCTNUMBER )
1102 {
1103 translationKey = string.Format( "DCC - Configurator - List - OS Language - {0} - Label", Co3.DCC.Data.Utilities.Constants.ECOMMERCE_PRODUCT_OSLANGUAGE_MH_PRODUCTNUMBER );
1104 partName = Translate( translationKey, string.Format( "{0} (Tysk / Fransk / Italiensk / Hollandsk / Engelsk)", Co3.DCC.Data.Utilities.Constants.ECOMMERCE_PRODUCT_OSLANGUAGE_MH_PRODUCTNUMBER ) );
1105 }
1106 if ( partName == Co3.DCC.Data.Utilities.Constants.ECOMMERCE_PRODUCT_OSLANGUAGE_ES_PRODUCTNUMBER )
1107 {
1108 translationKey = string.Format( "DCC - Configurator - List - OS Language - {0} - Label", Co3.DCC.Data.Utilities.Constants.ECOMMERCE_PRODUCT_OSLANGUAGE_ES_PRODUCTNUMBER );
1109 partName = Translate( translationKey, string.Format( "{0} (Spansk)", Co3.DCC.Data.Utilities.Constants.ECOMMERCE_PRODUCT_OSLANGUAGE_ES_PRODUCTNUMBER ) );
1110 }
1111 if ( translateOther == true && partName == Co3.DCC.Data.Utilities.Constants.ECOMMERCE_PRODUCT_OSLANGUAGE_Other_PRODUCTNUMBER )
1112 {
1113 translationKey = string.Format( "DCC - Configurator - List - OS Language - {0} - Label", Co3.DCC.Data.Utilities.Constants.ECOMMERCE_PRODUCT_OSLANGUAGE_Other_PRODUCTNUMBER );
1114 partName = Translate( translationKey, string.Format( "{0}", Co3.DCC.Data.Utilities.Constants.ECOMMERCE_PRODUCT_OSLANGUAGE_Other_PRODUCTNUMBER ) );
1115 }
1116
1117
1118 if ( partName == Co3.DCC.Data.Utilities.Constants.ECOMMERCE_PRODUCT_OSLANGUAGE_Other_PRODUCTNUMBER )
1119 {
1120 translationKey = string.Format( "DCC - Configurator - List - OS Language - {0} - Label", Co3.DCC.Data.Utilities.Constants.ECOMMERCE_PRODUCT_OSLANGUAGE_Other_PRODUCTNUMBER );
1121 partName = Translate( translationKey, string.Format( "{0}", Co3.DCC.Data.Utilities.Constants.ECOMMERCE_PRODUCT_OSLANGUAGE_Other_PRODUCTNUMBER ) );
1122 }
1123
1124 return partName;
1125 }
1126
1127 }
1128
1129 @helper DCCProductListPlain( string sectionClasses = "e-section", string contentClasses = null, string heading = null,
1130 IEnumerable< RazorTemplateBase< RazorTemplateModel< Template > >.LoopItem > productLoop = null, int productTrim = 0, bool isAddMulti = false, int listId = 0 )
1131 {
1132
1133 ClassList headingClassList = new ClassList();
1134 headingClassList.AddClasses( "col-12" );
1135 ClassList contentClassList = new ClassList();
1136 contentClassList.AddClasses( "col-12" );
1137
1138 contentClassList.AddClasses( "col-12 js-dcc-plain-products-list" );
1139
1140 if (isAddMulti == false)
1141 {
1142 contentClassList.AddClasses( "js-e-productlist" );
1143 }
1144
1145 User user = User.get_Current( PagePermissionLevels.Frontend );
1146
1147
1148 @sectionStart( sectionClasses: sectionClasses, contentClasses: contentClasses )
1149
1150 if ( string.IsNullOrEmpty( heading ) == false )
1151 {
1152 <div class="@headingClassList">
1153 <h2 class="text-center">@heading</h2>
1154 </div>
1155 }
1156
1157
1158 string partialItemPath = "Designs/dcc/eCom/ProductList/inc/dcc-partial-item.cshtml";
1159
1160 if (isAddMulti)
1161 {
1162 partialItemPath = "Designs/dcc/eCom/ProductList/inc/dcc-partial-item-add-multi.cshtml";
1163 }
1164
1165
1166
1167 <div class="@contentClassList" >
1168 <div class="js-dcc-plain-products-list-products">
1169 <script class="js-dcc-plain-products-list-data" type="application/json">
1170 @JsonService.Instance.ToJson( DCCProductListItemData(productLoop, user, productTrim, isAddMulti, listId) )
1171 </script>
1172 <script id="js-e-handlebars-tmpl-productlist-plain-products" type="text/x-handlebars-template">
1173
1174 <div class="e-products mb-2">
1175 <div class="row">
1176 {{#each products}}
1177 @Co3.DCC.Dw.Services.TemplateService.Instance.PartialView( partialItemPath )
1178 {{/each}}
1179 </div>
1180 </div>
1181 </script>
1182 </div>
1183 </div>
1184
1185 @sectionEnd()
1186 }
1187
1188 @helper DCCProductListCarousel( string sectionClasses = "e-section", string contentClasses = null, string heading = null,
1189 IEnumerable< RazorTemplateBase< RazorTemplateModel< Template > >.LoopItem > productLoop = null, int productTrim = 0 )
1190 {
1191
1192 ClassList headingClassList = new ClassList();
1193 headingClassList.AddClasses( "col-12" );
1194 ClassList contentClassList = new ClassList();
1195 contentClassList.AddClasses( "col-12" );
1196
1197 User user = User.get_Current( PagePermissionLevels.Frontend );
1198
1199 @sectionStart( sectionClasses: sectionClasses, contentClasses: contentClasses )
1200
1201 if ( string.IsNullOrEmpty( heading ) == false )
1202 {
1203 <div class="@headingClassList">
1204 <h2 class="text-center">@heading</h2>
1205 </div>
1206 }
1207
1208 <div class="@contentClassList js-dcc-plain-products-list js-e-productlist">
1209 <div id="dcc-plain-products-list-carousel-@Pageview.CurrentParagraph.ID" class="carousel js-dcc-plain-products-list-carousel dcc-plain-products-list-carousel slide" data-ride="false" data-interval="false">
1210 <div class="carousel-inner js-dcc-plain-products-list-products">
1211 <script class="js-dcc-plain-products-list-data" type="application/json">
1212 @JsonService.Instance.ToJson( DCCProductListItemData(productLoop, user, productTrim) )
1213 </script>
1214 <script id="js-e-handlebars-tmpl-productlist-plain-products" type="text/x-handlebars-template">
1215 <div class="e-products">
1216 {{#grouped_each carouselCount products}}
1217 <div class="carousel-item">
1218 <div class="row mx-6">
1219 {{#each this}}
1220 @Co3.DCC.Dw.Services.TemplateService.Instance.PartialView( "Designs/dcc/eCom/ProductList/inc/dcc-partial-item.cshtml" )
1221 {{/each}}
1222 </div>
1223 </div>
1224 {{/grouped_each}}
1225 </div>
1226 </script>
1227 </div>
1228 <a class="carousel-control-prev" data-slide="prev" href="#dcc-plain-products-list-carousel-@Pageview.CurrentParagraph.ID"></a>
1229 <a class="carousel-control-next" data-slide="next" href="#dcc-plain-products-list-carousel-@Pageview.CurrentParagraph.ID"></a>
1230 </div>
1231 </div>
1232
1233 @sectionEnd()
1234
1235 }
1236
1237 @using System
1238 @using System.Collections.Generic
1239 @using System.Linq
1240 @using System.Text.RegularExpressions
1241 @using Co3.DCC.Data.DAL.Models
1242 @using Co3.DCC.Dw.Models.FrontEnd
1243 @using Co3.Espresso.Base.Extensions
1244 @using Co3.Espresso.Website.Services
1245 @using Dynamicweb.Ecommerce.Common
1246 @using Dynamicweb.Ecommerce.Products
1247 @using Dynamicweb.Frontend
1248 @using Dynamicweb.Security.UserManagement
1249
1250 @{
1251 bool isExtranet = GetGlobalValue( "Global:Extranet.UserID" ) == "0" ? false : true;
1252 bool hasDirectSale = (bool)PageView.Current().Area.Item["HasDirectSales"];
1253 User currentUser = User.get_Current( PagePermissionLevels.Frontend );
1254 bool isActive = GetBoolean( "Ecom:Product.IsActive" );
1255 string currencyCode = Context.Currency.Code;
1256
1257 if ( currentUser != null && string.IsNullOrEmpty( currentUser.Currency ) == false )
1258 {
1259 currencyCode = Dynamicweb.Ecommerce.Services.Currencies.GetCurrencyForCode( currentUser.Currency ).Code;
1260 }
1261
1262
1263
1264 //TODO Fix currency code
1265
1266 Dynamicweb.Ecommerce.Products.ProductService dwProductService = new Dynamicweb.Ecommerce.Products.ProductService();
1267 Product dwProduct = dwProductService.GetProductById( GetString( "Ecom:Product.ID" ), GetString( "Ecom:Product.VariantID" ), true );
1268
1269
1270 string mainCategory = GetString( "Ecom:Product:Field.InventoryPostingGroup.Value.Clean" );
1271 string[] selectedMainCategories = {"NOTEBOOK", "PC", "SERVER", "STORAGE", "MONITOR", "OTHER"};
1272 string manufacturerCode = GetString( "Ecom:Product:Field.GlobalDimension2Code.Value.Clean" );
1273 string conditionRaw = GetString( "Ecom:Product:Field.Condition.Value.Clean" );
1274 string condition = Translate( String.Format( "Product_Refurbished_Condition_{0}", conditionRaw ), conditionRaw );
1275 string conditionClass = "dcc-condition-" + Regex.Replace( conditionRaw, @"\s", String.Empty ).ToLower().Trim().Replace( ".", "" );
1276
1277 bool stockCheck = GetInteger( "Ecom:Product.Stock" ) > 0;
1278 string stockNumber;
1279
1280 bool hasPrice = true;
1281
1282 string productId = GetString( "Ecom:Product.ID" );
1283 Product productObject = Co3.DCC.Dw.Services.ProductService.Instance.GetProductById( productId );
1284 ProductPriceInfo ppi = Co3.DCC.Dw.Services.ProductService.Instance.GetProductPriceInfo( productObject );
1285 bool isLeasingAllowed = Co3.DCC.Dw.Services.ProductService.Instance.IsLeasingAllowed( productObject );
1286
1287 ConfigurationDetails configurationDetails = Co3.DCC.Dw.Services.ProductService.Instance.GetConfigurationDetails( productObject );
1288
1289 bool outlet = productObject.GetProductFieldValue<bool>( "Outlet" );
1290 bool isCallForPrice = productObject.GetProductFieldValue<bool>( "WebCallForPrice" );
1291 bool isConfigurable = productObject.GetProductFieldValue<bool>( "IsConfigurable" );
1292 string isOSConfigurable = Co3.DCC.Dw.Services.ProductService.Instance.GetCategoryValue( productObject, "ItemAttributes", "OSConfigurable" ).ToLower();
1293
1294 List<SpecificationCategory> specificationCategory = Co3.DCC.Dw.Services.ProductService.Instance.GetProductSpecifications( productObject );
1295 SpecificationCategory PIMspecificationCategory = Co3.DCC.Dw.Services.ProductService.Instance.GetPIMItemProductSpecification( productObject );
1296
1297
1298 string BrandLogoDirectory = @"~\Files\Images\dcc\icons\";
1299 string BrandLogoPath = "/Files/Images/dcc/icons/";
1300
1301
1302 if ( manufacturerCode == "AMP" || manufacturerCode == "APC" || manufacturerCode == "TYCO" || manufacturerCode == "UPS" )
1303 {
1304 stockNumber = GetDouble( "Ecom:Product.Stock" ).ToString();
1305 }
1306 else
1307 {
1308 stockNumber = GetDouble( "Ecom:Product.Stock" ).ToString();
1309 }
1310
1311 string stockETA = string.Empty;
1312
1313 if ( Co3.DCC.Dw.Services.ProductService.Instance.IsNextPurchaseDateSet( dwProduct ) == true )
1314 {
1315 double stockAmount = Co3.DCC.Dw.Services.ProductService.Instance.GetQtyAvailableOnStockPlus( dwProduct );
1316 string stockAmountText = stockAmount.ToString();
1317 string stockEtaDate = Co3.DCC.Dw.Services.ProductService.Instance.GetNextPurchaseDateFormatted( dwProduct );
1318
1319 if ( stockAmount > 0 )
1320 {
1321 stockETA = string.Format( "{0} {1} {2}", stockAmountText, Translate( "eCom Product - ETA - Expected in stock - Text", "forventet på lager" ), stockEtaDate );
1322 }
1323
1324
1325 }
1326
1327
1328
1329
1330 IEnumerable<ProductRelatedGroup> relatedGroups = productObject.RelatedGroups;
1331
1332 ProductCollection warrantyRelatedProductCollection = new ProductCollection();
1333
1334 if ( relatedGroups.FirstOrDefault( rg => rg.GroupId == "WARRANTY" ) != null )
1335 {
1336 warrantyRelatedProductCollection = relatedGroups.FirstOrDefault( rg => rg.GroupId == "WARRANTY" ).Products;
1337 }
1338
1339 List<dynamic> warrantyRelatedProducts = new List<dynamic>();
1340
1341 foreach ( Product relatedWarrentyProduct in warrantyRelatedProductCollection )
1342 {
1343 if ( relatedWarrentyProduct.IsActive && relatedWarrentyProduct.Price.Price > 0 )
1344 {
1345 warrantyRelatedProducts.Add( new
1346 {
1347 id = relatedWarrentyProduct.Id,
1348 name = relatedWarrentyProduct.Name,
1349 number = relatedWarrentyProduct.Number,
1350 intPrice = relatedWarrentyProduct.Price.PriceWithoutVAT,
1351 strPrice = relatedWarrentyProduct.Price.PriceWithoutVAT.ToString( "N2" ),
1352 shortDescription = relatedWarrentyProduct.ShortDescription
1353 } );
1354 }
1355 }
1356
1357 if (warrantyRelatedProducts.Any())
1358 {
1359 isConfigurable = true;
1360 }
1361
1362 bool hasRelated = relatedGroups != null && productObject.RelatedGroups.Any();
1363
1364 string keyboardLanguage = Co3.DCC.Dw.Services.ProductService.Instance.GetCategoryValue( productObject, "ItemAttributes", "Keyboard_Language" );
1365 string productType = Co3.DCC.Dw.Services.ProductService.Instance.GetCategoryValue( productObject, "ItemAttributes", "Product_Type" );
1366
1367 dynamic JSON = new
1368 {
1369 configurationDetails = configurationDetails,
1370 PIMspecificationCategory = PIMspecificationCategory,
1371 ItemDescriptionByItemRelations = new List<dynamic>(),
1372 product = new
1373 {
1374 id = productObject.Id,
1375 variantId = productObject.VariantId,
1376 OSConfigurable = isOSConfigurable,
1377 },
1378 isLeasingAllowed = isLeasingAllowed,
1379 prices = new
1380 {
1381 currencyCode = Context.Currency.Code,
1382 basePrice = ppi != null && ppi.Price != null ? ppi.Price.PriceAmount : 0,
1383 basePriceFormatted = ppi != null && ppi.Price != null ? Co3.DCC.Dw.Services.ProductService.Instance.GetPriceFormatted( ppi.Price.PriceAmount ) : string.Empty,
1384 beforePrice = ppi != null && ppi.BeforePrice != null ? ppi.BeforePrice.PriceAmount : 0,
1385 beforePriceFormatted = ppi != null && ppi.BeforePrice != null ? Co3.DCC.Dw.Services.ProductService.Instance.GetPriceFormatted( ppi.BeforePrice.PriceAmount ) : string.Empty
1386 },
1387 configurables = new Dictionary<string, dynamic>(),
1388 warrantyRelatedProducts = warrantyRelatedProducts
1389 };
1390
1391 double autoPilotPrice = 0;
1392 if (User.IsExtranetUserLoggedIn() && (productType == "MOBILE" || productType == "Desktops"))
1393 {
1394 string userAutopilotPrice = User.GetCurrentUser().GetCustomFieldValue<string>("AutopilotPrice");
1395 double.TryParse(userAutopilotPrice, out autoPilotPrice);
1396 }
1397 }
1398
1399
1400
1401
1402 @if ( ppi != null )
1403 {
1404
1405 if ( ppi.Price != null )
1406 {
1407 if ( ppi.Price.PriceAmount == 0 )
1408 {
1409 hasPrice = false;
1410 }
1411 }
1412 }
1413
1414 @sectionEnd()
1415 <div id="@GetValue( "Ecom:Product.ID" )" class="e-product js-dcc-main-product" data-product-id="@productId">
1416 @sectionStart(
1417 sectionClasses: "e-section pb-3"
1418 )
1419
1420
1421 <div class="col-12 col-md-5">
1422 <div class="e-product-text-container">
1423 <div class="row">
1424 <div class="col-12 col-md-10">
1425 <p></p>
1426
1427 @if ( Directory.Exists( HttpContext.Current.Server.MapPath( BrandLogoDirectory ) ) )
1428 {
1429
1430 string BrandCode = GetString( "Ecom:Product:Field.GlobalDimension2Code.Value.Clean" ).ToLower();
1431 DirectoryInfo directory = new DirectoryInfo( HttpContext.Current.Server.MapPath( BrandLogoDirectory ) );
1432
1433 List< FileInfo > files = directory.GetFiles().ToList();
1434 foreach ( FileInfo file in files )
1435 {
1436 if (file.Name == string.Format("{0}.svg", BrandCode) )
1437
1438 {
1439 string imgPath = string.Format( "{0}{1}", BrandLogoPath, file.Name );
1440
1441 <img class="dcc-custom-brandlogo" src="@imgPath" />
1442 }
1443
1444 }
1445 }
1446
1447 <h1 class="e-product-name h2 mb-0 mt-1">
1448 @GetString( "Ecom:Product.Name" )
1449 </h1>
1450 <p class="small mb-2">
1451 @Translate( "eCom Product - Product Number - Text", "Number" ) @GetString( "Ecom:Product.Number" )
1452 @if ( GetString( "Ecom:Product:Field.GetEAN.Value.Clean" ) != "NOEAN" )
1453 {
1454 <br>
1455 @Translate( "eCom Product - EAN Number - Text", "EAN" )
1456 @GetString( "Ecom:Product:Field.GetEAN.Value.Clean" )
1457 }
1458 @if (string.IsNullOrEmpty(dwProduct.GetProductFieldValue<string>("ProductWarning")) == false)
1459 {
1460 <p class="alert alert-secondary small my-1">
1461 @Translate("eCom - Product - Warning - Label") @(dwProduct.GetProductFieldValue<string>("ProductWarning"))
1462 </p>
1463 }
1464 </p>
1465
1466 @using Dynamicweb.Frontend
1467 @* NOTEBOOK AND PHONE *@
1468
1469 @{
1470 string helpText = Translate("mainCategory_Icon_HelpText", "mainCategory_Icon_HelpText");
1471
1472 if (PageView.Current().User != null)
1473 {
1474 helpText = Translate("mainCategory_Icon_HelpText_loggedIn", "mainCategory_Icon_HelpText_loggedIn");
1475 }
1476 }
1477
1478 @if ( mainCategory == "NOTEBOOK" || mainCategory == "PHONE" )
1479 {
1480 if ( Espresso.Area.Item.MainCategoryFieldsNotebook != null )
1481 {
1482 List< DescriptionField > customCategoryFieldsNotebook = Co3.DCC.Dw.Services.ProductService.GetProductItemDescriptionByItemRelations( productObject, Espresso.Area.Item.MainCategoryFieldsNotebook );
1483 <div class="attribute-field-wrapper">
1484 @foreach ( DescriptionField descriptionField in customCategoryFieldsNotebook )
1485 {
1486 <div class="attribute-field-header" data-category="@mainCategory">
1487 @if (isConfigurable && string.IsNullOrEmpty(descriptionField.ConfigurationAnchor) == false && PageView.Current().User != null)
1488 {
1489 string anchor = string.Format("{0}#dcc-productpage-tab-config", PageView.Current().SearchFriendlyUrl);
1490
1491 <a class="js-dcc-configurator-anchor-link" href="@anchor" style="text-decoration: none;" title="@helpText">
1492 <img src="/files/images/dcc/icons/configuration.svg" style="width:16px;height:16px;margin:0 5px 0 0">
1493 </a>
1494 }
1495 else
1496 {
1497 <span class="d-inline-flex justify-content-center align-items-center" style="width:16px;height:16px;margin:0 5px 0 0;font-size: 1.5em;">
1498 ·
1499 </span>
1500 }
1501 @Translate(String.Format("mainCategory_FieldLabel_{0}", descriptionField.Header), descriptionField.Header)
1502 </div>
1503
1504 <div class="attribute-field-value">
1505
1506 @descriptionField.Value.Replace( "U0022", "\"" )
1507 </div>
1508 JSON.ItemDescriptionByItemRelations.Add(new
1509 {
1510 header = descriptionField.Header,
1511 value = descriptionField.Value,
1512 configurationAnchor = descriptionField.ConfigurationAnchor
1513 });
1514 }
1515 </div>
1516 }
1517 }
1518 @* PC *@
1519 else if ( mainCategory == "PC" )
1520 {
1521 if ( Espresso.Area.Item.MainCategoryFieldsPC != null )
1522 {
1523 List< DescriptionField > customCategoryFieldsPc = Co3.DCC.Dw.Services.ProductService.GetProductItemDescriptionByItemRelations( productObject, Espresso.Area.Item.MainCategoryFieldsPC );
1524
1525 <div class="attribute-field-wrapper">
1526 @foreach ( DescriptionField descriptionField in customCategoryFieldsPc )
1527 {
1528 <div class="attribute-field-header" data-category="@mainCategory">
1529 @if (isConfigurable && string.IsNullOrEmpty(descriptionField.ConfigurationAnchor) == false && PageView.Current().User != null)
1530 {
1531 string anchor = string.Format("{0}#dcc-productpage-tab-config", PageView.Current().SearchFriendlyUrl);
1532 <a class="js-dcc-configurator-anchor-link" href="@anchor" style="text-decoration: none;" title="@helpText">
1533 <img src="/files/images/dcc/icons/configuration.svg" style="width:16px;height:16px;margin:0 5px 0 0">
1534 </a>
1535 }
1536 else
1537 {
1538 <span class="d-inline-flex justify-content-center align-items-center" style="width:16px;height:16px;margin:0 5px 0 0;font-size: 1.5em;">
1539 ·
1540 </span>
1541 }
1542 @Translate(String.Format("mainCategory_FieldLabel_{0}", descriptionField.Header), descriptionField.Header)
1543 </div>
1544 <div class="attribute-field-value">@descriptionField.Value</div>
1545 JSON.ItemDescriptionByItemRelations.Add(new
1546 {
1547 header = descriptionField.Header,
1548 value = descriptionField.Value + $"({descriptionField.ConfigurationAnchor})",
1549 configurationAnchor = descriptionField.ConfigurationAnchor
1550 });
1551 }
1552 </div>
1553 }
1554 }
1555 @* SERVER *@
1556 else if ( mainCategory == "SERVER" )
1557 {
1558 if ( Espresso.Area.Item.MainCategoryFieldsServer != null )
1559 {
1560 List< DescriptionField > customCategoryFieldsServer = Co3.DCC.Dw.Services.ProductService.GetProductItemDescriptionByItemRelations( productObject, Espresso.Area.Item.MainCategoryFieldsServer );
1561
1562 <div class="attribute-field-wrapper">
1563 @foreach ( DescriptionField descriptionField in customCategoryFieldsServer )
1564 {
1565 <div class="attribute-field-header" data-category="@mainCategory">
1566 @if (isConfigurable && string.IsNullOrEmpty(descriptionField.ConfigurationAnchor) == false && PageView.Current().User != null)
1567 {
1568 string anchor = string.Format("{0}#dcc-productpage-tab-config", PageView.Current().SearchFriendlyUrl);
1569 <a class="js-dcc-configurator-anchor-link" href="@anchor" style="text-decoration: none;" title="@helpText">
1570 <img src="/files/images/dcc/icons/configuration.svg" style="width:16px;height:16px;margin:0 5px 0 0">
1571 </a>
1572 }
1573 else
1574 {
1575 <span class="d-inline-flex justify-content-center align-items-center" style="width:16px;height:16px;margin:0 5px 0 0;font-size: 1.5em;">
1576 ·
1577 </span>
1578 }
1579 @Translate(String.Format("mainCategory_FieldLabel_{0}", descriptionField.Header), descriptionField.Header)
1580 </div>
1581 <div class="attribute-field-value">@descriptionField.Value.Replace( "U0022", "\"" )</div>
1582 JSON.ItemDescriptionByItemRelations.Add(new
1583 {
1584 header = descriptionField.Header,
1585 value = descriptionField.Value,
1586 configurationAnchor = descriptionField.ConfigurationAnchor
1587 });
1588 }
1589 </div>
1590 }
1591 }
1592 @* STORAGE *@
1593 else if ( mainCategory == "STORAGE" )
1594 {
1595 if ( Espresso.Area.Item.MainCategoryFieldsStorage != null )
1596 {
1597 List< DescriptionField > customCategoryFieldsStorage = Co3.DCC.Dw.Services.ProductService.GetProductItemDescriptionByItemRelations( productObject, Espresso.Area.Item.MainCategoryFieldsStorage );
1598
1599 <div class="attribute-field-wrapper">
1600 @foreach ( DescriptionField descriptionField in customCategoryFieldsStorage )
1601 {
1602 <div class="attribute-field-header" data-category="@mainCategory">
1603 @if (isConfigurable && string.IsNullOrEmpty(descriptionField.ConfigurationAnchor) == false && PageView.Current().User != null)
1604 {
1605 string anchor = string.Format("{0}#dcc-productpage-tab-config", PageView.Current().SearchFriendlyUrl);
1606 <a class="js-dcc-configurator-anchor-link" href="@anchor" style="text-decoration: none;" title="@helpText">
1607 <img src="/files/images/dcc/icons/configuration.svg" style="width:16px;height:16px;margin:0 5px 0 0">
1608 </a>
1609 }
1610 else
1611 {
1612 <span class="d-inline-flex justify-content-center align-items-center" style="width:16px;height:16px;margin:0 5px 0 0;font-size: 1.5em;">
1613 ·
1614 </span>
1615 }
1616 @Translate(String.Format("mainCategory_FieldLabel_{0}", descriptionField.Header), descriptionField.Header)
1617 </div>
1618 <div class="attribute-field-value">@descriptionField.Value.Replace( "U0022", "\"" )</div>
1619 JSON.ItemDescriptionByItemRelations.Add(new
1620 {
1621 header = descriptionField.Header,
1622 value = descriptionField.Value,
1623 configurationAnchor = descriptionField.ConfigurationAnchor
1624 });
1625 }
1626 </div>
1627 }
1628 }
1629 @* MONITOR *@
1630 else if ( mainCategory == "MONITOR" )
1631 {
1632 if ( Espresso.Area.Item.MainCategoryFieldsMonitor != null )
1633 {
1634 List< DescriptionField > customCategoryFieldsMonitor = Co3.DCC.Dw.Services.ProductService.GetProductItemDescriptionByItemRelations( productObject, Espresso.Area.Item.MainCategoryFieldsMonitor );
1635 <div class="attribute-field-wrapper">
1636 @foreach ( DescriptionField descriptionField in customCategoryFieldsMonitor )
1637 {
1638 <div class="attribute-field-header" data-category="@mainCategory">
1639 @if (isConfigurable && string.IsNullOrEmpty(descriptionField.ConfigurationAnchor) == false && PageView.Current().User != null)
1640 {
1641 string anchor = string.Format("{0}#dcc-productpage-tab-config", PageView.Current().SearchFriendlyUrl);
1642 <a class="js-dcc-configurator-anchor-link" href="@anchor" style="text-decoration: none;" title="@helpText">
1643 <img src="/files/images/dcc/icons/configuration.svg" style="width:16px;height:16px;margin:0 5px 0 0">
1644 </a>
1645 }
1646 else
1647 {
1648 <span class="d-inline-flex justify-content-center align-items-center" style="width:16px;height:16px;margin:0 5px 0 0;font-size: 1.5em;">
1649 ·
1650 </span>
1651 }
1652 @Translate(String.Format("mainCategory_FieldLabel_{0}", descriptionField.Header), descriptionField.Header)
1653 </div>
1654 <div class="attribute-field-value">@descriptionField.Value.Replace( "U0022", "\"" )</div>
1655 JSON.ItemDescriptionByItemRelations.Add(new
1656 {
1657 header = descriptionField.Header,
1658 value = descriptionField.Value,
1659 configurationAnchor = descriptionField.ConfigurationAnchor
1660 });
1661 }
1662 </div>
1663 }
1664 }
1665 else if ( mainCategory == "MONITOR" )
1666 {
1667 List< DescriptionField > customCategoryFieldsOther = Co3.DCC.Dw.Services.ProductService.GetProductItemDescriptionByItemRelations( productObject, Espresso.Area.Item.MainCategoryFieldsOther );
1668 <div class="attribute-field-wrapper">
1669 @foreach ( DescriptionField descriptionField in customCategoryFieldsOther )
1670 {
1671 <div class="attribute-field-header" data-category="@mainCategory">
1672 @if (isConfigurable && string.IsNullOrEmpty(descriptionField.ConfigurationAnchor) == false && PageView.Current().User != null)
1673 {
1674 string anchor = string.Format("{0}#dcc-productpage-tab-config", PageView.Current().SearchFriendlyUrl);
1675 <a class="js-dcc-configurator-anchor-link" href="@anchor" style="text-decoration: none;" title="@helpText">
1676 <img src="/files/images/dcc/icons/configuration.svg" style="width:16px;height:16px;margin:0 5px 0 0">
1677 </a>
1678 }
1679 else
1680 {
1681 <span class="d-inline-flex justify-content-center align-items-center" style="width:16px;height:16px;margin:0 5px 0 0;font-size: 1.5em;">
1682 ·
1683 </span>
1684 }
1685 @Translate(String.Format("mainCategory_FieldLabel_{0}", descriptionField.Header), descriptionField.Header)
1686 </div>
1687 <div class="attribute-field-value">@descriptionField.Value.Replace( "U0022", "\"" )</div>
1688 JSON.ItemDescriptionByItemRelations.Add(new
1689 {
1690 header = descriptionField.Header,
1691 value = descriptionField.Value,
1692 configurationAnchor = descriptionField.ConfigurationAnchor
1693 });
1694 }
1695 </div>
1696 }
1697 else
1698 {
1699 <p>@Co3.DCC.Dw.Services.ProductService.Instance.GetCategoryValue( productObject, "PIMItemDescription", "Description" )</p>
1700 }
1701
1702
1703 </div>
1704 <div class="col-3">
1705
1706 </div>
1707 </div>
1708
1709
1710 @* AUTOPILOT *@
1711 @using Co3.Espresso.Base.Extensions
1712 @using Dynamicweb.Notifications
1713 @using Dynamicweb.Security.UserManagement
1714 @using Dynamicweb.SystemTools
1715
1716 @if (User.IsExtranetUserLoggedIn() && autoPilotPrice > 0)
1717 {
1718 <div class="row">
1719 <div class="col-12 mb-2">
1720 <div class="dcc-leasing-wrapper small">
1721 <div class="row">
1722 <div class="col-12 col-lg-6 mb-2 mb-lg-0 small">
1723 <label>
1724 <input type="checkbox" class="js-dcc-autopilot-checkbox" data-toggle="collapse" data-target="#dcc-autopilot-collapse" data-price="100"/>
1725 @Translate("DCC - Configurator - Overview - Autopilot - Header", "Autopilot")
1726 </label>
1727 </div>
1728 <div class="col-12 col-lg-6 mb-2 mb-lg-0 small text-right">
1729 @Co3.DCC.Dw.Services.ProductService.Instance.GetPriceFormatted( autoPilotPrice )
1730 </div>
1731 <div class="col-12 order-3">
1732 <div id="dcc-autopilot-collapse" class="collapse">
1733 <div class="form-group my-1">
1734 <label for="AutopilotEmail">@Translate("DCC - Configurator - Overview - Autopilot - Email - Text", "Email address")</label>
1735 <input type="email" class="form-control js-dcc-autopilot-email-input" id="AutopilotEmail" value="@(User.IsExtranetUserLoggedIn() ? User.GetCurrentUser().Email : string.Empty)">
1736 </div>
1737 </div>
1738 </div>
1739 </div>
1740 </div>
1741 </div>
1742 </div>
1743 }
1744
1745
1746
1747
1748 <div class="js-dcc-configurator-disabled-element">
1749
1750
1751
1752
1753 @* LEASING *@
1754
1755
1756 @if ( (isExtranet || hasDirectSale) && isActive && isLeasingAllowed && isCallForPrice == false ) {
1757
1758 <div class="row">
1759 <div class="col-12 mb-2">
1760 <div class="dcc-leasing-wrapper small">
1761 <div class="row">
1762 @*
1763 <div class="col-12 col-lg-6 order-2 order-lg-1 small">
1764 @Co3.DCC.Dw.Services.ProductService.Instance.CalculateLeasingPaymentPerMonth( productObject, 36, 5 ) @currencyCode @Translate( "eCom Product - Leasing - Ratio", "pr. måned i 36 måneder" )
1765
1766 <a aria-controls="collapseExample" aria-expanded="false" class="d-block" data-toggle="collapse" href="#collapseExample" role="button">
1767 @Translate( "eCom Product - Leasing - ConfigureText", "Konfigurér leasingmuligheder" ) <i class="material-icons">unfold_more</i>
1768 </a>
1769
1770 </div>
1771 *@
1772 <div class="col-12 col-lg-6 mb-2 mb-lg-0 small ">
1773 <label><input type="checkbox" class="js-leasing-offer-checkbox" />@Translate( "eCom Product - Leasing - YesPlease", "Ja tak, jeg er interesseret i leasing." )</label>
1774 </div>
1775 @*
1776 <div class="col-12 order-3">
1777 <div class="collapse" id="collapseExample">
1778 <table class="mt-2 table">
1779 <tr>
1780 <td class="align-middle pl-0">@Translate( "eCom Product - Leasing - AvancePercent", "Avance i procent" )</td>
1781 <td class="pr-0 text-right">
1782 <select class="js-dcc-product-leasing-interest-rate p-1">
1783 @{
1784 int[] leasingInterestRates = {5, 10, 15, 20, 25};
1785 foreach ( int leasingInterestRate in leasingInterestRates )
1786 {
1787
1788 <option value="@Co3.DCC.Dw.Services.ProductService.Instance.CalculateLeasingPaymentPerMonth( productObject, 36, leasingInterestRate )">@leasingInterestRate%</option>
1789 }
1790 }
1791 </select>
1792 </td>
1793 </tr>
1794 </table>
1795 </div>
1796 </div>
1797 *@
1798 </div>
1799 </div>
1800 </div>
1801 </div>
1802 }
1803
1804 @if ( (isExtranet || hasDirectSale ) && isActive ){
1805 <div class="dcc-price-setup">
1806 <div class="row">
1807 <div class="col-12 col-md-6">
1808 <div class="dcc-price-setup-price text-right">
1809 @if ( ppi != null && ppi.Price != null )
1810 {
1811
1812 if ( isCallForPrice == false && hasPrice == true )
1813 {
1814 <span class="dcc-product-details-specifications-price @(!isExtranet ? "open-shop" : string.Empty) @(isConfigurable ? "js-dcc-configuration-main-price" : string.Empty)" data-base-price="@HttpUtility.HtmlAttributeEncode( Co3.DCC.Dw.Services.ProductService.Instance.GetPriceFormatted( ppi.Price.PriceAmount, ppi.BeforePrice != null ? ppi.BeforePrice.PriceAmount : 0, !isExtranet ) )">@Co3.DCC.Dw.Services.ProductService.Instance.GetPriceFormatted( ppi.Price.PriceAmount, ppi.BeforePrice != null ? ppi.BeforePrice.PriceAmount : 0, !isExtranet )</span>
1815 }
1816 }
1817 </div>
1818 </div>
1819 <div class="col-12 @(isCallForPrice ? "col-md-12" : "col-md-6")">
1820 <div class="dcc-price-setup-stock-and-action">
1821 <div class="dcc-flex-stock mb-1">
1822 @if (hasPrice == true)
1823 {
1824 <div class="dcc-product-list-specifications-stock-message text-right">
1825
1826 @if ( stockCheck )
1827 {
1828 <span class="dcc-custom-product-details-stockstatus dcc-stockstatus-instock">
1829 <small>@stockNumber @Translate( "eCom Product - stock in - Text", "på lager" )</small>
1830 </span>
1831 }
1832 else
1833 {
1834 <span class="dcc-custom-product-details-stockstatus dcc-stockstatus-outofstock">
1835 <small>@Translate( "eCom Product - stock out - Text", "Ikke på lager" )</small>
1836 </span>
1837 }
1838 @if (string.IsNullOrEmpty(GetString("Ecom:Product:Field.RemoteStock")) == false)
1839 {<br>
1840 <span class="dcc-custom-product-details-stockstatus dcc-stockstatus-remotestock">
1841 @{
1842 string translationKey = string.Format("eCom Product - Remote Stock - Status - {0}", GetString("Ecom:Product:Field.RemoteStock"));
1843 }
1844 <small>@Translate(translationKey, GetString("Ecom:Product:Field.RemoteStock"))</small>
1845 </span>
1846 }
1847 @if ( string.IsNullOrEmpty( stockETA ) == false )
1848 {<br>
1849 <span class="dcc-custom-product-details-stockstatus dcc-stockstatus-eta">
1850 <small>@stockETA</small>
1851 </span>
1852 }
1853
1854
1855 </div>
1856 }
1857 </div>
1858 @if ( !isCallForPrice && hasPrice )
1859 {
1860 <div class="dcc-flex-addtocart">
1861 <form action="/system/data/cart" class="e-product-form js-e-product-form" method="post">
1862 <input name="CartCmd" type="hidden" value="Add">
1863 <input type="hidden" name="ProductID" value="@GetString( "Ecom:Product.ID" )">
1864 <input name="VariantID" type="hidden" value="">
1865 <input name="UnitID" type="hidden" value="">
1866 <input name="Redirect" type="hidden" value="">
1867 <input class="js-leasing-offer-input-rate" type="hidden" value="" name="EcomOrderLineFieldInput_leasing_rate" />
1868 <input class="js-leasing-offer-input-price" type="hidden" value="" name="EcomOrderLineFieldInput_leasing_price" />
1869 <input class="js-leasing-offer-input-checked" type="hidden" value="" name="EcomOrderLineFieldInput_leasing_checked" />
1870
1871 <input class="js-dcc-autopilot-email-orderline-input" name="EcomOrderLineFieldInput_AutopilotEmail" type="hidden" value="" />
1872 <input class="js-dcc-autopilot-checked-orderline-input" name="EcomOrderLineFieldInput_Autopilot" type="hidden" value="false" />
1873
1874
1875 <input type="hidden" value="false" name="EcomOrderLineFieldInput_HasConfiguration" />
1876 <input type="hidden" value="false" name="EcomOrderLineFieldInput_IsConfigurable" />
1877 <div class="dcc-product-details-add-to-cart-wrapper">
1878
1879 <input name="Quantity" type="number" value="1" autocomplete="off">
1880 <button class="btn btn-primary @(isConfigurable ? "js-dcc-add-configuration-to-cart-from-main" : string.Empty)" type="submit">@Translate( "eCom Product - Add To Cart - Button", "Add to cart" )</button>
1881
1882 </div>
1883 </form>
1884
1885 </div>
1886 }
1887 else if (!hasPrice)
1888 {
1889 <span></span>
1890 }
1891 else if(isCallForPrice)
1892 {
1893 <div class="dcc-product-details-callforprice-wrapper">
1894 <button class="btn btn-call btn-secondary" data-toggle="modal" data-target="#callForPrice-@productId">
1895 <i class="material-icons">phone</i> @Translate( "eCom Product - callforprice - Text", "Ring for pris" )</button>
1896 </div>
1897
1898 <div class="fade modal" id="callForPrice-@productId" tabindex="-1" role="dialog" aria-labelledby="exampleModalCenterTitle" aria-hidden="true">
1899 <div class="modal-dialog modal-dialog-centered" role="document">
1900 <div class="modal-content">
1901 <div class="modal-header">
1902 <h3 class="modal-title" id="exampleModalLongTitle">@Translate( "eCom Product - callforprice - Text", "Ring for pris" )</h3>
1903 <button aria-label="Close" class="close" data-dismiss="modal" type="button">
1904 <span aria-hidden="true">×</span>
1905 </button>
1906 </div>
1907 <div class="modal-body">
1908 <div class="dcc-callforprice-product-wrapper">
1909 <div class="dcc-callforprice-image">
1910 <img src="/admin/public/getimage.ashx?Crop=0&Image=@GetValue( "Ecom:Product.ImageLarge.Clean" )&Format=jpg&Width=200&Height=&Quality=90" alt="@GetString( "Ecom:Product.Name" )">
1911 </div>
1912 <div class="dcc-callforprice-desc">
1913 <h3 class="mb-0">@GetString( "Ecom:Product.Name" )</h3>
1914 <p class="mb-0 small"># @GetString( "Ecom:Product.Number" )</p>
1915 <div class="dcc-product-list-specifications-stock-message">
1916
1917 @if ( stockCheck )
1918 {
1919 <span class="dcc-custom-product-details-stockstatus dcc-stockstatus-instock">
1920 <small>@stockNumber @Translate( "eCom Product - stock in - Text", "på lager" )</small>
1921 </span>
1922 }
1923 else
1924 {
1925 <span class="dcc-custom-product-details-stockstatus dcc-stockstatus-outofstock">
1926 <small>@Translate( "eCom Product - stock out - Text", "Ikke på lager" )</small>
1927 </span>
1928 }
1929 @if (string.IsNullOrEmpty(GetString("Ecom:Product:Field.RemoteStock")) == false)
1930 {<br>
1931 <span class="dcc-custom-product-details-stockstatus dcc-stockstatus-remotestock">
1932 @{
1933 string translationKey = string.Format("eCom Product - Remote Stock - Status - {0}", GetString("Ecom:Product:Field.RemoteStock"));
1934 }
1935 <small>@Translate(translationKey, GetString("Ecom:Product:Field.RemoteStock"))</small>
1936 </span>
1937 }
1938 @if ( string.IsNullOrEmpty( stockETA ) == false )
1939 {<br>
1940 <span class="dcc-custom-product-details-stockstatus dcc-stockstatus-eta">
1941 <small>@stockETA</small>
1942 </span>
1943 }
1944
1945 </div>
1946 </div>
1947 </div>
1948 <hr>
1949 <div class="row">
1950 <div class="col-12 col-lg-7">
1951 @RenderParagraphContent( 14654 )
1952 </div>
1953
1954 <div class="col-12 col-lg-5 mt-5 mt-lg-0">
1955 <div class="col-12 p p-imagetext p-imagetext-lr p-width-auto">
1956 <p class="h3 mb-1 small text-secondary">@Translate( "eCom callforprice - contactDCCDirectly - Text", "Kontakt DCC direkte på" )</p>
1957 <p class="lead mb-1 small">
1958 <small>
1959 <i class="material-icons">phone</i> <a href="tel:@Translate( "eCom callforprice - dccPhone - Text", "+45 8698 8660" )"> @Translate( "eCom callforprice - dccPhone - Text", "+45 8698 8660" )</a>
1960 </small>
1961 </p>
1962 <p class="lead small">
1963 <small>
1964 <i class="material-icons">mail_outline</i> <a href="mailto:@Translate( "eCom callforprice - dccPMail - Text", "info@dcc.dk" )"> @Translate( "eCom callforprice - dccPMail - Text", "info@dcc.dk" )</a>
1965 </small>
1966 </p>
1967 </div>
1968 </div>
1969 </div>
1970
1971 </div>
1972
1973 </div>
1974 </div>
1975 </div>
1976 }
1977 </div>
1978 </div>
1979 </div>
1980 </div>
1981 }
1982
1983 @if ( (isExtranet || hasDirectSale) && isActive )
1984 {
1985 if ( !isCallForPrice )
1986 {
1987 if ( ppi != null && ppi.QuantityPrices != null && ppi.QuantityPrices.Any() )
1988 {
1989 <h3 class="mb-1 mt-2 small">@Translate( "eCom QuantityPrices - QuantityPricesHeading - Text", "Køb flere og spar" )</h3>
1990
1991 <table class="mb-3 table table-sm">
1992 <thead>
1993 <th style="width: 40%;">@Translate( "eCom QuantityPrices - QuantityPricesNumber - Text", "Antal" )</th>
1994 <th>@Translate( "eCom QuantityPrices - QuantityPricesPrice - Text", "Pris pr. stk" )</th>
1995 <th class="text-right">@Translate( "eCom QuantityPrices - QuantityPricesDiscount - Text", "Rabat" )</th>
1996 </thead>
1997 @foreach ( Co3.DCC.Data.DAL.Models.Price price in ppi.QuantityPrices )
1998 {
1999 <tr>
2000 <td style="width: 40%;">@price.Discount.MinimumQuantity</td>
2001
2002 <td>@Co3.DCC.Dw.Services.ProductService.Instance.GetPriceFormatted( price.PriceAmount )</td>
2003 <td class="text-right text-success">
2004 <strong>@Translate( "eCom QuantityPrices - QuantityPricesDiscountSave - Text", "Spar" ) @price.Discount.LineDiscountPercent%</strong>
2005 </td>
2006
2007 </tr>
2008 }
2009
2010 </table>
2011 }
2012
2013
2014
2015 }
2016 else
2017 {
2018 <br />
2019 <br />
2020 }
2021
2022
2023 <div>
2024 </div>
2025 }
2026
2027 @if ( !isActive )
2028 {
2029 <div class="d-flex justify-content-between align-items-center">
2030 <div>
2031 <span class="dcc-custom-product-details-stockstatus dcc-stockstatus-outofstock">
2032 <small>@Translate( "eCom Product - stock out - Text", "Ikke på lager" )</small>
2033 </span>
2034 @if ( string.IsNullOrEmpty( stockETA ) == false )
2035 {
2036 <br />
2037 <span class="dcc-custom-product-details-stockstatus dcc-stockstatus-eta">
2038 <small>@stockETA</small>
2039 </span>
2040 }
2041 </div>
2042
2043 <button type="button" disabled class="btn btn-secondary"><i class="material-icons">block</i> @Translate( "eCom Product - Inactive - Info Text", "Product is not available" )</button>
2044 </div>
2045
2046 }
2047
2048 @if (!(isExtranet || hasDirectSale) && isActive) {
2049 <div class="dcc-product-details-cart-flex-wrapper">
2050 <div class="dcc-flex-stock">
2051 <div class="dcc-product-list-specifications-stock-message">
2052
2053 @if ( stockCheck )
2054 {
2055 <span class="dcc-custom-product-details-stockstatus dcc-stockstatus-instock">
2056 <small>@stockNumber @Translate( "eCom Product - stock in - Text", "på lager" )</small>
2057 </span>
2058 }
2059 else
2060 {
2061 <span class="dcc-custom-product-details-stockstatus dcc-stockstatus-outofstock">
2062 <small>@Translate( "eCom Product - stock out - Text", "Ikke på lager" )</small>
2063 </span>
2064 }
2065 @if (string.IsNullOrEmpty(GetString("Ecom:Product:Field.RemoteStock")) == false)
2066 {<br>
2067 <span class="dcc-custom-product-details-stockstatus dcc-stockstatus-remotestock">
2068 @{
2069 string translationKey = string.Format("eCom Product - Remote Stock - Status - {0}", GetString("Ecom:Product:Field.RemoteStock"));
2070 }
2071 <small>@Translate(translationKey, GetString("Ecom:Product:Field.RemoteStock"))</small>
2072 </span>
2073 }
2074 @if ( string.IsNullOrEmpty( stockETA ) == false )
2075 {<br>
2076 <span class="dcc-custom-product-details-stockstatus dcc-stockstatus-eta">
2077 <small>@stockETA</small>
2078 </span>
2079 }
2080
2081 </div>
2082
2083 </div>
2084 <div>
2085
2086 </div>
2087 <div class="dcc-flex-addtocart">
2088 <a class="btn btn-block btn-secondary text-muted" href="@Espresso.Area.Item.ExtranetLoginPage">@Translate( "eCom ProductList - ReadMore button - Text", "Læs mere" )</a>
2089 </div>
2090 </div>
2091 }
2092
2093 <div class="d-flex justify-content-end mt-2">
2094 <div class="ml-auto">
2095 @using Dynamicweb.Frontend
@if ( isExtranet && isActive ) {
<div class="dropdown">
<button type="button" class="btn btn-link btn-with-icon dropdown-toggle" data-toggle="dropdown"><span><img class="dcc-custom-icon" src="/Files/Images/dcc/icons/favorite.svg" /></span> @Translate( "eCom Product - Add to favorites - Link", "Add to favorites" )</button>
<div class="dropdown-menu pt-0">
<h4 class="dropdown-header">@Translate( "eCom Product - Add to favorite list - Heading", "Add to ..." )</h4>
<form action="" class="js-e-product-cc-list-form mt-1">
@foreach ( LoopItem listType in GetLoop( "CustomerCenter.ListTypes" ) )
{
foreach ( LoopItem list in listType.GetLoop( "CustomerCenter.ProductLists" ) )
{
<div class="dropdown-item">
<label class="custom-checkbox custom-control m-0">
<input type="checkbox" class="custom-control-input js-e-cc-list" id="js-e-cc-list-@list.GetValue( "Ecom:CustomerCenter.List.ID" )" name="list-@list.GetValue( "Ecom:CustomerCenter.List.ID" )" @( list.GetBoolean( "Ecom:Product.List.IsProductInThisList" ) == true ? "checked" : "" ) data-url-add="@list.GetString( "Ecom:Product.AddToThisListAction" )" data-url-remove="@list.GetString( "Ecom:Product.RemoveFromThisList" )">
<span class="custom-control-indicator"></span>
<span class="custom-control-description">@list.GetValue( "Ecom:CustomerCenter.List.Name" )</span>
</label>
</div>
}
}
</form>
<div class="dropdown-divider"></div>
<a class="dropdown-item" href="@PageView.Current().Area.Item[ "ExtranetListsPage" ]"><i class="material-icons">add</i> @Translate( "eCom Product - Add new favorite list - Link", "Create a new list" )</a>
</div>
</div>
}
2096 </div>
2097 </div>
2098 </div>
2099
2100
2101 </div>
2102 </div>
2103 <div class="col-12 col-md-7 order-first">
2104 <div class="e-product-image-container position-relative">
2105
2106 @using System.Collections.Generic
@using Co3.Espresso.Base.Models
@using Co3.Espresso.Website.Services
@using Dynamicweb.Rendering
@{
var defaultImageLarge = GetString( "Ecom:Product.ImageLarge.Clean" );
bool hasNoImage = string.IsNullOrEmpty( defaultImageLarge ) ? true : false;
if ( hasNoImage == true )
{
defaultImageLarge = "/Files/Templates/Designs/dcc/_assets/img/dcc-noimage.svg";
}
List<dynamic> Carousel = new List<dynamic>();
foreach ( ElementWithIndex< LoopItem > image in GetLoop( "Details" ).WithIndex() )
{
Carousel.Add(new
{
src = image.Element.GetString("Ecom:Product:Detail.Image.Clean"),
index = ( image.Index + 1 )
});
}
}
<div class="e-product-image-container js-e-product-image-container">
<div class="carousel slide" data-interval="false" data-ride="carousel" id="js-e-product-image-carousel">
<div class="e-product-image-wrapper">
<a href="@GetGlobalValue( "Global:Pageview.Url" )#condition">
<span class="dcc-product-details-badge top @conditionClass">
<span class="dcc-product-details-badge-title">@condition</span>
</span>
</a>
<div class="carousel-inner js-dcc-image-carousel-images-container">
<div class="active carousel-item" data-target="#js-e-product-image-modal" data-toggle="modal">
<img src="/admin/public/getimage.ashx?Crop=0&Image=@defaultImageLarge&Format=jpg&Width=600&Height=&Quality=90" alt="@GetString( "Ecom:Product.Name" )" class="e-product-image" data-target="#js-e-product-image-modal-carousel" data-slide-to="0">
</div>
<script id="js-e-handlebars-tmpl-carousel-images" type="text/x-handlebars-template">
<div class="active carousel-item" data-target="#js-e-product-image-modal" data-toggle="modal">
<img src="/admin/public/getimage.ashx?Crop=0&Image={{imageLarge}}&Format=jpg&Width=600&Height=&Quality=90" alt="@GetString( "Ecom:Product.Name" )" class="e-product-image" data-target="#js-e-product-image-modal-carousel" data-slide-to="0">
</div>
{{#each images}}
<div class="carousel-item" data-target="#js-e-product-image-modal" data-toggle="modal">
<img src="/admin/public/getimage.ashx?Crop=0&Image={{src}}&Format=jpg&Width=600&Height=&Quality=90" alt="@GetString( "Ecom:Product.Name" )" class="e-product-image" data-target="#js-e-product-image-modal-carousel" data-slide-to="{{index}}">
</div>
{{/each}}
</script>
<a class="carousel-control-prev" data-slide="prev" data-target="#js-e-product-image-carousel"></a>
<a class="carousel-control-next" data-slide="next" data-target="#js-e-product-image-carousel"></a>
</div>
</div>
<ol class="carousel-indicators js-dcc-image-carousel-thumbs-container">
<script id="js-e-handlebars-tmpl-carousel-thumbs" type="text/x-handlebars-template">
<li class="active" data-slide-to="0" data-target="#js-e-product-image-carousel">
<span class="preload-background-image js-preload-background-image" data-src="/admin/public/getimage.ashx?Crop=0&Image={{imageLarge}}&Format=jpg&Width=50&Height=&Quality=90" role="img" aria-label="@GetString( "Ecom:Product.Name" )" title="@GetString( "Ecom:Product.Name" )"></span>
</li>
{{#each images}}
{{#if src}}
<li data-target="#js-e-product-image-carousel" data-slide-to="{{index}}">
<span class="preload-background-image js-preload-background-image" data-src="/admin/public/getimage.ashx?Crop=0&Image={{src}}&Format=jpg&Width=50&Height=&Quality=75" role="img" aria-label="@GetString( "Ecom:Product.Name" )" title="@GetString( "Ecom:Product.Name" )"></span>
</li>
{{/if}}
{{/each}}
</script>
</ol>
</div>
</div>
<script>
var carouselDataImages = {
imageLarge: "@defaultImageLarge",
images: @JsonService.Instance.ToJson( Carousel )
};
</script>
2107 @if ( ppi != null && ppi.IsCampaignPrice )
2108 {
2109 <div class="dcc-campaign-label dcc-streamer dcc-streamer-detail-view">
2110 <svg height="120px" id="dcc-streamer-svg" viewBox="0 0 199.9 145.2" width="164px" xmlns="http://www.w3.org/2000/svg">
2111 <path class="dcc-streamer-color" d="M0 145.2h73.2l126.7-92V0z" />
2112 @*<path class="dcc-streamer-color-secondary" d="M7.5 139.8H0v5.4zM199.9 0h-7.6v5.5z"/>*@
2113 </svg>
2114 <p>@Translate( "eCom Product - Streamer Campaign - Heading", "Kampagne" )</p>
2115 </div>
2116 }
2117 else if ( outlet )
2118 {
2119 <div class="dcc-campaign-label dcc-streamer dcc-streamer-detail-view">
2120 <svg height="120px" id="dcc-streamer-svg" viewBox="0 0 199.9 145.2" width="164px" xmlns="http://www.w3.org/2000/svg">
2121 <path class="dcc-streamer-color" d="M0 145.2h73.2l126.7-92V0z" />
2122 @*<path class="dcc-streamer-color-secondary" d="M7.5 139.8H0v5.4zM199.9 0h-7.6v5.5z"/>*@
2123 </svg>
2124 <p>@Translate( "eCom Product - Streamer Outlet - Heading", "Outlet" )</p>
2125 </div>
2126 }
2127 </div>
2128 <div class="modal modal-fullscreen fade e-product-image-modal" id="js-e-product-image-modal" data-backdrop="false" data-keyboard="true">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-body">
<button type="button" class="close" data-dismiss="modal">
<i class="material-icons">close</i>
</button>
<div id="js-e-product-image-modal-carousel" class="carousel slide" data-keyboard="true" data-interval="false">
<div class="carousel-inner js-dcc-image-carousel-modal-images-container">
<script id="js-e-handlebars-tmpl-carousel-modal-images" type="text/x-handlebars-template">
<div class="carousel-item active" style="background-image: url(/admin/public/getimage.ashx?Crop=0&Image={{imageLarge}}&Format=jpg&Width=&Height=1800&Quality=90)" role="img" aria-label="@GetString( "Ecom:Product.Name" )" title="@GetString( "Ecom:Product.Name" )">
</div>
{{#each images}}
<div class="carousel-item" style="background-image: url(/admin/public/getimage.ashx?Crop=0&Image={{src}}&Format=jpg&Width=&Height=1800&Quality=90)" role="img" aria-label="@GetString( "Ecom:Product.Name" )" title="@GetString( "Ecom:Product.Name" )">
</div>
{{/each}}
</script>
</div>
<ol class="carousel-indicators js-dcc-image-carousel-modal-thumbs-container">
<script id="js-e-handlebars-tmpl-carousel-modal-thumbs" type="text/x-handlebars-template">
<li data-target="#js-e-product-image-modal-carousel" data-slide-to="0" class="active">
<span class="preload-background-image" style="background-image: url(/admin/public/getimage.ashx?Crop=0&Image={{imageLarge}}&Format=jpg&Width=50&Height=&Quality=90)" role="img" aria-label="@GetString( "Ecom:Product.Name" )" title="@GetString( "Ecom:Product.Name" )"></span>
</li>
{{#each images}}
{{#if src}}
<li data-target="#js-e-product-image-modal-carousel" data-slide-to="{{index}}">
<span class="preload-background-image" style="background-image: url(/admin/public/getimage.ashx?Crop=0&Image={{src}}&Format=jpg&Width=50&Height=&Quality=75)" role="img" aria-label="@GetString( "Ecom:Product.Name" )" title="@GetString( "Ecom:Product.Name" )"></span>
</li>
{{/if}}
{{/each}}
</script>
</ol>
<a class="carousel-control-prev" data-target="#js-e-product-image-modal-carousel" data-slide="prev"></a>
<a class="carousel-control-next" data-target="#js-e-product-image-modal-carousel" data-slide="next"></a>
</div>
</div>
</div>
</div>
</div>
2129 </div>
2130
2131 @sectionEnd()
2132
2133 @sectionStart(
2134 sectionClasses: "e-section pt-1 pb-4",
2135 sectionCollapse: false,
2136 contentClasses: "col-12 mx-auto"
2137 )
2138
2139 @{
2140 bool configurationShow = (
2141 hasPrice &&
2142 isActive &&
2143 (isExtranet || hasDirectSale) &&
2144 ((isConfigurable && IsConfiguratorActive()) ||
2145 warrantyRelatedProductCollection.Any())
2146 );
2147 }
2148
2149 <div class="col-12 dcc-product-tabs">
2150 <ul class="nav nav-tabs" role="tablist">
@if ( hasRelated )
{
<li class="nav-item" role="presentation">
<a class="nav-link js-dcc-productpage-tab @(!configurationShow ? "active" : string.Empty)" id="dcc-productpage-tab-accessories" data-toggle="tab" href="#dcc-productpage-tab-content-accessories" aria-controls="dcc-productpage-tab-content-accessories" aria-selected="true">
<h2 class="m-0 px-1 small">@Translate( "eCom Product - Tilbehør - Tab", "Tilbehør" )</h2>
</a>
</li>
}
<li class="nav-item" role="presentation">
<a class="nav-link js-dcc-productpage-tab @( (!configurationShow && !hasRelated) ? "active" : string.Empty)" id="dcc-productpage-tab-specs" data-toggle="tab" href="#dcc-productpage-tab-content-specs" aria-controls="dcc-productpage-tab-content-specs">
<h2 class="m-0 px-1 small">@Translate( "eCom Product - Specifications - Tab", "Specifikationer" )</h2>
</a>
</li>
@if ( configurationShow )
{
<li class="nav-item" role="presentation">
<a class="nav-link js-dcc-productpage-tab @(configurationShow ? "active" : string.Empty)" id="dcc-productpage-tab-config" data-toggle="tab" href="#dcc-productpage-tab-content-config" aria-controls="dcc-productpage-tab-content-config">
<h2 class="m-0 px-1 small">@Translate( "eCom Product - Configuration - Tab", "Tilpas produkt" )</h2>
</a>
</li>
}
</ul>
2151 <div class="tab-content">
2152 <div class="tab-pane fade @(!configurationShow ? "active show" : string.Empty)" id="dcc-productpage-tab-content-accessories" role="tabpanel" aria-labelledby="dcc-productpage-tab-accessories">
2153 @using System.Collections.Generic
2154 @using Dynamicweb.Ecommerce.Products
2155
2156 @if ( relatedGroups != null && productObject.RelatedGroups.Any() )
2157 {
2158 @sectionStart(
2159 sectionClasses: "e-section dcc-section-related-products p-2 bg-white js-dcc-section-related-products",
2160 sectionCollapse: true,
2161 collapsetoggleHidden: true,
2162 collapseToggleTextExpand: Translate("Related Products - Toggle - Expand"),
2163 collapseToggleTextCollapse: Translate("Related Products - Toggle - Collapse"),
2164 contentClasses: "col-12 mx-auto show"
2165 )
2166 <div class="js-dcc-configurator-cart-related-products-container pt-0 pb-4 w-100">
2167 <div class="e-loading-overlay is-loading" style="background: none; height: 10em; position: relative">
2168 <div class="e-loading-spinner"></div>
2169 </div>
2170 <script id="js-e-handlebars-tmpl-configurator-cart-related-products" type="text/x-handlebars-template">
2171 <div class="row">
2172 <div class="col-12">
2173 {{#each relatedGroups}}
2174 <div class="bg-white border-0 card mt-1 shadow-none">
2175 <div class="card-header px-2 py-1" id="cart-related-parts-{{id}}-header">
2176 <h3 aria-controls="cart-related-parts-{{id}}-collapse" aria-expanded="false" class="border-0 m-0 cart-related-parts-header" data-target="#cart-related-parts-{{id}}-collapse" data-toggle="collapse">
2177 {{name}}
2178 </h3>
2179 </div>
2180 </div>
2181 <div aria-labelledby="cart-related-parts-{{id}}-header" class="dcc-productlist-presentation-list collapse" id="cart-related-parts-{{id}}-collapse">
2182 <div class="bg-white card-body px-0 py-0 e-products">
2183 {{#each products}}
2184 {{> configuratorCartRelatedProduct this}}
2185 {{/each}}
2186
2187 </div>
2188 </div>
2189 {{/each}}
2190 </div>
2191 </div>
2192 </script>
2193 </div>
2194 @sectionEnd()
2195 }
2196
2197
2198 <script id="js-e-handlebars-partial-configurator-cart-related-product" type="text/x-handlebars-template">
2199 <div class="col-12 col-sm-12 col-md-6 col-lg-3 col-xl-3 px-0">
2200 <div class="border-bottom e-products-item js-e-products-item">
2201 <div class="e-products-item-container">
2202 <div class="e-products-item-image-container">
2203 <a class="e-block-link e-products-item-image-wrapper js-e-block-link" href="{{url}}">
2204 <img alt="" class="e-products-item-image" src="{{image}}">
2205 </a>
2206 {{#if isCampaign}}
2207 <a class="e-block-link" href="{{url}}">
2208 <div class="dcc-campaign-label dcc-streamer">
2209 <svg height="120px" id="dcc-streamer-svg" viewBox="0 0 199.9 145.2" width="164px" xmlns="http://www.w3.org/2000/svg">
2210 <path class="dcc-streamer-color" d="M0 145.2h73.2l126.7-92V0z" />
2211 </svg>
2212 <p>@Translate( "eCom Product - Streamer Campaign - Heading", "Kampagne" )</p>
2213 </div>
2214 </a>
2215 {{/if}}
2216 {{#compare_extended isCampaign '!==' "True"}}
2217 {{#if isOutlet}}
2218 <a class="e-block-link" href="{{url}}">
2219 <div class="dcc-campaign-label dcc-streamer">
2220 <svg height="120px" id="dcc-streamer-svg" viewBox="0 0 199.9 145.2" width="164px" xmlns="http://www.w3.org/2000/svg">
2221 <path class="dcc-streamer-color" d="M0 145.2h73.2l126.7-92V0z" />
2222 </svg>
2223 <p>@Translate( "eCom Product - Streamer Outlet - Heading", "Outlet" )</p>
2224 </div>
2225 </a>
2226 {{/if}}
2227 {{/compare_extended}}
2228
2229 {{#compare condition '!==' ""}}
2230 <a class="e-block-link" href="{{url}}">
2231 <span class="{{conditionClass}} dcc-product-list-badge">
2232 <span class="dcc-product-list-badge-title">
2233 {{condition}}
2234 </span>
2235 </span>
2236 </a>
2237 {{/compare}}
2238 </div>
2239
2240 <div class="e-block-link e-products-item-text-container js-e-block-link small">
2241
2242 <div class="dcc-products-item-list-heading">
2243 <h3 class="e-products-item-name mb-0">
2244 <a href="{{url}}">{{shortDescription}}</a>
2245 </h3>
2246 <p class="hidden-grid mb-0 small text-muted">@Translate( "eCom Product - Product Number - Text", "Number" ) {{number}}</p>
2247 </div>
2248 <div class="dcc-product-list-specifications-unordered-list">
2249 @* NOTEBOOK *@
2250 {{#compare mainCategory '===' "NOTEBOOK"}}
2251 <div class="attribute-field-wrapper productlist-view">
2252 {{#each categoryFieldsNotebook}}
2253 <div class="attribute-field-header">{{this.header}}</div>
2254 <div class="attribute-field-value">{{this.value}}</div>
2255 {{/each}}
2256 </div>
2257 {{/compare}}
2258
2259 @* PC *@
2260 {{#compare mainCategory '===' "PC"}}
2261 <div class="attribute-field-wrapper productlist-view">
2262 {{#each categoryFieldsPc}}
2263 <div class="attribute-field-header">{{this.header}}</div>
2264 <div class="attribute-field-value">{{this.value}}</div>
2265 {{/each}}
2266 </div>
2267 {{/compare}}
2268
2269 @* SERVER *@
2270 {{#compare mainCategory '===' "SERVER"}}
2271 <div class="attribute-field-wrapper productlist-view">
2272 {{#each categoryFieldsServer}}
2273 <div class="attribute-field-header">{{this.header}}</div>
2274 <div class="attribute-field-value">{{this.value}}</div>
2275 {{/each}}
2276 </div>
2277 {{/compare}}
2278
2279 @* STORAGE *@
2280 {{#compare mainCategory '===' "STORAGE"}}
2281 <div class="attribute-field-wrapper productlist-view">
2282 {{#each categoryFieldsStorage}}
2283 <div class="attribute-field-header">{{this.header}}</div>
2284 <div class="attribute-field-value">{{this.value}}</div>
2285 {{/each}}
2286 </div>
2287 {{/compare}}
2288
2289 @* MONITOR *@
2290 {{#compare mainCategory '===' "MONITOR"}}
2291 <div class="attribute-field-wrapper productlist-view">
2292 {{#each categoryFieldsMonitor}}
2293 <div class="attribute-field-header">{{this.header}}</div>
2294 <div class="attribute-field-value">{{this.value}}</div>
2295 {{/each}}
2296 </div>
2297 {{/compare}}
2298
2299 @* STANDARD FALLBACK*@
2300 {{#compare_extended mainCategory '!==' "NOTEBOOK,PC,SERVER,STORAGE,MONITOR"}}
2301 <div class="attribute-field-wrapper productlist-view">
2302 <div class="dcc-simple-desc">{{simpleDesc}}</div>
2303 </div>
2304 {{/compare_extended}}
2305 </div>
2306 </div>
2307
2308
2309
2310
2311
2312
2313 <div class="e-products-item-buy-container">
2314 <div class="dcc-price-setup">
2315 <div class="d-flex justify-content-end">
2316 <div class="">
2317 {{#compare isUserAuthenticated '||' hasDirectSale}}
2318 {{#if isActive}}
2319 <div class="dcc-flex-price d-flex my-flex-container-column mr-1 h-100">
2320 {{#compare isCallForPrice '||' isNoPrice}}
2321 <button class="btn btn-block btn-call btn-secondary" data-target="#callForPrice-{{id}}" data-toggle="modal">
2322 <i class="material-icons">phone</i> @Translate( "eCom Product - callforprice - Text", "Ring for pris" )
2323 </button>
2324 {{else}}
2325 <span class="dcc-product-list-specifications-price">{{{price}}}</span>
2326
2327 {{/compare}}
2328 </div>
2329 {{/if}}
2330 {{/compare}}
2331 </div>
2332 <div class="d-flex flex-column" style="width: 44%;">
2333
2334
2335
2336 <div class="dcc-flex-stock ml-auto mb-1">
2337 <div class="dcc-product-list-specifications-stock-message">
2338 {{#if isActive}}
2339 {{#if stockCheck}}
2340 <span class="dcc-custom-productlist-stockstatus dcc-stockstatus-instock">
2341 <small>{{stock}} @Translate( "eCom Product - stock in - Text", "på lager" )</small>
2342 </span>
2343 {{else}}
2344 <span class="dcc-custom-productlist-stockstatus dcc-stockstatus-outofstock">
2345 <small>@Translate( "eCom Product - stock out - Text", "Ikke på lager" )</small>
2346 </span>
2347 {{/if}}
2348 {{/if}}
2349 </div>
2350 </div>
2351 <div class="dcc-bottom-flex-wrapper">
2352
2353
2354 {{#compare isUserAuthenticated '||' hasDirectSale}}
2355 <div class="dcc-flex-addtocart">
2356 <div class="dcc-product-list-specifications-form-wrapper">
2357 {{#if isActive}}
2358 {{#if isCallForPrice}}
2359 <button class="btn btn-block btn-call btn-secondary" data-target="#callForPrice-{{id}}" data-toggle="modal">
2360 <i class="material-icons">phone</i> @Translate( "eCom Product - callforprice - Text", "Ring for pris" )
2361 </button>
2362 {{else}}
2363 <form action="/system/data/cart" class="e-product-form js-e-product-form" method="post">
2364 <input name="CartCmd" type="hidden" value="Add">
2365 <input type="hidden" name="ProductID" value="{{id}}">
2366 <input name="VariantID" type="hidden" value="">
2367 <input name="UnitID" type="hidden" value="">
2368 <input name="Redirect" type="hidden" value="">
2369 <input type="hidden" value="false" name="EcomOrderLineFieldInput_IsConfigurable" />
2370 <div class="dcc-product-list-add-to-cart-wrapper">
2371 <input name="Quantity" type="number" value="1" autocomplete="off">
2372 <button class="btn btn-primary" type="submit">@Translate( "eCom Product - Add To Cart - Button", "Add to cart" )</button>
2373 </div>
2374 </form>
2375 {{/if}}
2376 {{else}}
2377 <a class="btn btn-block btn-secondary" href="{{url}}">
2378 <i class="material-icons">not_interested</i> @Translate( "eCom ProductList - NotforSale button - Text", "Varen er udgået" )</a>
2379 {{/if}}
2380 </div>
2381 </div>
2382 {{else}}
2383 {{#if isActive}}
2384 <div class="dcc-flex-addtocart text-right">
2385 <a class="btn btn-secondary text-muted" href="{{url}}">@Translate( "eCom ProductList - ReadMore button - Text", "Læs mere" )</a>
2386 </div>
2387 {{else}}
2388 <a class="btn btn-block btn-secondary" href="{{url}}">
2389 <i class="material-icons">not_interested</i> @Translate( "eCom ProductList - NotforSale button - Text", "Varen er udgået" )</a>
2390 {{/if}}
2391
2392 {{/compare}}
2393 </div>
2394 </div>
2395 </div>
2396 </div>
2397
2398
2399 <div class="d-flex mt-1">
2400
2401 {{#if isActive}}
2402 {{#if isConfigurable}}
2403 <div class="small">
2404 <a class="btn btn-link btn-with-icon js-dcc-configurator-open " href="{{url}}#/state=configuration/"><span><img class="dcc-custom-icon" src="/Files/Images/dcc/icons/configuration.svg" /></span> @Translate( "DCC - Configurator - List - Configur - Text", "Tilpas produkt" )</a>
2405 </div>
2406 {{/if}}
2407 {{/if}}
2408
2409 {{#if isUserAuthenticated}}
2410 {{#if isActive}}
2411 <div class="small ml-auto">
2412 <div class="dcc-product-list-item-add-to-favorites dropdown ">
2413 <button type="button" class="btn btn-link btn-with-icon dropdown-toggle ml-auto" data-toggle="dropdown"><span><img class="dcc-custom-icon" src="/Files/Images/dcc/icons/favorite.svg" /></span> @Translate( "eCom Product - Add to favorites - Link", "Add to favorites" )</button>
2414 <div class="dropdown-menu pt-0">
2415 <h3 class="dropdown-header">@Translate( "eCom Product - Add to favorite list - Heading", "Add to ..." )</h3>
2416 <form action="" class="js-e-product-cc-list-form mt-1">
2417 {{#each favoriteLists}}
2418 <div class="dropdown-item">
2419 <label class="custom-checkbox custom-control m-0">
2420 <input type="checkbox" class="custom-control-input js-e-cc-list" id="js-e-cc-list-{{../id}}-{{id}}" name="list-{{id}}" {{#if isProductInThisList}}checked{{/if}} data-url-add="{{urlAdd}}" data-url-remove="{{urlRemove}}">
2421 <span class="custom-control-indicator"></span>
2422 <span class="custom-control-description">{{name}}</span>
2423 </label>
2424 </div>
2425 {{/each}}
2426 </form>
2427 <div class="dropdown-divider"></div>
2428 <a class="dropdown-item" href="@PageView.Current().Area.Item[ "ExtranetListsPage" ]">
2429 <i class="material-icons">add</i> @Translate( "eCom Product - Add new favorite list - Link", "Create a new list" )</a>
2430 </div>
2431 </div>
2432 </div>
2433 {{/if}}
2434 {{/if}}
2435 </div>
2436 </div>
2437 </div>
2438 </div>
2439 </div>
2440
2441
2442 </script>
2443
2444 </div>
2445
2446 <div class="tab-pane fade @((!configurationShow && !hasRelated) ? "active show" : string.Empty ) " id="dcc-productpage-tab-content-specs" role="tabpanel" aria-labelledby="dcc-productpage-tab-specs">
2447 @if ( specificationCategory.Any() == true || ( PIMspecificationCategory != null && PIMspecificationCategory.FieldValues != null ) )
2448 {
2449
2450
2451
2452 @sectionStart(
2453 sectionClasses: "e-section pt-4 pb-3",
2454 sectionCollapse: false,
2455 contentClasses: "col-12",
2456 collapseToggleTextExpand: Translate( "eCom Product - View more - Text", "View more" ),
2457 collapseToggleTextCollapse: Translate( "eCom Product - View less - Text", "View less" )
2458 )
2459 <div class="col-12">
2460 <h3 class="font-weight-normal mb-2">@Translate( "eCom Product - Specifications - Text", "Native product specifications. The product description originates from Cnet. DCC accepts no responsibility for error or misinformation in product descriptions from Cnet." )</h3>
2461
2462 @if ( PIMspecificationCategory != null && PIMspecificationCategory.FieldValues.Any() )
2463 {
2464 <p class="mb-1">
2465 <strong class="font-headings">@Translate( String.Format( "productCategory_Render_Label_{0}", PIMspecificationCategory.Name ), PIMspecificationCategory.Name )</strong>
2466 </p>
2467
2468 <table class="dcc-product-detail-specifications-table mb-5 table">
2469 @if (PIMspecificationCategory.FieldValues != null)
2470 {
2471
2472 foreach ( SpecificationField sf in PIMspecificationCategory.FieldValues )
2473 {
2474 <tr style="line-height: 1.2;">
2475 @if ( string.IsNullOrEmpty( sf.Value ) == false )
2476 {
2477 <td class="dcc-product-detail-specifications-table-title" style="width: 50%">
2478 <small>@sf.Name</small>
2479 </td>
2480 <td class="dcc-product-detail-specifications-table-value" style="width: 50%">@sf.Value.Replace( "U0022", "\"" )</td>
2481 }
2482 </tr>
2483 }
2484 }
2485 </table>
2486 }
2487
2488 @if ( specificationCategory != null )
2489 {
2490 foreach ( SpecificationCategory sc in specificationCategory )
2491 {
2492 if ( sc.FieldValues != null && sc.FieldValues.Any() )
2493 {
2494 <p class="mb-1">
2495 <strong class="font-headings">@Translate( String.Format( "productCategory_Render_Label_{0}", sc.Name ), sc.Name )</strong>
2496 </p>
2497
2498 <table class="dcc-product-detail-specifications-table mb-5 table">
2499 @foreach ( SpecificationField sf in sc.FieldValues )
2500 {
2501 <tr style="line-height: 1.2;">
2502 @if ( string.IsNullOrEmpty( sf.Value ) == false )
2503 {
2504 <td class="dcc-product-detail-specifications-table-title" style="width: 50%">
2505 <small>@sf.Name</small>
2506 </td>
2507 <td class="dcc-product-detail-specifications-table-value" style="width: 50%">@sf.Value.Replace( "U0022", "\"" )</td>
2508 }
2509 </tr>
2510 }
2511 </table>
2512 }
2513 }
2514 }
2515
2516
2517 </div>
2518
2519 @sectionEnd()
2520 }
2521
2522 </div>
2523 @if ( configurationShow )
2524 {
2525 <div class="tab-pane fade @(configurationShow ? "active show" : string.Empty)" id="dcc-productpage-tab-content-config" role="tabpanel" aria-labelledby="dcc-productpage-tab-config">
2526 @{
dynamic configuratorSettings = new
{
listWidths = "col-12 col-lg-8",
overviewWidths = "col-12 col-lg-4"
};
}
@sectionStart(
sectionClasses: "e-section bg-white dcc-configurator-section dcc-configurator-total-collapse js-dcc-configurator-section",
sectionCollapse: false,
contentClasses: "col-12",
collapseToggleTextExpand: Translate( "eCom Product - View more - Text", "View more" ),
collapseToggleTextCollapse: Translate( "eCom Product - View less - Text", "View less" )
)
<div id="dcc-configurator-section" class="col-12 py-4 border-bottom">
<div class="row">
<div class="@configuratorSettings.listWidths">
@using Dynamicweb.SystemTools
@{
string isLockedText = Translate("DCC - Configurator - List - Locked Group - Text", "Built-in / Unchangeable");
}
<div class="row">
<div class="col-12">
<div class="tab-content" id="dcc-configurator-tabs">
<div aria-labelledby="dcc-configurator-parts-tab" class="active fade show tab-pane" id="dcc-configurator-home-tab-content" role="tabpanel">
<div class="js-dcc-configurator-parts">
<script id="js-e-handlebars-tmpl-configurator-parts" type="text/x-handlebars-template">
{{#each configurables}}
<div class="js-dcc-configurator-category dcc-configurator-category mb-2 {{#compare @@key '===' 'oslanguage'}}{{#compare isOSConfigurable '===' 'no'}}is-hidden{{/compare}}{{/compare}} " data-category="{{@@key}}" id="category-parts-{{@@key}}" data-slot="{{this.slot}}" data-edit-slot="{{this.editableName}}">
<div class="row">
<div class="col-12" id="category-parts-{{@@key}}-header">
<h3 class="category-parts-header {{#if isLocked}}lock-icon{{/if}}" data-toggle="collapse" data-target="#category-parts-{{@@key}}-collapse" aria-expanded="true" aria-controls="category-parts-{{@@key}}-collapse">
<span class="category-parts-header-label" {{#if isLocked}}alt="@isLockedText" title="@isLockedText"{{/if}}>{{this.label}}</span>
<span class="ml-auto pr-2">@currencyCode @Translate( "eCom - Product Price - Ex. VAT - Text" )</span>
</h3>
</div>
<div id="category-parts-{{@@key}}-collapse" class="col-12 collapse show {{#if isLocked}}is-locked{{/if}}" aria-labelledby="category-parts-{{@@key}}-header">
{{#each this.parts}}
{{#filterConfigurationParts this @@../key}}
<div class="dcc-configurator-category-item js-dcc-configurator-category-item form-check my-0 px-2">
<div class="py-0">
{{#compare ../this.hasLanguages '|!' basicKeyboard}}
<input data-test="!basicKeyboard" class="dcc-configurator-part-input form-check-input js-dcc-configurator-part-input js-dcc-configurator-part-input-language" name="{{@@../key}}{{@@../index}}" type="{{inputType}}" value="{{id}}" {{#if isDefault}}checked{{/if}}
data-category="{{@@../key}}"
data-default-language="{{defaultLanguage}}"
data-language="{{../this.hasLanguages}}"
data-id="{{id}}" id="{{@@../key}}"
{{#compare itemNameSplit '===' 'MEMORY' }}
data-ram="{{configurationValue}}"
data-max-ram-supported="{{partConfigurationGroup.SupportPrices.SupportMaxRAMSupported}}"
{{/compare}}
{{#if isDefault}}data-default-configuration="{{id}}"{{/if}}
>
{{else}}
<input data-test="+basicKeyboard" class="dcc-configurator-part-input form-check-input js-dcc-configurator-part-input {{#if ../this.hasLanguages}}js-dcc-configurator-part-input-none{{/if}}" name="{{@@../key}}{{@@../index}}" type="{{inputType}}" value="{{#if ../this.hasLanguages}}PROD1{{else}}{{id}}{{/if}}" {{#if isDefault}}checked{{/if}}
data-category="{{@@../key}}"
data-default-language="{{defaultLanguage}}"
data-language="{{../this.hasLanguages}}"
data-id="{{#if ../this.hasLanguages}}PROD1{{else}}{{id}}{{/if}}" id="{{@@../key}}{{@@index}}"
{{#compare itemNameSplit '===' 'MEMORY' }}
data-ram="{{configurationValue}}"
data-max-ram-supported="{{partConfigurationGroup.SupportPrices.SupportMaxRAMSupported}}"
{{/compare}}
{{#if isDefault}}data-default-configuration="{{#if ../this.hasLanguages}}PROD1{{else}}{{id}}{{/if}}"{{/if}}
>
{{/compare}}
<label class="align-items-center d-flex form-check-label justify-content-between px-0 py-1" for="{{@@../key}}{{@@index}}">
<div class="w-50">
{{#compare @@../key '===' 'keyboardsinternal'}}
{{#compare ../this.hasLanguages '&&' basicKeyboard}}
{{defaultLanguage}}
{{else}}
{{#compare ../this.hasLanguages '|!' basicKeyboard}}
@Translate("DCC - Configurator - List - Keyboard Language - Other - Label", "Other / please select language")
{{else}}
{{label}}
{{/compare}}
{{/compare}}
{{/compare}}
{{#compare @@../key '===' 'oslanguage'}}
{{#compare number '===' 'OSLOther'}}
@Translate("DCC - Configurator - List - Os Language - Other - Label", "Other / please write language")
{{else}}
{{label}}
{{/compare}}
{{/compare}}
{{#compare_extended @@../key '!==' 'oslanguage,keyboardsinternal'}}
{{label}}
{{/compare_extended}}
</div>
{{#compare @@../key '===' 'keyboardsinternal'}}
{{#compare ../this.hasLanguages '|!' basicKeyboard}}
<div class="w-lg-25">
<select class="dcc-configurator-part-select custom-select js-dcc-configurator-category-item-language-select" data-prop="{{@@../key}}.{{@@key}}">
{{#filterKeyboardLanguages languages}}
{{#if isDefault}}
<option value="PROD1" selected class="js-dcc-is-default-keyboard-language" data-lang="{{keyboardLang}}" data-price-diff="{{priceDiff}}">
@Translate("DCC - Configurator - List - Keyboardlanguage - Default - Text", "Basic")
</option>
{{else}}
<option value="{{id}}" data-lang="{{keyboardLang}}" data-price-diff="{{priceDiff}}">
{{keyboardLangTranslated}}
</option>
{{/if}}
{{/filterKeyboardLanguages}}
</select>
</div>
<div class="ml-auto">
<span class="badge dcc-configurator-part-price-diff js-dcc-configurator-part-keyboard-price-diff">
+{{getKeyboardDiffPrice languages}}
</span>
</div>
{{else}}
<div class="ml-auto">
<span class="badge dcc-configurator-part-price-diff js-dcc-configurator-part-price-diff {{#if isDefault}}js-dcc-configurator-part-diff-default dcc-configurator-part-diff-default{{/if}}">{{#if isDefault}}@Translate("DCC - Configurator - List - Default - Text", "Basic"){{/if}}</span>
</div>
{{/compare}}
{{/compare}}
{{#compare @@../key '===' 'oslanguage'}}
{{#compare number '===' 'OSLOther'}}
<div class="w-lg-25">
<div class="form-group mb-0">
<input type="text" class="form-control js-dcc-configurator-input-os-language" name="OSLanguageCustom" placeholder="@Translate("DCC - Configurator - List - Os Language - Input - Placeholder", "e.g. Slovak")" onfocus="this.placeholder = ''" onblur="this.placeholder = '@Translate("DCC - Configurator - List - Os Language - Input - Placeholder", "e.g. Slovak")'">
</div>
</div>
<div class="ml-auto">
<span class="badge dcc-configurator-part-price-diff js-dcc-configurator-part-price-diff"></span>
</div>
{{else}}
<div class="ml-auto">
<span class="badge dcc-configurator-part-price-diff js-dcc-configurator-part-price-diff {{#if isDefault}}js-dcc-configurator-part-diff-default dcc-configurator-part-diff-default{{/if}}">{{#if isDefault}}@Translate("DCC - Configurator - List - Default - Text", "Basic"){{/if}}</span>
</div>
{{/compare}}
{{/compare}}
{{#compare_extended @@../key '!==' 'oslanguage,keyboardsinternal'}}
<div class="ml-auto">
<span class="badge dcc-configurator-part-price-diff js-dcc-configurator-part-price-diff {{#if isDefault}}js-dcc-configurator-part-diff-default dcc-configurator-part-diff-default{{/if}}">{{#if isDefault}}@Translate("DCC - Configurator - List - Default - Text", "Basic"){{/if}}</span>
</div>
{{/compare_extended}}
</label>
</div>
</div>
{{/filterConfigurationParts}}
{{/each}}
</div>
</div>
</div>
</div>
{{/each}}
{{#if warrantyRelatedProducts}}
<div class="card shadow-none border-0 bg-light dcc-warrenty-container">
<div class="card-header pb-1 pt-0 px-0 border-bottom bg-white" id="warrantyCollapseHeader">
<h3 class="mb-0">
<a class="d-flex p-0 collapse-header" data-toggle="collapse" data-target="#warrantyCollapse" aria-expanded="true" aria-controls="warrantyCollapse">
<span class="collapse-text font-weight-bold">@Translate( "DCC - Configurator - Overview - Warranty - Header", "Udvidet garanti" )</span>
<span class="ml-auto pr-2">@Context.Currency.Code @Translate( "eCom - Product Price - Ex. VAT - Text" )</span>
</a>
</h3>
</div>
<div id="warrantyCollapse" class="js-dcc-configurator-overview-warranty-collapse collapse show" aria-labelledby="warrantyCollapseHeader">
<div class="card-body py-1 bg-white p-0">
<input type="hidden" class="js-dcc-configurator-overview-warranty-orderline-field" value="@productId" />
{{#each warrantyRelatedProducts}}
<div class="dcc-configurator-category-item form-check my-0 px-2">
<input type="radio" class="dcc-configurator-part-input form-check-input js-dcc-configurator-overview-warranty-input" id="warranty{{@@index}}" name="warranty" value="{{id}}" data-price="{{intPrice}}" {{#if ../warranty.selectedValue}}{{#compare ../warranty.selectedValue '===' id}}checked{{/compare}}{{else}}{{#compare @@index '===' 0}}checked{{/compare}}{{/if}} >
<label class="align-items-center d-flex form-check-label justify-content-between px-0 py-1" for="warranty{{@@index}}">
<div class="w-50">
{{name}}
</div>
<div class="ml-auto">
<span class="badge dcc-configurator-part-price-diff dcc-configurator-part-diff-default">{{#if intPrice}}{{{strPrice}}}{{else}}@Translate("DCC - Configurator - List - Default - Text", "Basic"){{/if}}</span>
</div>
</label>
</div>
{{/each}}
</div>
</div>
</div>
{{/if}}
</script>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="@configuratorSettings.overviewWidths ">
<div class="sticky-overview">
<div class="dcc-configurator-overview js-dcc-configurator-overview bg-white">
2527 @*
2528 <a class="close js-dcc-configurator-overview-mobile-handle p-1 d-block d-lg-none"><i class="material-icons">close</i></a>
2529 *@
2530 <form action="/shop/cart" class="js-dcc-configurator-configuration-form" method="post">
2531
2532 <div class="js-dcc-configurator-overview-container ">
2533 <script id="js-e-handlebars-tmpl-configurator-overview" type="text/x-handlebars-template">
2534 <div class="dcc-configurator-overview-price mt-0 bg-light">
2535 <div class="dcc-configurator-overview-price-base bg-light py-1 px-2 d-flex justify-content-between border-bottom" >
2536 <span>
2537 <h5 class="m-0 dcc-configurator-overview-price-lg">@Translate( "DCC - Configurator - Overview - Total Price", "Pris inkl. tilpasning" )</h5>
2538 </span>
2539 <span>
2540 <h5 class="m-0 dcc-configurator-overview-price-lg">@Context.Currency.Code @Translate( "eCom - Product Price - Ex. VAT - Text" )</h5>
2541 </span>
2542 </div>
2543 {{#if hasBeforePrice}}
2544 <div class="dcc-configurator-overview-price-base bg-light py-1 px-2 d-flex justify-content-between border-bottom" >
2545 <span>
2546 <h5 class="m-0 text-muted">@Translate( "DCC - Configurator - Overview - Base Price", "Basis" )</h5>
2547 </span>
2548 <span>
2549 <h5 class="m-0 text-muted text-line-through">{{{baseBeforePrice}}}</h5>
2550 </span>
2551 </div>
2552 <div class="dcc-configurator-overview-price-base bg-light py-1 px-2 d-flex justify-content-between border-bottom" >
2553 <span>
2554 <h5 class="m-0 text-muted dcc-configurator-overview-price-lg">@Translate( "DCC - Configurator - Overview - Discount Price", "Tilbudspris" )</h5>
2555 </span>
2556 <span>
2557 <h5 class="m-0 text-muted dcc-configurator-overview-price-lg">{{{basePrice}}}</h5>
2558 </span>
2559 </div>
2560 {{else}}
2561 <div class="dcc-configurator-overview-price-base bg-light py-1 px-2 d-flex justify-content-between border-bottom">
2562 <span>
2563 <h5 class="m-0 text-muted">@Translate( "DCC - Configurator - Overview - Base Price", "Basis" )</h5>
2564 </span>
2565 <span>
2566 <h5 class="m-0 text-muted">{{{basePrice}}}</h5>
2567 </span>
2568 </div>
2569 {{/if}}
2570 {{#hasCategories categories}}
2571 <div class="dcc-configurator-overview-price-base bg-light py-1 px-2 border-bottom" >
2572 {{#each categories}}
2573 {{#isNotDefaultPartInCategory this}}
2574 <p class="mb-0 small">
2575 <strong>{{label}}</strong>
2576 </p>
2577 <ul class="list-group list-group-flush m-0 p-0">
2578 {{#each parts}}
2579 <li class="list-group-item bg-light border-0 small m-0 p-0">
2580 <div class="container">
2581 <div class="row">
2582 <div class="col-8">
2583 <h5 class="text-ellipsis text-muted">
2584 {{#compare @@../key '===' 'keyboardsinternal'}}
2585 {{keyboardLang}}
2586 {{else}}
2587 {{#compare number '===' 'OSLOther'}}
2588 <span class="js-dcc-configurator-overview-custom-os-language-label">{{getCustomOsLanguagePartName partOsLanguage}}</span>
2589 {{else}}
2590 {{label}}
2591 {{/compare}}
2592
2593 {{/compare}}
2594 </h5>
2595 </div>
2596 <div class="col-4 pr-0 text-right">
2597 <h5 class="text-muted">
2598 {{#if isDefault}}
2599 @Translate("DCC - Configurator - List - Default - Text", "Basic")
2600 {{else}}
2601 {{#compare price '>' 0}}+{{/compare}}{{{priceFormatted}}}
2602 {{/if}}
2603 </h5>
2604 </div>
2605 </div>
2606 </div>
2607 </li>
2608 {{/each}}
2609 </ul>
2610 {{/isNotDefaultPartInCategory}}
2611 {{/each}}
2612 </div>
2613 {{/hasCategories}}
2614 {{#if price.intSupportPrice}}
2615 <div class="dcc-configurator-overview-price-configured js-dcc-configurator-overview-price-configured py-1 px-2 mb-0 justify-content-between d-flex border-bottom">
2616 <span>
2617 <h5 class="m-0 text-muted">
2618 @Translate( "DCC - Configurator - Overview - Service Fee", "Serviceafgift" )
2619 <span class="dcc-item-details-icon-info tooltip" data-toggle="tooltip" data-placement="auto" title="@Translate( "DCC - Configurator - Overview - Service Fee - Help Text", "Text about the service fee" )">
2620 <i class="material-icons material-icons-large ml-1">info</i>
2621 </span>
2622 </h5>
2623 </span>
2624 <span>
2625 <h5 class="m-0 text-muted">{{{price.strSupportPrice}}}</h5>
2626 </span>
2627 </div>
2628 {{/if}}
2629 {{#compare warranty.data.intPrice '>' 0}}
2630 <div class="dcc-configurator-overview-price-configured js-dcc-configurator-overview-price-configured py-1 px-2 mb-0 justify-content-between d-flex border-bottom">
2631 <span>
2632 <h5 class="m-0 text-muted">
2633 @Translate( "DCC - Configurator - Overview - Warranty - Header", "Udvidet garanti" )
2634 </h5>
2635 </span>
2636 <span>
2637 <h5 class="m-0 text-muted">+{{{warranty.data.strPrice}}}</h5>
2638 </span>
2639 </div>
2640 {{/compare}}
2641 {{#compare autopilot.intPrice '>' 0}}
2642 <div class="dcc-configurator-overview-price-configured js-dcc-configurator-overview-price-configured py-1 px-2 mb-0 justify-content-between d-flex border-bottom">
2643 <span>
2644 <h5 class="m-0 text-muted">
2645 Autopilot
2646 </h5>
2647 </span>
2648 <span>
2649 <h5 class="m-0 text-muted">+{{{autopilot.strPrice}}}</h5>
2650 </span>
2651 </div>
2652 {{/compare}}
2653 <div class="dcc-configurator-overview-price-configured js-dcc-configurator-overview-price-configured py-1 px-2 mb-0 justify-content-between d-flex ">
2654 <span>
2655 <h5 class="dcc-configurator-overview-price-lg m-0">@Translate( "DCC - Configurator - Overview - Your Price", "Din pris" )</h5>
2656 </span>
2657 <span>
2658 <h5 class="m-0 dcc-configurator-overview-price-lg">{{{price.strPrice}}}</h5>
2659 </span>
2660 </div>
2661 </div>
2662 {{#if isLeasingAllowed}}
2663 <div class="card shadow-none border-0 bg-light">
2664 <div class="card-header py-1 px-0 border-bottom bg-white" id="leasingCollapseHeader">
2665 <h3 class="mb-0">
2666 <a class="d-flex p-0 collapse-header" data-toggle="collapse" data-target="#leasingCollapse" aria-expanded="{{#if leasing.open}}true{{else}}false{{/if}}" aria-controls="leasingCollapse">
2667 <span class="collapse-text font-weight-bold">@Translate( "DCC - Configurator - Overview - Leasing - Header", "Leasing" )</span>
2668 </a>
2669 </h3>
2670 </div>
2671 <div id="leasingCollapse" class="js-dcc-configurator-overview-leasing-collapse collapse {{#if leasing.open}}show{{/if}}" aria-labelledby="leasingCollapseHeader">
2672 <div class="card-body py-1 bg-white">
2673 <div class="small">
2674 <div class="row">
2675 <div class="col-12 mb-2 mb-lg-0 small">
2676 <label><input type="checkbox" class="js-dcc-configurator-overview-leasing-checkbox mr-1" {{#if leasing.checked}}checked{{/if}} />@Translate( "eCom Product - Leasing - YesPlease", "Ja tak, jeg er interesseret i leasing." )</label>
2677 </div>
2678 </div>
2679 </div>
2680 </div>
2681 </div>
2682 </div>
2683 {{/if}}
2684
2685 @using Co3.Espresso.Base.Extensions
2686 @using Dynamicweb.Security.UserManagement
2687
2688 @if (User.IsExtranetUserLoggedIn() && autoPilotPrice > 0)
2689 {
2690
2691 <div class="card shadow-none border-0 bg-light">
2692 <div class="card-header py-1 px-0 border-bottom bg-white" id="leasingCollapseHeader">
2693 <h3 class="mb-0">
2694 <a class="d-flex p-0 collapse-header" data-toggle="collapse" data-target="#autopilotCollapse" aria-expanded="{{#if autopilot.open}}true{{else}}false{{/if}}" aria-controls="autopilotCollapse">
2695 <span class="collapse-text font-weight-bold">
2696 @Translate("DCC - Configurator - Overview - Autopilot - Header", "Autopilot")
2697 </span>
2698 </a>
2699 </h3>
2700 </div>
2701 <div id="autopilotCollapse" class="js-dcc-configurator-overview-autopilot-collapse collapse {{#if autopilot.open}}show{{/if}}" aria-labelledby="autopilotCollapseHeader">
2702 <div class="card-body py-1 bg-white">
2703 <div class="small">
2704 <div class="row">
2705 <div class="col-12 col-lg-6 mb-2 mb-lg-0 small">
2706 <label>
2707 <input class="js-dcc-configurator-overview-autopilot-checkbox" type="checkbox" data-price="@autoPilotPrice" {{#if autopilot.checked}}checked{{/if}}/>
2708 @Translate("DCC - Configurator - Overview - Autopilot - Add - Text", "Tilføj Autopilot")
2709 </label>
2710 </div>
2711 <div class="col-12 col-lg-6 mb-2 mb-lg-0 small text-right">
2712 @Co3.DCC.Dw.Services.ProductService.Instance.GetPriceFormatted(autoPilotPrice)
2713 </div>
2714 </div>
2715 <div class="row">
2716 <div class="col-12">
2717 <div id="js-dcc-autopilot-config-collapse" class="collapse {{#if autopilot.checked}}show{{/if}}">
2718 <div class="form-group my-1">
2719 <label for="autopilotEmailConfig">@Translate("DCC - Configurator - Overview - Autopilot - Email - Text", "Email address")</label>
2720 <input type="email" class="form-control js-dcc-configurator-autopilot-email-value" id="autopilotEmailConfig" value="@(User.IsExtranetUserLoggedIn() ? User.GetCurrentUser().Email : string.Empty)">
2721 </div>
2722 </div>
2723 </div>
2724 </div>
2725 </div>
2726 </div>
2727 </div>
2728 </div>
2729
2730 }
2731 <div class="dcc-configurator-overview-action mb-2 py-1">
2732 <div class="row">
2733 <div class="col-12 col-lg-4">
2734 </div>
2735 <div class="col-12 col-lg-8">
2736 <div class="dcc-flex-stock mt-1 mb-1 d-flex justify-content-end">
2737 <div class="dcc-product-list-specifications-stock-message">
2738 @if ( stockCheck )
2739 {
2740 <span class="dcc-custom-product-details-stockstatus dcc-stockstatus-instock">
2741 <small>@stockNumber @Translate( "eCom Product - stock in - Text", "på lager" )</small>
2742 </span>
2743 }
2744 else
2745 {
2746 <span class="dcc-custom-product-details-stockstatus dcc-stockstatus-outofstock">
2747 <small>@Translate( "eCom Product - stock out - Text", "Ikke på lager" )</small>
2748 </span>
2749 }
2750 </div>
2751 </div>
2752 @if (hasPrice)
2753 {
2754 <div class="dcc-product-details-add-to-cart-wrapper">
2755 <input name="Quantity" class="js-dcc-configurator-quantity" type="number" value="{{quantity}}" autocomplete="off">
2756
2757 <button class="btn btn-primary" type="submit">
2758 {{#if isEditing}}
2759 @Translate( "DCC - Configurator - Add To Cart - Update - Text", "Opdater" )
2760 {{else}}
2761 @Translate( "DCC - Configurator - Add To Cart - Text", "Læg i kurv" )
2762 {{/if}}
2763 </button>
2764
2765
2766 </div>
2767 }
2768 </div>
2769 </div>
2770
2771
2772 </div>
2773
2774 <input name="CartCmd" type="hidden" value="add" />
2775 <input name="Redirect" type="hidden" value="false" />
2776 <input name="ProductID" type="hidden" value="@GetString( "Ecom:Product.ID" )" />
2777 <input id="VariantID" name="VariantID" type="hidden" value="@GetString( "Ecom:Product.VariantID" )">
2778 <input id="UnitID" name="UnitID" type="hidden" value="">
2779
2780
2781 <input class="js-dcc-configurator-orderline-field js-dcc-configurator-overview-leasing-input-rate" name="EcomOrderLineFieldInput_leasing_rate" type="hidden" value="{{leasing.rate}}" />
2782 <input class="js-dcc-configurator-orderline-field js-dcc-configurator-overview-leasing-price-input" name="EcomOrderLineFieldInput_leasing_price" type="hidden" value="{{leasing.price}}" />
2783 <input class="js-dcc-configurator-orderline-field js-dcc-configurator-overview-leasing-checked" name="EcomOrderLineFieldInput_leasing_checked" type="hidden" value="{{leasing.checked}}" />
2784
2785 <input class="js-dcc-configurator-orderline-field js-dcc-configurator-overview-autopilot-email-input" name="EcomOrderLineFieldInput_AutopilotEmail" type="hidden" value="{{autopilot.email}}" />
2786 <input class="js-dcc-configurator-orderline-field js-dcc-configurator-overview-autopilot-checked" name="EcomOrderLineFieldInput_Autopilot" type="hidden" value="{{autopilot.checked}}" />
2787
2788 <input class="js-dcc-configurator-overview-has-configuration" type="hidden" value="{{hasConfiguration}}" name="EcomOrderLineFieldInput_HasConfiguration" />
2789 {{#if hasConfiguration}}
2790 <input type="hidden" value="true" name="EcomOrderLineFieldInput_IsConfigurable" />
2791 {{#each categories}}
2792 {{#each parts}}
2793
2794 <input name="{{../id}}" type="hidden" value="{{id}}">
2795 <input name="EcomOrderLineFieldInput_BomItemProductCategory{{../id}}" type="hidden" value="{{../label}}" />
2796 <input name="EcomOrderLineFieldInput_SlotName{{../id}}" type="hidden" value="{{slotName}}" />
2797 <input name="EcomOrderLineFieldInput_isDefault{{../id}}" type="hidden" value="{{isDefault}}" />
2798
2799 {{/each}}
2800
2801 {{#compare @@key '===' 'oslanguage'}}
2802 <input class="js-dcc-configurator-orderline-field js-dcc-configurator-overview-custom-os-language" name="EcomOrderLineFieldInput_OSLanguageCustom{{id}}" type="hidden" value="{{partOsLanguage}}" />
2803 {{/compare}}
2804 {{/each}}
2805
2806 {{/if}}
2807 </script>
2808 </div>
2809 </form>
2810 </div>
</div>
</div>
</div>
</div>
@sectionEnd()
<script>
2811 @inherits RazorTemplateBase< RazorTemplateModel< Template > >
2812 @inherits Co3.Espresso.Website.TemplateBases.Pages.PageBase
2813 @using Dynamicweb.Security.UserManagement
2814 @using System.Linq
2815 @using System.Collections.Generic
2816 @using Dynamicweb.Ecommerce.Products;
2817 @using Co3.Espresso.Website.Services
2818 @using ProductService = Co3.Espresso.Website.Services.ProductService
2819 @using Co3.DCC.Dw.Models.FrontEnd
2820 @using Dynamicweb.Frontend
2821 @{
2822 if ( productObject != null && productObject.Items != null )
2823 {
2824 int configurableCounter = 3;
2825 foreach ( ProductItem item in productObject.Items )
2826 {
2827 User user = Co3.DCC.Dw.Services.CustomerService.Instance.GetCurrentUser();
2828
2829 if ( item != null )
2830 {
2831 ConfigurationId configId = Co3.DCC.Dw.Services.ProductService.Instance.GetConfigurationIdByProductItem( productObject, item );
2832 string configurationId = string.Empty;
2833 string itemName = string.IsNullOrEmpty( item.Name ) ? string.Empty : item.Name;
2834
2835 string groupId = itemName.ToLower().Replace( " ", string.Empty ).Replace( "|", "_" );
2836
2837 configurableCounter++;
2838
2839 int sortKey = configurableCounter;
2840
2841 if ( itemName.Equals( Co3.DCC.Data.Utilities.Constants.KEYBOARD_INTERNAL_CONFIGURATION_GROUP_ID ) )
2842 {
2843 sortKey = 0;
2844 }
2845
2846 if ( itemName.Split( '|' )[ 0 ].Equals( Co3.DCC.Data.Utilities.Constants.MEMORY_CONFIGURATION_GROUP_ID ) )
2847 {
2848 sortKey = 1;
2849 }
2850
2851 string groupKey = sortKey + "_" + itemName.ToLower().Replace( " ", string.Empty ).Replace( "|", "_" );
2852
2853 bool addGroup = true;
2854
2855 if ( configId != null && addGroup == true && JSON.configurables.ContainsKey( groupKey ) == false )
2856 {
2857 JSON.configurables[ groupKey ] = new List< dynamic >();
2858
2859 dynamic configurable = new
2860 {
2861 id = groupId,
2862 sortKey = sortKey,
2863 slot = itemName.Split( '|' )[ 0 ],
2864 editableName = itemName.ToLower(),
2865 bomId = item.Id,
2866 label = Translate( string.Format( "DCC - Configurator - List - Category - Label - {0}", itemName ), itemName ),
2867 configurationId = configurationId,
2868 parts = new List< dynamic >(),
2869 languageParts = new List< dynamic >(),
2870 keyboardLanguages = new List< dynamic >(),
2871 hasDefault = true,
2872 configId = configId,
2873 isOSConfigurable = isOSConfigurable,
2874 isLocked = configId.IsLocked,
2875 hasLanguages = itemName.Equals( Co3.DCC.Data.Utilities.Constants.KEYBOARD_INTERNAL_CONFIGURATION_GROUP_ID ),
2876 aidebug = item.Products.Count()
2877 };
2878 if ( item.Products != null )
2879 {
2880 List<object> partObjects = new List<object>();
2881
2882 foreach ( Product part in item.Products.OrderByDescending( p => p.Stock ) )
2883 {
2884 object partObj = getPartsObj( productObject, item, part, user );
2885
2886 partObjects.Add(partObj);
2887 }
2888
2889 foreach ( object partObj in partObjects )
2890 {
2891 if ( partObj != null && ((configId.IsLocked && ((dynamic)partObj).isDefault) || !configId.IsLocked || (configId.IsLocked && ((dynamic)partObj).number == Co3.DCC.Data.Utilities.Constants.ECOMMERCE_PRODUCT_NOTHING_SELECTED_PRODUCTNUMBER && !partObjects.Any(p => p != null && ((dynamic)p).isDefault) )))
2892 {
2893 if ( itemName.Equals( Co3.DCC.Data.Utilities.Constants.KEYBOARD_INTERNAL_CONFIGURATION_GROUP_ID ) == false )
2894 {
2895 if ( partObj != null )
2896 {
2897 configurable.parts.Add( partObj );
2898 }
2899 }
2900 else
2901 {
2902 if ( partObj != null )
2903 {
2904 configurable.languageParts.Add( partObj );
2905 }
2906 }
2907 }
2908 }
2909 foreach ( Product part in item.Products.OrderByDescending( p => p.Stock ) )
2910 {
2911 object partObj = getPartsObj( productObject, item, part, user, configurable.languageParts );
2912
2913 if ( itemName.Equals( Co3.DCC.Data.Utilities.Constants.KEYBOARD_INTERNAL_CONFIGURATION_GROUP_ID ) == true )
2914 {
2915 if ( partObj != null && configurable.parts.Count == 0 )
2916 {
2917 configurable.parts.Add( partObj );
2918 }
2919 }
2920 }
2921
2922 JSON.configurables[ groupKey ].Add( configurable );
2923 }
2924 }
2925 }
2926 }
2927 }
2928 }
2929
2930 e4.data.set('dcc.configurator.data.json', @JsonService.Instance.ToJson( JSON ));
2931 </script>
2932
2933 @functions
2934 {
2935
2936 public object getPartsObj( Product productObject, ProductItem item, Product part, User user, dynamic languages = null )
2937 {
2938 if ( user == null )
2939 {
2940 return null;
2941 }
2942 Dynamicweb.Ecommerce.Products.ProductService dwProductService = new Dynamicweb.Ecommerce.Products.ProductService();
2943 ConfigurationDetails configurationDetails = Co3.DCC.Dw.Services.ProductService.Instance.GetConfigurationDetails( productObject );
2944
2945 if ( configurationDetails != null )
2946 {
2947 ConfigurationGroupDetails configurationGroupDetails = Co3.DCC.Dw.Services.ProductService.Instance.GetConfigurationGroupDetails( productObject, part, user );
2948 ConfigurationGroup partConfigurationGroup = new ConfigurationGroup();
2949 ConfigurationId configId = Co3.DCC.Dw.Services.ProductService.Instance.GetConfigurationIdByProductItem( productObject, item );
2950
2951 string configValue = string.Empty;
2952 string configUOM = string.Empty;
2953 string translationKey = string.Empty;
2954
2955 if ( configId != null )
2956 {
2957 configValue = configId.Value;
2958 configUOM = configId.UOM;
2959 }
2960
2961 string productLink = ProductService.Instance.GetProductLink( part.PrimaryGroupId, part.Id );
2962 productLink = SearchEngineFriendlyURLs.GetFriendlyUrl( productLink );
2963 string partName = configurationDetails.Items.ContainsKey( part.Number ) ? configurationDetails.Items[ part.Number ].Description : part.Name;
2964 partName = ConfiguratorPartName( partName );
2965
2966 string keyboardLangTranslated = string.Empty;
2967 string keyboardLangDefaultTranslated = string.Empty;
2968
2969 if ( partName == "OSLDefault" )
2970 {
2971 string OSLDefaultTranslationKey = string.Format( "DCC - Configurator - List - OS Language - {0} - Label", Co3.DCC.Dw.Services.ProductService.Instance.GetCategoryValue( productObject, "ItemAttributes", "Software_Language" ) );
2972 partName = Translate( OSLDefaultTranslationKey, Co3.DCC.Dw.Services.ProductService.Instance.GetCategoryValue( productObject, "ItemAttributes", "Software_Language" ) );
2973 }
2974
2975 if ( item.Name.Equals( Co3.DCC.Data.Utilities.Constants.KEYBOARD_INTERNAL_CONFIGURATION_GROUP_ID ) )
2976 {
2977 string keyboardLangStr = Co3.DCC.Dw.Services.ProductService.Instance.GetCategoryValue( part, "ItemAttributes", "Keyboard_Language" );
2978 string keyboardDefaultLangStr = Co3.DCC.Dw.Services.ProductService.Instance.GetCategoryValue( productObject, "ItemAttributes", "Keyboard_Language" );
2979 string translatedPartNameKey = string.Format( "ProductListItem_Keyboard_Language_ID_{0}", keyboardLangStr );
2980 string translatedDefaultPartNameKey = string.Format( "ProductListItem_Keyboard_Language_ID_{0}", keyboardDefaultLangStr );
2981 keyboardLangTranslated = Translate( translatedPartNameKey, keyboardLangStr );
2982 keyboardLangDefaultTranslated = Translate( translatedDefaultPartNameKey, keyboardDefaultLangStr );
2983 }
2984
2985 string itemNameSplit = item.Name.Split( '|' )[ 0 ];
2986
2987 if ( part.Number == Co3.DCC.Data.Utilities.Constants.ECOMMERCE_PRODUCT_NOTHING_SELECTED_PRODUCTNUMBER )
2988 {
2989 partName = Co3.DCC.Dw.Services.ProductService.Instance.GetDefaultPartName(productObject, item);
2990
2991 if (string.IsNullOrEmpty(partName))
2992 {
2993 partName = Translate( "DCC - Configurator - List - Nothing Selected - Text", "Nothing Selected" );
2994 }
2995
2996 //if ( item.Name == "DRIVES|1" )
2997 //{
2998 // partName = Co3.DCC.Dw.Services.ProductService.Instance.GetCategoryValue( productObject, "ItemAttributes", "HDDTEXT1" );
2999 //}
3000 //else
3001 //{
3002 // partName = Translate( "DCC - Configurator - List - Nothing Selected - Text", "Nothing Selected" );
3003 //}
3004 }
3005
3006
3007 object partCondition = dwProductService.GetProductFieldValue( part, "Condition" );
3008
3009
3010 string partConfigurationKey = $"{itemNameSplit}.{configValue}.{configUOM}.{partCondition}";
3011
3012 bool partIsDefault = Co3.DCC.Dw.Services.ProductService.Instance.IsDefaultBOMProduct( configurationDetails, productObject, item, part );
3013
3014 double partSupportPrice = 0;
3015 double partCombinedSupportPrice = 0;
3016
3017 if ( configurationGroupDetails != null )
3018 {
3019 ConfigurationGroup specificConfigurationGroup = configurationGroupDetails.BOM != null ? configurationGroupDetails.BOM : configurationGroupDetails.Default;
3020 if ( specificConfigurationGroup != null )
3021 {
3022 partSupportPrice = specificConfigurationGroup.SupportPrices.PriceByCurrency[ user.Currency ];
3023 partCombinedSupportPrice = specificConfigurationGroup.SupportPrices.CombinedPriceByCurrency[ user.Currency ];
3024 }
3025 }
3026
3027 Co3.DCC.Data.DAL.Models.Price originalPrice = Co3.DCC.Dw.Services.PriceService.Instance.GetProductPriceForBOM( productObject, part, user, item.Name );
3028
3029 dynamic partObj = new
3030 {
3031 id = part.Id,
3032 number = part.Number,
3033 bomId = item.BomGroupId,
3034 variantId = part.VariantId,
3035 label = partName,
3036 itemNameSplit = itemNameSplit,
3037 slotName = item.Name,
3038 url = productLink,
3039 description = part.ShortDescription,
3040 isDefault = partIsDefault,
3041 hasDefault = false,
3042 isActive = part.IsActive,
3043 hasLanguages = item.Name.Equals( Co3.DCC.Data.Utilities.Constants.KEYBOARD_INTERNAL_CONFIGURATION_GROUP_ID ),
3044 inputType = "radio",
3045 defaultLanguage = keyboardLangDefaultTranslated,
3046 defaultLanguageLanguageTranslated = keyboardLangTranslated,
3047 price = originalPrice.PriceAmount,
3048 priceFormatted = originalPrice.PriceAmount.ToString( "N2" ),
3049 priceDiff = originalPrice.PriceAmount,
3050 priceDiffFormatted = Co3.DCC.Dw.Services.ProductService.Instance.GetPriceFormatted( originalPrice.PriceAmount ),
3051 originalPriceObj = new
3052 {
3053 price = originalPrice.PriceAmount,
3054 priceFormatted = originalPrice.PriceAmount.ToString( "N2" )
3055 },
3056 condition = partCondition,
3057 partConfigurationGroup = partConfigurationGroup,
3058 supportPrice = partSupportPrice,
3059 combinedSupportPrice = partCombinedSupportPrice,
3060 stock = part.Stock,
3061 languages = languages,
3062 keyboardLang = Co3.DCC.Dw.Services.ProductService.Instance.GetCategoryValue( part, "ItemAttributes", "Keyboard_Language" ),
3063 keyboardLangTranslated = keyboardLangTranslated,
3064 osLang = string.Format( "OSL{0}", Co3.DCC.Dw.Services.ProductService.Instance.GetCategoryValue( productObject, "ItemAttributes", "Software_Language" ) ),
3065 configurationValue = configurationGroupDetails,
3066 userCurrency = user.Currency,
3067 isDefaultDebug = partIsDefault
3068 };
3069
3070 bool addPart = configurationGroupDetails != null || part.Id == "PROD1";
3071
3072 if ( item.Name.Equals( Co3.DCC.Data.Utilities.Constants.KEYBOARD_INTERNAL_CONFIGURATION_GROUP_ID ) && part.Stock <= 0 && part.Id != "PROD1" )
3073 {
3074 if ( !partIsDefault )
3075 {
3076 addPart = false;
3077 }
3078 }
3079
3080 if ( addPart == true )
3081 {
3082 return partObj;
3083 }
3084 }
3085 return null;
3086 }
3087
3088 }
3089 </div>
3090 }
3091 </div>
3092 </div>
3093
3094 @sectionEnd()
3095
3096
3097 @if ( string.IsNullOrEmpty( GetString( "Ecom:Product:Field.Marketingdescription.Value.Clean" ) ) == false || string.IsNullOrEmpty( GetString( "Ecom:Product:Field.ProductFeatures.Value.Clean" ) ) == false )
3098 {
3099 @sectionStart(
3100 sectionClasses: "e-section pt-4 pb-4 dcc-product-detail-longdescription-container",
3101 sectionCollapse: true,
3102 contentClasses: "col-12 col-md-10 col-lg-6 mx-auto",
3103 collapseToggleTextExpand: Translate( "eCom Product - View more - Text", "View more" ),
3104 collapseToggleTextCollapse: Translate( "eCom Product - View less - Text", "View less" )
3105 )
3106
3107 <div class="col-12">
3108 <h2 class="text-center">@Translate( "eCom Product - Egenskaber - Heading", "Egenskaber" )</h2>
3109 <p class="lead text-center">@GetString( "Ecom:Product:Field.Marketingdescription.Value.Clean" )</p>
3110 @GetString( "Ecom:Product:Field.ProductFeatures.Value.Clean" )
3111 </div>
3112
3113 if ( string.IsNullOrEmpty( GetString( "Ecom:Product:Field.Video" ) ) == false )
3114 {
3115 <div class="col-12 mt-3 text-center">
3116 @if ( string.IsNullOrEmpty( GetString( "Ecom:Product:Field.VideoHeading" ) ) == false )
3117 {
3118 <h2 class="mb-2">@GetString( "Ecom:Product:Field.VideoHeading" )</h2>
3119 }
3120 <div class="embed-responsive embed-responsive-16by9 mb-3">
3121 <iframe class="embed-responsive-item" src="@GetString( "Ecom:Product:Field.Video" )" width="1080" height="608" frameborder="0" webkitallowfullscreen mozallowfullscreen allowfullscreen></iframe>
3122 </div>
3123 </div>
3124 }
3125 @sectionEnd()
3126 }
3127
3128
3129
3130 @sectionEnd()
3131 @sectionStart(
3132 sectionClasses: "e-section pt-4 pb-4",
3133 sectionCollapse: false,
3134 contentClasses: "col-12 col-md-10 col-lg-6 mx-auto"
3135 )
3136
3137 <a id="condition"></a>
3138 <span class="dcc-product-details-badge mx-auto mb-2 @conditionClass">
3139 <span class="dcc-product-details-badge-title">@condition</span>
3140 </span>
3141 @if ( conditionClass == "dcc-condition-01new" && !string.IsNullOrEmpty(Espresso.Area.Item.ConditionNew) )
3142 {
3143 @RenderPageContent( Convert.ToInt32(Espresso.Area.Item.ConditionNew) )
3144 }
3145 @if ( conditionClass == "dcc-condition-gold" && !string.IsNullOrEmpty(Espresso.Area.Item.ConditionGold))
3146 {
3147 @RenderPageContent( Convert.ToInt32(Espresso.Area.Item.ConditionGold) )
3148 }
3149 @if ( conditionClass == "dcc-condition-silver" && !string.IsNullOrEmpty(Espresso.Area.Item.ConditionSilver))
3150 {
3151 @RenderPageContent( Convert.ToInt32(Espresso.Area.Item.ConditionSilver) )
3152 }
3153 @if ( conditionClass == "dcc-condition-bronze" && !string.IsNullOrEmpty(Espresso.Area.Item.ConditionBronze))
3154 {
3155 @RenderPageContent( Convert.ToInt32(Espresso.Area.Item.ConditionBronze) )
3156 }
3157 @if ( conditionClass == "dcc-condition-02bulk" && !string.IsNullOrEmpty(Espresso.Area.Item.ConditionBulk))
3158 {
3159 @RenderPageContent( Convert.ToInt32(Espresso.Area.Item.ConditionBulk) )
3160 }
3161 @if ( conditionClass == "dcc-condition-demo" && !string.IsNullOrEmpty(Espresso.Area.Item.ConditionDemo))
3162 {
3163 @RenderPageContent( Convert.ToInt32(Espresso.Area.Item.ConditionDemo) )
3164 }
3165 @if ( conditionClass == "dcc-condition-gradea" && !string.IsNullOrEmpty(Espresso.Area.Item.ConditionGradeA))
3166 {
3167 @RenderPageContent( Convert.ToInt32(Espresso.Area.Item.ConditionGradeA) )
3168 }
3169 @if ( conditionClass == "dcc-condition-gradeb" && !string.IsNullOrEmpty(Espresso.Area.Item.ConditionGradeB))
3170 {
3171 @RenderPageContent( Convert.ToInt32(Espresso.Area.Item.ConditionGradeB) )
3172 }
3173 @if ( conditionClass == "dcc-condition-gradec" && !string.IsNullOrEmpty(Espresso.Area.Item.ConditionGradeC))
3174 {
3175 @RenderPageContent( Convert.ToInt32(Espresso.Area.Item.ConditionGradeC) )
3176 }
3177 @if ( conditionClass == "dcc-condition-04exdemo" && !string.IsNullOrEmpty(Espresso.Area.Item.ConditionExdemo))
3178 {
3179 @RenderPageContent( Convert.ToInt32(Espresso.Area.Item.ConditionExdemo) )
3180 }
3181 @if ( conditionClass == "dcc-condition-08ref" && !string.IsNullOrEmpty(Espresso.Area.Item.ConditionRefurbished))
3182 {
3183 @RenderPageContent( Convert.ToInt32(Espresso.Area.Item.ConditionRefurbished) )
3184 }
3185 @if ( conditionClass == "dcc-condition-premium" && !string.IsNullOrEmpty(Espresso.Area.Item.ConditionPremium))
3186 {
3187 @RenderPageContent( Convert.ToInt32(Espresso.Area.Item.ConditionPremium) )
3188 }
3189
3190
3191 @sectionEnd()
3192
3193 @*
3194 @if ( isExtranet )
3195 {
3196 @sectionStart(
3197 sectionClasses: "e-section pt-4 pb-4 bg-light",
3198 sectionCollapse: false,
3199 contentClasses: "col-12 col-md-10 col-lg-6 mx-auto"
3200 )
3201
3202 @RenderParagraphContent( 12003 )
3203
3204 @sectionEnd()
3205 }
3206 *@
3207
3208 @DCCProductListPlain(
3209 heading: Translate( "eCom Product - Recently viewed items - Heading", "Recently viewed items" ),
3210 productLoop: GetLoop( "eCom:Related.YouHaveSeenTheseProducts" ).Take( 4 ),
3211 sectionClasses: "e-section p-section p-section-border-top dcc-productlist-presentation-grid"
3212 )
3213
3214
3215 <script type="application/ld+json">
3216 {
3217 "@@context" : "http://schema.org",
3218 "@@type" : "Product",
3219 "description" : "@GetString("Ecom:Product.ShortDescription").StripHtml()",
3220 "mpn" : "@GetString("Ecom:Product.Number").StripHtml()",
3221 "name" : "@GetString("Ecom:Product.Name").StripHtml()",
3222 "image" : "@( GetGlobalValue( "Global:Request.Scheme" ) + "://" + GetGlobalValue( "Global:Request.Host" ) + GetString("Ecom:Product.ImageLarge.Clean") )",
3223 "offers" : {
3224 "@@type" : "Offer",
3225 "availability" : @( GetInteger( "Ecom:Product.Stock" ) > 0 ? "\"http://schema.org/InStock\"" : "\"http://schema.org/OutOfStock\"" ),
3226 "price" : "@GetDouble("Ecom:Product.Price.Price")",
3227 "priceCurrency" : "@EcomContext.Currency.Code"
3228 }
3229 }
3230 </script>
3231
3232
3233 @{
3234 string productBreadCrumbLink = ProductService.Instance.GetProductLink( GetString( "Ecom:Product.PrimaryOrFirstGroupID" ), GetString( "Ecom:Product.ID" ) );
3235
3236 if ( string.IsNullOrEmpty( productBreadCrumbLink ) )
3237 {
3238 productBreadCrumbLink = string.Format( "Default.aspx?ID={0}&productid={1}", PageView.Current().Page.ID, GetString( "Ecom:Product.ID" ) );
3239 }
3240 }
3241
3242 <code class="js-e-breadcrumb-item-append" data-text="@HttpUtility.HtmlAttributeEncode( GetString( "Ecom:Product.Name" ) )" data-link="@HttpUtility.HtmlAttributeEncode( productBreadCrumbLink )"></code>
3243 <code class="js-tracking-product-id d-none" data-text="@HttpUtility.HtmlAttributeEncode( GetString( "Ecom:Product.ID" ) )" >@GetString( "Ecom:Product.ID" )</code>
3244
3245 </div>
3246
3247 @sectionStart()
3248
3249
3250 @if ( configurationShow )
3251 {
3252 <div class="e-loading-overlay dcc-configurator-loading-overlay is-loading js-dcc-configurator-loading-overlay">
<svg class="dcc-spinner" viewBox="0 0 100 100">
<circle class="path" cx="50" cy="50" r="20" fill="none"></circle>
</svg>
</div>
3253 }