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