Error executing template "Designs/dcc/eCom/Product/dcc-b2b.cshtml"
System.Collections.Generic.KeyNotFoundException: The given key was not present in the dictionary.
   at System.ThrowHelper.ThrowKeyNotFoundException()
   at System.Collections.Generic.Dictionary`2.get_Item(TKey key)
   at Co3.DCC.Dw.Services.ProductService.GetConfigurationDetails(Product product, Boolean forceLoad) in C:\Data\Development\git\dcc-solution-master\Co3.DCC.Dynamicweb\Services\ProductService.cs:line 1152
   at CompiledRazorTemplates.Dynamic.RazorEngine_94fbca8a9aba46f8ac9e091a3d4fefbc.Execute() in D:\dynamicweb.net\Solutions\foxwaysite.espresso4.dk\Files\Templates\Designs\dcc\eCom\Product\dcc-b2b.cshtml:line 1284
   at RazorEngine.Templating.TemplateBase.RazorEngine.Templating.ITemplate.Run(ExecuteContext context, TextWriter reader)
   at RazorEngine.Templating.RazorEngineService.RunCompile(ITemplateKey key, TextWriter writer, Type modelType, Object model, DynamicViewBag viewBag)
   at RazorEngine.Templating.RazorEngineServiceExtensions.<>c__DisplayClass16_0.b__0(TextWriter writer)
   at RazorEngine.Templating.RazorEngineServiceExtensions.WithWriter(Action`1 withWriter)
   at Dynamicweb.Rendering.Template.RenderRazorTemplate()

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