Error executing template "Designs/dcc/eCom/Product/dcc-b2b.cshtml"
System.NullReferenceException: Object reference not set to an instance of an object.
   at Co3.DCC.Dw.DAL.Repositories.ProductRepository.GetSpecificationMetaDataByProduct(Product product)
   at Co3.DCC.Dw.Services.ProductService.GetProductSpecifications(Product product)
   at CompiledRazorTemplates.Dynamic.RazorEngine_fb0bf78c5aa846689efabb1bc67941a2.Execute() in D:\dynamicweb.net\Solutions\foxwaysite.espresso4.dk\Files\Templates\Designs\dcc\eCom\Product\dcc-b2b.cshtml:line 1296
   at RazorEngine.Templating.TemplateBase.RazorEngine.Templating.ITemplate.Run(ExecuteContext context, TextWriter reader)
   at RazorEngine.Templating.RazorEngineService.RunCompile(ITemplateKey key, TextWriter writer, Type modelType, Object model, DynamicViewBag viewBag)
   at RazorEngine.Templating.RazorEngineServiceExtensions.<>c__DisplayClass16_0.b__0(TextWriter writer)
   at RazorEngine.Templating.RazorEngineServiceExtensions.WithWriter(Action`1 withWriter)
   at Dynamicweb.Rendering.Template.RenderRazorTemplate()

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