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