Error executing template "Designs/dcc/eCom/Product/dcc-b2b.cshtml"
System.NullReferenceException: Object reference not set to an instance of an object.
   at System.Collections.Generic.Dictionary`2.Insert(TKey key, TValue value, Boolean add)
   at Co3.DCC.Dw.Services.ProductService.GetConfigurationDetails(Product product, Boolean forceLoad) in C:\Data\Development\git\dcc-solution\Co3.DCC.Dynamicweb\Services\ProductService.cs:line 1145
   at CompiledRazorTemplates.Dynamic.RazorEngine_370dc01d131b4963bb85ac559cafd67a.Execute() in D:\dynamicweb.net\Solutions\dcc.espresso4.dk\files\Templates\Designs\dcc\eCom\Product\dcc-b2b.cshtml:line 1286
   at RazorEngine.Templating.TemplateBase.RazorEngine.Templating.ITemplate.Run(ExecuteContext context, TextWriter reader)
   at RazorEngine.Templating.RazorEngineService.RunCompile(ITemplateKey key, TextWriter writer, Type modelType, Object model, DynamicViewBag viewBag)
   at RazorEngine.Templating.RazorEngineServiceExtensions.<>c__DisplayClass16_0.b__0(TextWriter writer)
   at RazorEngine.Templating.RazorEngineServiceExtensions.WithWriter(Action`1 withWriter)
   at Dynamicweb.Rendering.Template.RenderRazorTemplate()

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