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_561f52ef3b5b45ce97571ddd3088f6f4.Execute() in D:\dynamicweb.net\Solutions\foxwaysite.espresso4.dk\Files\Templates\Designs\dcc\eCom\Product\dcc-b2b.cshtml:line 1287
   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 Co3.Espresso.Website.Services 1245 @using Dynamicweb.Ecommerce.Common 1246 @using Dynamicweb.Ecommerce.Products 1247 @using Dynamicweb.Frontend 1248 @using Dynamicweb.Security.UserManagement 1249 1250 @{ 1251 bool isExtranet = GetGlobalValue( "Global:Extranet.UserID" ) == "0" ? false : true; 1252 bool hasDirectSale = (bool)PageView.Current().Area.Item["HasDirectSales"]; 1253 User currentUser = User.get_Current( PagePermissionLevels.Frontend ); 1254 bool isActive = GetBoolean( "Ecom:Product.IsActive" ); 1255 string currencyCode = Context.Currency.Code; 1256 1257 if ( currentUser != null && string.IsNullOrEmpty( currentUser.Currency ) == false ) 1258 { 1259 currencyCode = Dynamicweb.Ecommerce.Services.Currencies.GetCurrencyForCode( currentUser.Currency ).Code; 1260 } 1261 1262 1263 1264 //TODO Fix currency code 1265 1266 Dynamicweb.Ecommerce.Products.ProductService dwProductService = new Dynamicweb.Ecommerce.Products.ProductService(); 1267 Product dwProduct = dwProductService.GetProductById( GetString( "Ecom:Product.ID" ), GetString( "Ecom:Product.VariantID" ), true ); 1268 1269 1270 string mainCategory = GetString( "Ecom:Product:Field.InventoryPostingGroup.Value.Clean" ); 1271 string[] selectedMainCategories = {"NOTEBOOK", "PC", "SERVER", "STORAGE", "MONITOR", "OTHER"}; 1272 string manufacturerCode = GetString( "Ecom:Product:Field.GlobalDimension2Code.Value.Clean" ); 1273 string conditionRaw = GetString( "Ecom:Product:Field.Condition.Value.Clean" ); 1274 string condition = Translate( String.Format( "Product_Refurbished_Condition_{0}", conditionRaw ), conditionRaw ); 1275 string conditionClass = "dcc-condition-" + Regex.Replace( conditionRaw, @"\s", String.Empty ).ToLower().Trim().Replace( ".", "" ); 1276 1277 bool stockCheck = GetInteger( "Ecom:Product.Stock" ) > 0; 1278 string stockNumber; 1279 1280 bool hasPrice = true; 1281 1282 string productId = GetString( "Ecom:Product.ID" ); 1283 Product productObject = Co3.DCC.Dw.Services.ProductService.Instance.GetProductById( productId ); 1284 ProductPriceInfo ppi = Co3.DCC.Dw.Services.ProductService.Instance.GetProductPriceInfo( productObject ); 1285 bool isLeasingAllowed = Co3.DCC.Dw.Services.ProductService.Instance.IsLeasingAllowed( productObject ); 1286 1287 ConfigurationDetails configurationDetails = Co3.DCC.Dw.Services.ProductService.Instance.GetConfigurationDetails( productObject ); 1288 1289 bool outlet = productObject.GetProductFieldValue<bool>( "Outlet" ); 1290 bool isCallForPrice = productObject.GetProductFieldValue<bool>( "WebCallForPrice" ); 1291 bool isConfigurable = productObject.GetProductFieldValue<bool>( "IsConfigurable" ); 1292 string isOSConfigurable = Co3.DCC.Dw.Services.ProductService.Instance.GetCategoryValue( productObject, "ItemAttributes", "OSConfigurable" ).ToLower(); 1293 1294 List<SpecificationCategory> specificationCategory = Co3.DCC.Dw.Services.ProductService.Instance.GetProductSpecifications( productObject ); 1295 SpecificationCategory PIMspecificationCategory = Co3.DCC.Dw.Services.ProductService.Instance.GetPIMItemProductSpecification( productObject ); 1296 1297 1298 string BrandLogoDirectory = @"~\Files\Images\dcc\icons\"; 1299 string BrandLogoPath = "/Files/Images/dcc/icons/"; 1300 1301 1302 if ( manufacturerCode == "AMP" || manufacturerCode == "APC" || manufacturerCode == "TYCO" || manufacturerCode == "UPS" ) 1303 { 1304 stockNumber = GetDouble( "Ecom:Product.Stock" ).ToString(); 1305 } 1306 else 1307 { 1308 stockNumber = GetDouble( "Ecom:Product.Stock" ).ToString(); 1309 } 1310 1311 string stockETA = string.Empty; 1312 1313 if ( Co3.DCC.Dw.Services.ProductService.Instance.IsNextPurchaseDateSet( dwProduct ) == true ) 1314 { 1315 double stockAmount = Co3.DCC.Dw.Services.ProductService.Instance.GetQtyAvailableOnStockPlus( dwProduct ); 1316 string stockAmountText = stockAmount.ToString(); 1317 string stockEtaDate = Co3.DCC.Dw.Services.ProductService.Instance.GetNextPurchaseDateFormatted( dwProduct ); 1318 1319 if ( stockAmount > 0 ) 1320 { 1321 stockETA = string.Format( "{0} {1} {2}", stockAmountText, Translate( "eCom Product - ETA - Expected in stock - Text", "forventet på lager" ), stockEtaDate ); 1322 } 1323 1324 1325 } 1326 1327 1328 1329 1330 IEnumerable<ProductRelatedGroup> relatedGroups = productObject.RelatedGroups; 1331 1332 ProductCollection warrantyRelatedProductCollection = new ProductCollection(); 1333 1334 if ( relatedGroups.FirstOrDefault( rg => rg.GroupId == "WARRANTY" ) != null ) 1335 { 1336 warrantyRelatedProductCollection = relatedGroups.FirstOrDefault( rg => rg.GroupId == "WARRANTY" ).Products; 1337 } 1338 1339 List<dynamic> warrantyRelatedProducts = new List<dynamic>(); 1340 1341 foreach ( Product relatedWarrentyProduct in warrantyRelatedProductCollection ) 1342 { 1343 if ( relatedWarrentyProduct.IsActive && relatedWarrentyProduct.Price.Price > 0 ) 1344 { 1345 warrantyRelatedProducts.Add( new 1346 { 1347 id = relatedWarrentyProduct.Id, 1348 name = relatedWarrentyProduct.Name, 1349 number = relatedWarrentyProduct.Number, 1350 intPrice = relatedWarrentyProduct.Price.PriceWithoutVAT, 1351 strPrice = relatedWarrentyProduct.Price.PriceWithoutVAT.ToString( "N2" ), 1352 shortDescription = relatedWarrentyProduct.ShortDescription 1353 } ); 1354 } 1355 } 1356 1357 if (warrantyRelatedProducts.Any()) 1358 { 1359 isConfigurable = true; 1360 } 1361 1362 bool hasRelated = relatedGroups != null && productObject.RelatedGroups.Any(); 1363 1364 string keyboardLanguage = Co3.DCC.Dw.Services.ProductService.Instance.GetCategoryValue( productObject, "ItemAttributes", "Keyboard_Language" ); 1365 string productType = Co3.DCC.Dw.Services.ProductService.Instance.GetCategoryValue( productObject, "ItemAttributes", "Product_Type" ); 1366 1367 dynamic JSON = new 1368 { 1369 configurationDetails = configurationDetails, 1370 PIMspecificationCategory = PIMspecificationCategory, 1371 ItemDescriptionByItemRelations = new List<dynamic>(), 1372 product = new 1373 { 1374 id = productObject.Id, 1375 variantId = productObject.VariantId, 1376 OSConfigurable = isOSConfigurable, 1377 }, 1378 isLeasingAllowed = isLeasingAllowed, 1379 prices = new 1380 { 1381 currencyCode = Context.Currency.Code, 1382 basePrice = ppi != null && ppi.Price != null ? ppi.Price.PriceAmount : 0, 1383 basePriceFormatted = ppi != null && ppi.Price != null ? Co3.DCC.Dw.Services.ProductService.Instance.GetPriceFormatted( ppi.Price.PriceAmount ) : string.Empty, 1384 beforePrice = ppi != null && ppi.BeforePrice != null ? ppi.BeforePrice.PriceAmount : 0, 1385 beforePriceFormatted = ppi != null && ppi.BeforePrice != null ? Co3.DCC.Dw.Services.ProductService.Instance.GetPriceFormatted( ppi.BeforePrice.PriceAmount ) : string.Empty 1386 }, 1387 configurables = new Dictionary<string, dynamic>(), 1388 warrantyRelatedProducts = warrantyRelatedProducts 1389 }; 1390 1391 double autoPilotPrice = 0; 1392 if (User.IsExtranetUserLoggedIn() && (productType == "MOBILE" || productType == "Desktops")) 1393 { 1394 string userAutopilotPrice = User.GetCurrentUser().GetCustomFieldValue<string>("AutopilotPrice"); 1395 double.TryParse(userAutopilotPrice, out autoPilotPrice); 1396 } 1397 } 1398 1399 1400 1401 1402 @if ( ppi != null ) 1403 { 1404 1405 if ( ppi.Price != null ) 1406 { 1407 if ( ppi.Price.PriceAmount == 0 ) 1408 { 1409 hasPrice = false; 1410 } 1411 } 1412 } 1413 1414 @sectionEnd() 1415 <div id="@GetValue( "Ecom:Product.ID" )" class="e-product js-dcc-main-product" data-product-id="@productId"> 1416 @sectionStart( 1417 sectionClasses: "e-section pb-3" 1418 ) 1419 1420 1421 <div class="col-12 col-md-5"> 1422 <div class="e-product-text-container"> 1423 <div class="row"> 1424 <div class="col-12 col-md-10"> 1425 <p></p> 1426 1427 @if ( Directory.Exists( HttpContext.Current.Server.MapPath( BrandLogoDirectory ) ) ) 1428 { 1429 1430 string BrandCode = GetString( "Ecom:Product:Field.GlobalDimension2Code.Value.Clean" ).ToLower(); 1431 DirectoryInfo directory = new DirectoryInfo( HttpContext.Current.Server.MapPath( BrandLogoDirectory ) ); 1432 1433 List< FileInfo > files = directory.GetFiles().ToList(); 1434 foreach ( FileInfo file in files ) 1435 { 1436 if (file.Name == string.Format("{0}.svg", BrandCode) ) 1437 1438 { 1439 string imgPath = string.Format( "{0}{1}", BrandLogoPath, file.Name ); 1440 1441 <img class="dcc-custom-brandlogo" src="@imgPath" /> 1442 } 1443 1444 } 1445 } 1446 1447 <h1 class="e-product-name h2 mb-0 mt-1"> 1448 @GetString( "Ecom:Product.Name" ) 1449 </h1> 1450 <p class="small mb-2"> 1451 @Translate( "eCom Product - Product Number - Text", "Number" ) @GetString( "Ecom:Product.Number" ) 1452 @if ( GetString( "Ecom:Product:Field.GetEAN.Value.Clean" ) != "NOEAN" ) 1453 { 1454 <br> 1455 @Translate( "eCom Product - EAN Number - Text", "EAN" ) 1456 @GetString( "Ecom:Product:Field.GetEAN.Value.Clean" ) 1457 } 1458 @if (string.IsNullOrEmpty(dwProduct.GetProductFieldValue<string>("ProductWarning")) == false) 1459 { 1460 <p class="alert alert-secondary small my-1"> 1461 @Translate("eCom - Product - Warning - Label") @(dwProduct.GetProductFieldValue<string>("ProductWarning")) 1462 </p> 1463 } 1464 </p> 1465 1466 @using Dynamicweb.Frontend 1467 @* NOTEBOOK AND PHONE *@ 1468 1469 @{ 1470 string helpText = Translate("mainCategory_Icon_HelpText", "mainCategory_Icon_HelpText"); 1471 1472 if (PageView.Current().User != null) 1473 { 1474 helpText = Translate("mainCategory_Icon_HelpText_loggedIn", "mainCategory_Icon_HelpText_loggedIn"); 1475 } 1476 } 1477 1478 @if ( mainCategory == "NOTEBOOK" || mainCategory == "PHONE" ) 1479 { 1480 if ( Espresso.Area.Item.MainCategoryFieldsNotebook != null ) 1481 { 1482 List< DescriptionField > customCategoryFieldsNotebook = Co3.DCC.Dw.Services.ProductService.GetProductItemDescriptionByItemRelations( productObject, Espresso.Area.Item.MainCategoryFieldsNotebook ); 1483 <div class="attribute-field-wrapper"> 1484 @foreach ( DescriptionField descriptionField in customCategoryFieldsNotebook ) 1485 { 1486 <div class="attribute-field-header" data-category="@mainCategory"> 1487 @if (isConfigurable && string.IsNullOrEmpty(descriptionField.ConfigurationAnchor) == false && PageView.Current().User != null) 1488 { 1489 string anchor = string.Format("{0}#dcc-productpage-tab-config", PageView.Current().SearchFriendlyUrl); 1490 1491 <a class="js-dcc-configurator-anchor-link" href="@anchor" style="text-decoration: none;" title="@helpText"> 1492 <img src="/files/images/dcc/icons/configuration.svg" style="width:16px;height:16px;margin:0 5px 0 0"> 1493 </a> 1494 } 1495 else 1496 { 1497 <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;"> 1498 &middot; 1499 </span> 1500 } 1501 @Translate(String.Format("mainCategory_FieldLabel_{0}", descriptionField.Header), descriptionField.Header) 1502 </div> 1503 1504 <div class="attribute-field-value"> 1505 1506 @descriptionField.Value.Replace( "U0022", "\"" ) 1507 </div> 1508 JSON.ItemDescriptionByItemRelations.Add(new 1509 { 1510 header = descriptionField.Header, 1511 value = descriptionField.Value, 1512 configurationAnchor = descriptionField.ConfigurationAnchor 1513 }); 1514 } 1515 </div> 1516 } 1517 } 1518 @* PC *@ 1519 else if ( mainCategory == "PC" ) 1520 { 1521 if ( Espresso.Area.Item.MainCategoryFieldsPC != null ) 1522 { 1523 List< DescriptionField > customCategoryFieldsPc = Co3.DCC.Dw.Services.ProductService.GetProductItemDescriptionByItemRelations( productObject, Espresso.Area.Item.MainCategoryFieldsPC ); 1524 1525 <div class="attribute-field-wrapper"> 1526 @foreach ( DescriptionField descriptionField in customCategoryFieldsPc ) 1527 { 1528 <div class="attribute-field-header" data-category="@mainCategory"> 1529 @if (isConfigurable && string.IsNullOrEmpty(descriptionField.ConfigurationAnchor) == false && PageView.Current().User != null) 1530 { 1531 string anchor = string.Format("{0}#dcc-productpage-tab-config", PageView.Current().SearchFriendlyUrl); 1532 <a class="js-dcc-configurator-anchor-link" href="@anchor" style="text-decoration: none;" title="@helpText"> 1533 <img src="/files/images/dcc/icons/configuration.svg" style="width:16px;height:16px;margin:0 5px 0 0"> 1534 </a> 1535 } 1536 else 1537 { 1538 <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;"> 1539 &middot; 1540 </span> 1541 } 1542 @Translate(String.Format("mainCategory_FieldLabel_{0}", descriptionField.Header), descriptionField.Header) 1543 </div> 1544 <div class="attribute-field-value">@descriptionField.Value</div> 1545 JSON.ItemDescriptionByItemRelations.Add(new 1546 { 1547 header = descriptionField.Header, 1548 value = descriptionField.Value + $"({descriptionField.ConfigurationAnchor})", 1549 configurationAnchor = descriptionField.ConfigurationAnchor 1550 }); 1551 } 1552 </div> 1553 } 1554 } 1555 @* SERVER *@ 1556 else if ( mainCategory == "SERVER" ) 1557 { 1558 if ( Espresso.Area.Item.MainCategoryFieldsServer != null ) 1559 { 1560 List< DescriptionField > customCategoryFieldsServer = Co3.DCC.Dw.Services.ProductService.GetProductItemDescriptionByItemRelations( productObject, Espresso.Area.Item.MainCategoryFieldsServer ); 1561 1562 <div class="attribute-field-wrapper"> 1563 @foreach ( DescriptionField descriptionField in customCategoryFieldsServer ) 1564 { 1565 <div class="attribute-field-header" data-category="@mainCategory"> 1566 @if (isConfigurable && string.IsNullOrEmpty(descriptionField.ConfigurationAnchor) == false && PageView.Current().User != null) 1567 { 1568 string anchor = string.Format("{0}#dcc-productpage-tab-config", PageView.Current().SearchFriendlyUrl); 1569 <a class="js-dcc-configurator-anchor-link" href="@anchor" style="text-decoration: none;" title="@helpText"> 1570 <img src="/files/images/dcc/icons/configuration.svg" style="width:16px;height:16px;margin:0 5px 0 0"> 1571 </a> 1572 } 1573 else 1574 { 1575 <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;"> 1576 &middot; 1577 </span> 1578 } 1579 @Translate(String.Format("mainCategory_FieldLabel_{0}", descriptionField.Header), descriptionField.Header) 1580 </div> 1581 <div class="attribute-field-value">@descriptionField.Value.Replace( "U0022", "\"" )</div> 1582 JSON.ItemDescriptionByItemRelations.Add(new 1583 { 1584 header = descriptionField.Header, 1585 value = descriptionField.Value, 1586 configurationAnchor = descriptionField.ConfigurationAnchor 1587 }); 1588 } 1589 </div> 1590 } 1591 } 1592 @* STORAGE *@ 1593 else if ( mainCategory == "STORAGE" ) 1594 { 1595 if ( Espresso.Area.Item.MainCategoryFieldsStorage != null ) 1596 { 1597 List< DescriptionField > customCategoryFieldsStorage = Co3.DCC.Dw.Services.ProductService.GetProductItemDescriptionByItemRelations( productObject, Espresso.Area.Item.MainCategoryFieldsStorage ); 1598 1599 <div class="attribute-field-wrapper"> 1600 @foreach ( DescriptionField descriptionField in customCategoryFieldsStorage ) 1601 { 1602 <div class="attribute-field-header" data-category="@mainCategory"> 1603 @if (isConfigurable && string.IsNullOrEmpty(descriptionField.ConfigurationAnchor) == false && PageView.Current().User != null) 1604 { 1605 string anchor = string.Format("{0}#dcc-productpage-tab-config", PageView.Current().SearchFriendlyUrl); 1606 <a class="js-dcc-configurator-anchor-link" href="@anchor" style="text-decoration: none;" title="@helpText"> 1607 <img src="/files/images/dcc/icons/configuration.svg" style="width:16px;height:16px;margin:0 5px 0 0"> 1608 </a> 1609 } 1610 else 1611 { 1612 <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;"> 1613 &middot; 1614 </span> 1615 } 1616 @Translate(String.Format("mainCategory_FieldLabel_{0}", descriptionField.Header), descriptionField.Header) 1617 </div> 1618 <div class="attribute-field-value">@descriptionField.Value.Replace( "U0022", "\"" )</div> 1619 JSON.ItemDescriptionByItemRelations.Add(new 1620 { 1621 header = descriptionField.Header, 1622 value = descriptionField.Value, 1623 configurationAnchor = descriptionField.ConfigurationAnchor 1624 }); 1625 } 1626 </div> 1627 } 1628 } 1629 @* MONITOR *@ 1630 else if ( mainCategory == "MONITOR" ) 1631 { 1632 if ( Espresso.Area.Item.MainCategoryFieldsMonitor != null ) 1633 { 1634 List< DescriptionField > customCategoryFieldsMonitor = Co3.DCC.Dw.Services.ProductService.GetProductItemDescriptionByItemRelations( productObject, Espresso.Area.Item.MainCategoryFieldsMonitor ); 1635 <div class="attribute-field-wrapper"> 1636 @foreach ( DescriptionField descriptionField in customCategoryFieldsMonitor ) 1637 { 1638 <div class="attribute-field-header" data-category="@mainCategory"> 1639 @if (isConfigurable && string.IsNullOrEmpty(descriptionField.ConfigurationAnchor) == false && PageView.Current().User != null) 1640 { 1641 string anchor = string.Format("{0}#dcc-productpage-tab-config", PageView.Current().SearchFriendlyUrl); 1642 <a class="js-dcc-configurator-anchor-link" href="@anchor" style="text-decoration: none;" title="@helpText"> 1643 <img src="/files/images/dcc/icons/configuration.svg" style="width:16px;height:16px;margin:0 5px 0 0"> 1644 </a> 1645 } 1646 else 1647 { 1648 <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;"> 1649 &middot; 1650 </span> 1651 } 1652 @Translate(String.Format("mainCategory_FieldLabel_{0}", descriptionField.Header), descriptionField.Header) 1653 </div> 1654 <div class="attribute-field-value">@descriptionField.Value.Replace( "U0022", "\"" )</div> 1655 JSON.ItemDescriptionByItemRelations.Add(new 1656 { 1657 header = descriptionField.Header, 1658 value = descriptionField.Value, 1659 configurationAnchor = descriptionField.ConfigurationAnchor 1660 }); 1661 } 1662 </div> 1663 } 1664 } 1665 else if ( mainCategory == "MONITOR" ) 1666 { 1667 List< DescriptionField > customCategoryFieldsOther = Co3.DCC.Dw.Services.ProductService.GetProductItemDescriptionByItemRelations( productObject, Espresso.Area.Item.MainCategoryFieldsOther ); 1668 <div class="attribute-field-wrapper"> 1669 @foreach ( DescriptionField descriptionField in customCategoryFieldsOther ) 1670 { 1671 <div class="attribute-field-header" data-category="@mainCategory"> 1672 @if (isConfigurable && string.IsNullOrEmpty(descriptionField.ConfigurationAnchor) == false && PageView.Current().User != null) 1673 { 1674 string anchor = string.Format("{0}#dcc-productpage-tab-config", PageView.Current().SearchFriendlyUrl); 1675 <a class="js-dcc-configurator-anchor-link" href="@anchor" style="text-decoration: none;" title="@helpText"> 1676 <img src="/files/images/dcc/icons/configuration.svg" style="width:16px;height:16px;margin:0 5px 0 0"> 1677 </a> 1678 } 1679 else 1680 { 1681 <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;"> 1682 &middot; 1683 </span> 1684 } 1685 @Translate(String.Format("mainCategory_FieldLabel_{0}", descriptionField.Header), descriptionField.Header) 1686 </div> 1687 <div class="attribute-field-value">@descriptionField.Value.Replace( "U0022", "\"" )</div> 1688 JSON.ItemDescriptionByItemRelations.Add(new 1689 { 1690 header = descriptionField.Header, 1691 value = descriptionField.Value, 1692 configurationAnchor = descriptionField.ConfigurationAnchor 1693 }); 1694 } 1695 </div> 1696 } 1697 else 1698 { 1699 <p>@Co3.DCC.Dw.Services.ProductService.Instance.GetCategoryValue( productObject, "PIMItemDescription", "Description" )</p> 1700 } 1701 1702 1703 </div> 1704 <div class="col-3"> 1705 &nbsp; 1706 </div> 1707 </div> 1708 1709 1710 @* AUTOPILOT *@ 1711 @using Co3.Espresso.Base.Extensions 1712 @using Dynamicweb.Notifications 1713 @using Dynamicweb.Security.UserManagement 1714 @using Dynamicweb.SystemTools 1715 1716 @if (User.IsExtranetUserLoggedIn() && autoPilotPrice > 0) 1717 { 1718 <div class="row"> 1719 <div class="col-12 mb-2"> 1720 <div class="dcc-leasing-wrapper small"> 1721 <div class="row"> 1722 <div class="col-12 col-lg-6 mb-2 mb-lg-0 small"> 1723 <label> 1724 <input type="checkbox" class="js-dcc-autopilot-checkbox" data-toggle="collapse" data-target="#dcc-autopilot-collapse" data-price="100"/> 1725 @Translate("DCC - Configurator - Overview - Autopilot - Header", "Autopilot") 1726 </label> 1727 </div> 1728 <div class="col-12 col-lg-6 mb-2 mb-lg-0 small text-right"> 1729 @Co3.DCC.Dw.Services.ProductService.Instance.GetPriceFormatted( autoPilotPrice ) 1730 </div> 1731 <div class="col-12 order-3"> 1732 <div id="dcc-autopilot-collapse" class="collapse"> 1733 <div class="form-group my-1"> 1734 <label for="AutopilotEmail">@Translate("DCC - Configurator - Overview - Autopilot - Email - Text", "Email address")</label> 1735 <input type="email" class="form-control js-dcc-autopilot-email-input" id="AutopilotEmail" value="@(User.IsExtranetUserLoggedIn() ? User.GetCurrentUser().Email : string.Empty)"> 1736 </div> 1737 </div> 1738 </div> 1739 </div> 1740 </div> 1741 </div> 1742 </div> 1743 } 1744 1745 1746 1747 1748 <div class="js-dcc-configurator-disabled-element"> 1749 1750 1751 1752 1753 @* LEASING *@ 1754 1755 1756 @if ( (isExtranet || hasDirectSale) && isActive && isLeasingAllowed && isCallForPrice == false ) { 1757 1758 <div class="row"> 1759 <div class="col-12 mb-2"> 1760 <div class="dcc-leasing-wrapper small"> 1761 <div class="row"> 1762 @* 1763 <div class="col-12 col-lg-6 order-2 order-lg-1 small"> 1764 @Co3.DCC.Dw.Services.ProductService.Instance.CalculateLeasingPaymentPerMonth( productObject, 36, 5 ) @currencyCode @Translate( "eCom Product - Leasing - Ratio", "pr. måned i 36 måneder" ) 1765 1766 <a aria-controls="collapseExample" aria-expanded="false" class="d-block" data-toggle="collapse" href="#collapseExample" role="button"> 1767 @Translate( "eCom Product - Leasing - ConfigureText", "Konfigurér leasingmuligheder" ) <i class="material-icons">unfold_more</i> 1768 </a> 1769 1770 </div> 1771 *@ 1772 <div class="col-12 col-lg-6 mb-2 mb-lg-0 small "> 1773 <label><input type="checkbox" class="js-leasing-offer-checkbox" />@Translate( "eCom Product - Leasing - YesPlease", "Ja tak, jeg er interesseret i leasing." )</label> 1774 </div> 1775 @* 1776 <div class="col-12 order-3"> 1777 <div class="collapse" id="collapseExample"> 1778 <table class="mt-2 table"> 1779 <tr> 1780 <td class="align-middle pl-0">@Translate( "eCom Product - Leasing - AvancePercent", "Avance i procent" )</td> 1781 <td class="pr-0 text-right"> 1782 <select class="js-dcc-product-leasing-interest-rate p-1"> 1783 @{ 1784 int[] leasingInterestRates = {5, 10, 15, 20, 25}; 1785 foreach ( int leasingInterestRate in leasingInterestRates ) 1786 { 1787 1788 <option value="@Co3.DCC.Dw.Services.ProductService.Instance.CalculateLeasingPaymentPerMonth( productObject, 36, leasingInterestRate )">@leasingInterestRate%</option> 1789 } 1790 } 1791 </select> 1792 </td> 1793 </tr> 1794 </table> 1795 </div> 1796 </div> 1797 *@ 1798 </div> 1799 </div> 1800 </div> 1801 </div> 1802 } 1803 1804 @if ( (isExtranet || hasDirectSale ) && isActive ){ 1805 <div class="dcc-price-setup"> 1806 <div class="row"> 1807 <div class="col-12 col-md-6"> 1808 <div class="dcc-price-setup-price text-right"> 1809 @if ( ppi != null && ppi.Price != null ) 1810 { 1811 1812 if ( isCallForPrice == false && hasPrice == true ) 1813 { 1814 <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> 1815 } 1816 } 1817 </div> 1818 </div> 1819 <div class="col-12 @(isCallForPrice ? "col-md-12" : "col-md-6")"> 1820 <div class="dcc-price-setup-stock-and-action"> 1821 <div class="dcc-flex-stock mb-1"> 1822 @if (hasPrice == true) 1823 { 1824 <div class="dcc-product-list-specifications-stock-message text-right"> 1825 1826 @if ( stockCheck ) 1827 { 1828 <span class="dcc-custom-product-details-stockstatus dcc-stockstatus-instock"> 1829 <small>@stockNumber @Translate( "eCom Product - stock in - Text", "på lager" )</small> 1830 </span> 1831 } 1832 else 1833 { 1834 <span class="dcc-custom-product-details-stockstatus dcc-stockstatus-outofstock"> 1835 <small>@Translate( "eCom Product - stock out - Text", "Ikke på lager" )</small> 1836 </span> 1837 } 1838 @if (string.IsNullOrEmpty(GetString("Ecom:Product:Field.RemoteStock")) == false) 1839 {<br> 1840 <span class="dcc-custom-product-details-stockstatus dcc-stockstatus-remotestock"> 1841 @{ 1842 string translationKey = string.Format("eCom Product - Remote Stock - Status - {0}", GetString("Ecom:Product:Field.RemoteStock")); 1843 } 1844 <small>@Translate(translationKey, GetString("Ecom:Product:Field.RemoteStock"))</small> 1845 </span> 1846 } 1847 @if ( string.IsNullOrEmpty( stockETA ) == false ) 1848 {<br> 1849 <span class="dcc-custom-product-details-stockstatus dcc-stockstatus-eta"> 1850 <small>@stockETA</small> 1851 </span> 1852 } 1853 1854 1855 </div> 1856 } 1857 </div> 1858 @if ( !isCallForPrice && hasPrice ) 1859 { 1860 <div class="dcc-flex-addtocart"> 1861 <form action="/system/data/cart" class="e-product-form js-e-product-form" method="post"> 1862 <input name="CartCmd" type="hidden" value="Add"> 1863 <input type="hidden" name="ProductID" value="@GetString( "Ecom:Product.ID" )"> 1864 <input name="VariantID" type="hidden" value=""> 1865 <input name="UnitID" type="hidden" value=""> 1866 <input name="Redirect" type="hidden" value=""> 1867 <input class="js-leasing-offer-input-rate" type="hidden" value="" name="EcomOrderLineFieldInput_leasing_rate" /> 1868 <input class="js-leasing-offer-input-price" type="hidden" value="" name="EcomOrderLineFieldInput_leasing_price" /> 1869 <input class="js-leasing-offer-input-checked" type="hidden" value="" name="EcomOrderLineFieldInput_leasing_checked" /> 1870 1871 <input class="js-dcc-autopilot-email-orderline-input" name="EcomOrderLineFieldInput_AutopilotEmail" type="hidden" value="" /> 1872 <input class="js-dcc-autopilot-checked-orderline-input" name="EcomOrderLineFieldInput_Autopilot" type="hidden" value="false" /> 1873 1874 1875 <input type="hidden" value="false" name="EcomOrderLineFieldInput_HasConfiguration" /> 1876 <input type="hidden" value="false" name="EcomOrderLineFieldInput_IsConfigurable" /> 1877 <div class="dcc-product-details-add-to-cart-wrapper"> 1878 1879 <input name="Quantity" type="number" value="1" autocomplete="off"> 1880 <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> 1881 1882 </div> 1883 </form> 1884 1885 </div> 1886 } 1887 else if (!hasPrice) 1888 { 1889 <span></span> 1890 } 1891 else if(isCallForPrice) 1892 { 1893 <div class="dcc-product-details-callforprice-wrapper"> 1894 <button class="btn btn-call btn-secondary" data-toggle="modal" data-target="#callForPrice-@productId"> 1895 <i class="material-icons">phone</i> @Translate( "eCom Product - callforprice - Text", "Ring for pris" )</button> 1896 </div> 1897 1898 <div class="fade modal" id="callForPrice-@productId" tabindex="-1" role="dialog" aria-labelledby="exampleModalCenterTitle" aria-hidden="true"> 1899 <div class="modal-dialog modal-dialog-centered" role="document"> 1900 <div class="modal-content"> 1901 <div class="modal-header"> 1902 <h3 class="modal-title" id="exampleModalLongTitle">@Translate( "eCom Product - callforprice - Text", "Ring for pris" )</h3> 1903 <button aria-label="Close" class="close" data-dismiss="modal" type="button"> 1904 <span aria-hidden="true">&times;</span> 1905 </button> 1906 </div> 1907 <div class="modal-body"> 1908 <div class="dcc-callforprice-product-wrapper"> 1909 <div class="dcc-callforprice-image"> 1910 <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" )"> 1911 </div> 1912 <div class="dcc-callforprice-desc"> 1913 <h3 class="mb-0">@GetString( "Ecom:Product.Name" )</h3> 1914 <p class="mb-0 small"># @GetString( "Ecom:Product.Number" )</p> 1915 <div class="dcc-product-list-specifications-stock-message"> 1916 1917 @if ( stockCheck ) 1918 { 1919 <span class="dcc-custom-product-details-stockstatus dcc-stockstatus-instock"> 1920 <small>@stockNumber @Translate( "eCom Product - stock in - Text", "på lager" )</small> 1921 </span> 1922 } 1923 else 1924 { 1925 <span class="dcc-custom-product-details-stockstatus dcc-stockstatus-outofstock"> 1926 <small>@Translate( "eCom Product - stock out - Text", "Ikke på lager" )</small> 1927 </span> 1928 } 1929 @if (string.IsNullOrEmpty(GetString("Ecom:Product:Field.RemoteStock")) == false) 1930 {<br> 1931 <span class="dcc-custom-product-details-stockstatus dcc-stockstatus-remotestock"> 1932 @{ 1933 string translationKey = string.Format("eCom Product - Remote Stock - Status - {0}", GetString("Ecom:Product:Field.RemoteStock")); 1934 } 1935 <small>@Translate(translationKey, GetString("Ecom:Product:Field.RemoteStock"))</small> 1936 </span> 1937 } 1938 @if ( string.IsNullOrEmpty( stockETA ) == false ) 1939 {<br> 1940 <span class="dcc-custom-product-details-stockstatus dcc-stockstatus-eta"> 1941 <small>@stockETA</small> 1942 </span> 1943 } 1944 1945 </div> 1946 </div> 1947 </div> 1948 <hr> 1949 <div class="row"> 1950 <div class="col-12 col-lg-7"> 1951 @RenderParagraphContent( 14654 ) 1952 </div> 1953 1954 <div class="col-12 col-lg-5 mt-5 mt-lg-0"> 1955 <div class="col-12 p p-imagetext p-imagetext-lr p-width-auto"> 1956 <p class="h3 mb-1 small text-secondary">@Translate( "eCom callforprice - contactDCCDirectly - Text", "Kontakt DCC direkte på" )</p> 1957 <p class="lead mb-1 small"> 1958 <small> 1959 <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> 1960 </small> 1961 </p> 1962 <p class="lead small"> 1963 <small> 1964 <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> 1965 </small> 1966 </p> 1967 </div> 1968 </div> 1969 </div> 1970 1971 </div> 1972 1973 </div> 1974 </div> 1975 </div> 1976 } 1977 </div> 1978 </div> 1979 </div> 1980 </div> 1981 } 1982 1983 @if ( (isExtranet || hasDirectSale) && isActive ) 1984 { 1985 if ( !isCallForPrice ) 1986 { 1987 if ( ppi != null && ppi.QuantityPrices != null && ppi.QuantityPrices.Any() ) 1988 { 1989 <h3 class="mb-1 mt-2 small">@Translate( "eCom QuantityPrices - QuantityPricesHeading - Text", "Køb flere og spar" )</h3> 1990 1991 <table class="mb-3 table table-sm"> 1992 <thead> 1993 <th style="width: 40%;">@Translate( "eCom QuantityPrices - QuantityPricesNumber - Text", "Antal" )</th> 1994 <th>@Translate( "eCom QuantityPrices - QuantityPricesPrice - Text", "Pris pr. stk" )</th> 1995 <th class="text-right">@Translate( "eCom QuantityPrices - QuantityPricesDiscount - Text", "Rabat" )</th> 1996 </thead> 1997 @foreach ( Co3.DCC.Data.DAL.Models.Price price in ppi.QuantityPrices ) 1998 { 1999 <tr> 2000 <td style="width: 40%;">@price.Discount.MinimumQuantity</td> 2001 2002 <td>@Co3.DCC.Dw.Services.ProductService.Instance.GetPriceFormatted( price.PriceAmount )</td> 2003 <td class="text-right text-success"> 2004 <strong>@Translate( "eCom QuantityPrices - QuantityPricesDiscountSave - Text", "Spar" ) @price.Discount.LineDiscountPercent%</strong> 2005 </td> 2006 2007 </tr> 2008 } 2009 2010 </table> 2011 } 2012 2013 2014 2015 } 2016 else 2017 { 2018 <br /> 2019 <br /> 2020 } 2021 2022 2023 <div> 2024 </div> 2025 } 2026 2027 @if ( !isActive ) 2028 { 2029 <div class="d-flex justify-content-between align-items-center"> 2030 <div> 2031 <span class="dcc-custom-product-details-stockstatus dcc-stockstatus-outofstock"> 2032 <small>@Translate( "eCom Product - stock out - Text", "Ikke på lager" )</small> 2033 </span> 2034 @if ( string.IsNullOrEmpty( stockETA ) == false ) 2035 { 2036 <br /> 2037 <span class="dcc-custom-product-details-stockstatus dcc-stockstatus-eta"> 2038 <small>@stockETA</small> 2039 </span> 2040 } 2041 </div> 2042 2043 <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> 2044 </div> 2045 2046 } 2047 2048 @if (!(isExtranet || hasDirectSale) && isActive) { 2049 <div class="dcc-product-details-cart-flex-wrapper"> 2050 <div class="dcc-flex-stock"> 2051 <div class="dcc-product-list-specifications-stock-message"> 2052 2053 @if ( stockCheck ) 2054 { 2055 <span class="dcc-custom-product-details-stockstatus dcc-stockstatus-instock"> 2056 <small>@stockNumber @Translate( "eCom Product - stock in - Text", "på lager" )</small> 2057 </span> 2058 } 2059 else 2060 { 2061 <span class="dcc-custom-product-details-stockstatus dcc-stockstatus-outofstock"> 2062 <small>@Translate( "eCom Product - stock out - Text", "Ikke på lager" )</small> 2063 </span> 2064 } 2065 @if (string.IsNullOrEmpty(GetString("Ecom:Product:Field.RemoteStock")) == false) 2066 {<br> 2067 <span class="dcc-custom-product-details-stockstatus dcc-stockstatus-remotestock"> 2068 @{ 2069 string translationKey = string.Format("eCom Product - Remote Stock - Status - {0}", GetString("Ecom:Product:Field.RemoteStock")); 2070 } 2071 <small>@Translate(translationKey, GetString("Ecom:Product:Field.RemoteStock"))</small> 2072 </span> 2073 } 2074 @if ( string.IsNullOrEmpty( stockETA ) == false ) 2075 {<br> 2076 <span class="dcc-custom-product-details-stockstatus dcc-stockstatus-eta"> 2077 <small>@stockETA</small> 2078 </span> 2079 } 2080 2081 </div> 2082 2083 </div> 2084 <div> 2085 2086 </div> 2087 <div class="dcc-flex-addtocart"> 2088 <a class="btn btn-block btn-secondary text-muted" href="@Espresso.Area.Item.ExtranetLoginPage">@Translate( "eCom ProductList - ReadMore button - Text", "Læs mere" )</a> 2089 </div> 2090 </div> 2091 } 2092 2093 <div class="d-flex justify-content-end mt-2"> 2094 <div class="ml-auto"> 2095 @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> } 2096 </div> 2097 </div> 2098 </div> 2099 2100 2101 </div> 2102 </div> 2103 <div class="col-12 col-md-7 order-first"> 2104 <div class="e-product-image-container position-relative"> 2105 2106 @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> 2107 @if ( ppi != null && ppi.IsCampaignPrice ) 2108 { 2109 <div class="dcc-campaign-label dcc-streamer dcc-streamer-detail-view"> 2110 <svg height="120px" id="dcc-streamer-svg" viewBox="0 0 199.9 145.2" width="164px" xmlns="http://www.w3.org/2000/svg"> 2111 <path class="dcc-streamer-color" d="M0 145.2h73.2l126.7-92V0z" /> 2112 @*<path class="dcc-streamer-color-secondary" d="M7.5 139.8H0v5.4zM199.9 0h-7.6v5.5z"/>*@ 2113 </svg> 2114 <p>@Translate( "eCom Product - Streamer Campaign - Heading", "Kampagne" )</p> 2115 </div> 2116 } 2117 else if ( outlet ) 2118 { 2119 <div class="dcc-campaign-label dcc-streamer dcc-streamer-detail-view"> 2120 <svg height="120px" id="dcc-streamer-svg" viewBox="0 0 199.9 145.2" width="164px" xmlns="http://www.w3.org/2000/svg"> 2121 <path class="dcc-streamer-color" d="M0 145.2h73.2l126.7-92V0z" /> 2122 @*<path class="dcc-streamer-color-secondary" d="M7.5 139.8H0v5.4zM199.9 0h-7.6v5.5z"/>*@ 2123 </svg> 2124 <p>@Translate( "eCom Product - Streamer Outlet - Heading", "Outlet" )</p> 2125 </div> 2126 } 2127 </div> 2128 <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> 2129 </div> 2130 2131 @sectionEnd() 2132 2133 @sectionStart( 2134 sectionClasses: "e-section pt-1 pb-4", 2135 sectionCollapse: false, 2136 contentClasses: "col-12 mx-auto" 2137 ) 2138 2139 @{ 2140 bool configurationShow = ( 2141 hasPrice && 2142 isActive && 2143 (isExtranet || hasDirectSale) && 2144 ((isConfigurable && IsConfiguratorActive()) || 2145 warrantyRelatedProductCollection.Any()) 2146 ); 2147 } 2148 2149 <div class="col-12 dcc-product-tabs"> 2150 <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> 2151 <div class="tab-content"> 2152 <div class="tab-pane fade @(!configurationShow ? "active show" : string.Empty)" id="dcc-productpage-tab-content-accessories" role="tabpanel" aria-labelledby="dcc-productpage-tab-accessories"> 2153 @using System.Collections.Generic 2154 @using Dynamicweb.Ecommerce.Products 2155 2156 @if ( relatedGroups != null && productObject.RelatedGroups.Any() ) 2157 { 2158 @sectionStart( 2159 sectionClasses: "e-section dcc-section-related-products p-2 bg-white js-dcc-section-related-products", 2160 sectionCollapse: true, 2161 collapsetoggleHidden: true, 2162 collapseToggleTextExpand: Translate("Related Products - Toggle - Expand"), 2163 collapseToggleTextCollapse: Translate("Related Products - Toggle - Collapse"), 2164 contentClasses: "col-12 mx-auto show" 2165 ) 2166 <div class="js-dcc-configurator-cart-related-products-container pt-0 pb-4 w-100"> 2167 <div class="e-loading-overlay is-loading" style="background: none; height: 10em; position: relative"> 2168 <div class="e-loading-spinner"></div> 2169 </div> 2170 <script id="js-e-handlebars-tmpl-configurator-cart-related-products" type="text/x-handlebars-template"> 2171 <div class="row"> 2172 <div class="col-12"> 2173 {{#each relatedGroups}} 2174 <div class="bg-white border-0 card mt-1 shadow-none"> 2175 <div class="card-header px-2 py-1" id="cart-related-parts-{{id}}-header"> 2176 <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"> 2177 {{name}} 2178 </h3> 2179 </div> 2180 </div> 2181 <div aria-labelledby="cart-related-parts-{{id}}-header" class="dcc-productlist-presentation-list collapse" id="cart-related-parts-{{id}}-collapse"> 2182 <div class="bg-white card-body px-0 py-0 e-products"> 2183 {{#each products}} 2184 {{> configuratorCartRelatedProduct this}} 2185 {{/each}} 2186 2187 </div> 2188 </div> 2189 {{/each}} 2190 </div> 2191 </div> 2192 </script> 2193 </div> 2194 @sectionEnd() 2195 } 2196 2197 2198 <script id="js-e-handlebars-partial-configurator-cart-related-product" type="text/x-handlebars-template"> 2199 <div class="col-12 col-sm-12 col-md-6 col-lg-3 col-xl-3 px-0"> 2200 <div class="border-bottom e-products-item js-e-products-item"> 2201 <div class="e-products-item-container"> 2202 <div class="e-products-item-image-container"> 2203 <a class="e-block-link e-products-item-image-wrapper js-e-block-link" href="{{url}}"> 2204 <img alt="" class="e-products-item-image" src="{{image}}"> 2205 </a> 2206 {{#if isCampaign}} 2207 <a class="e-block-link" href="{{url}}"> 2208 <div class="dcc-campaign-label dcc-streamer"> 2209 <svg height="120px" id="dcc-streamer-svg" viewBox="0 0 199.9 145.2" width="164px" xmlns="http://www.w3.org/2000/svg"> 2210 <path class="dcc-streamer-color" d="M0 145.2h73.2l126.7-92V0z" /> 2211 </svg> 2212 <p>@Translate( "eCom Product - Streamer Campaign - Heading", "Kampagne" )</p> 2213 </div> 2214 </a> 2215 {{/if}} 2216 {{#compare_extended isCampaign '!==' "True"}} 2217 {{#if isOutlet}} 2218 <a class="e-block-link" href="{{url}}"> 2219 <div class="dcc-campaign-label dcc-streamer"> 2220 <svg height="120px" id="dcc-streamer-svg" viewBox="0 0 199.9 145.2" width="164px" xmlns="http://www.w3.org/2000/svg"> 2221 <path class="dcc-streamer-color" d="M0 145.2h73.2l126.7-92V0z" /> 2222 </svg> 2223 <p>@Translate( "eCom Product - Streamer Outlet - Heading", "Outlet" )</p> 2224 </div> 2225 </a> 2226 {{/if}} 2227 {{/compare_extended}} 2228 2229 {{#compare condition '!==' ""}} 2230 <a class="e-block-link" href="{{url}}"> 2231 <span class="{{conditionClass}} dcc-product-list-badge"> 2232 <span class="dcc-product-list-badge-title"> 2233 {{condition}} 2234 </span> 2235 </span> 2236 </a> 2237 {{/compare}} 2238 </div> 2239 2240 <div class="e-block-link e-products-item-text-container js-e-block-link small"> 2241 2242 <div class="dcc-products-item-list-heading"> 2243 <h3 class="e-products-item-name mb-0"> 2244 <a href="{{url}}">{{shortDescription}}</a> 2245 </h3> 2246 <p class="hidden-grid mb-0 small text-muted">@Translate( "eCom Product - Product Number - Text", "Number" ) {{number}}</p> 2247 </div> 2248 <div class="dcc-product-list-specifications-unordered-list"> 2249 @* NOTEBOOK *@ 2250 {{#compare mainCategory '===' "NOTEBOOK"}} 2251 <div class="attribute-field-wrapper productlist-view"> 2252 {{#each categoryFieldsNotebook}} 2253 <div class="attribute-field-header">{{this.header}}</div> 2254 <div class="attribute-field-value">{{this.value}}</div> 2255 {{/each}} 2256 </div> 2257 {{/compare}} 2258 2259 @* PC *@ 2260 {{#compare mainCategory '===' "PC"}} 2261 <div class="attribute-field-wrapper productlist-view"> 2262 {{#each categoryFieldsPc}} 2263 <div class="attribute-field-header">{{this.header}}</div> 2264 <div class="attribute-field-value">{{this.value}}</div> 2265 {{/each}} 2266 </div> 2267 {{/compare}} 2268 2269 @* SERVER *@ 2270 {{#compare mainCategory '===' "SERVER"}} 2271 <div class="attribute-field-wrapper productlist-view"> 2272 {{#each categoryFieldsServer}} 2273 <div class="attribute-field-header">{{this.header}}</div> 2274 <div class="attribute-field-value">{{this.value}}</div> 2275 {{/each}} 2276 </div> 2277 {{/compare}} 2278 2279 @* STORAGE *@ 2280 {{#compare mainCategory '===' "STORAGE"}} 2281 <div class="attribute-field-wrapper productlist-view"> 2282 {{#each categoryFieldsStorage}} 2283 <div class="attribute-field-header">{{this.header}}</div> 2284 <div class="attribute-field-value">{{this.value}}</div> 2285 {{/each}} 2286 </div> 2287 {{/compare}} 2288 2289 @* MONITOR *@ 2290 {{#compare mainCategory '===' "MONITOR"}} 2291 <div class="attribute-field-wrapper productlist-view"> 2292 {{#each categoryFieldsMonitor}} 2293 <div class="attribute-field-header">{{this.header}}</div> 2294 <div class="attribute-field-value">{{this.value}}</div> 2295 {{/each}} 2296 </div> 2297 {{/compare}} 2298 2299 @* STANDARD FALLBACK*@ 2300 {{#compare_extended mainCategory '!==' "NOTEBOOK,PC,SERVER,STORAGE,MONITOR"}} 2301 <div class="attribute-field-wrapper productlist-view"> 2302 <div class="dcc-simple-desc">{{simpleDesc}}</div> 2303 </div> 2304 {{/compare_extended}} 2305 </div> 2306 </div> 2307 2308 2309 2310 2311 2312 2313 <div class="e-products-item-buy-container"> 2314 <div class="dcc-price-setup"> 2315 <div class="d-flex justify-content-end"> 2316 <div class=""> 2317 {{#compare isUserAuthenticated '||' hasDirectSale}} 2318 {{#if isActive}} 2319 <div class="dcc-flex-price d-flex my-flex-container-column mr-1 h-100"> 2320 {{#compare isCallForPrice '||' isNoPrice}} 2321 <button class="btn btn-block btn-call btn-secondary" data-target="#callForPrice-{{id}}" data-toggle="modal"> 2322 <i class="material-icons">phone</i> @Translate( "eCom Product - callforprice - Text", "Ring for pris" ) 2323 </button> 2324 {{else}} 2325 <span class="dcc-product-list-specifications-price">{{{price}}}</span> 2326 2327 {{/compare}} 2328 </div> 2329 {{/if}} 2330 {{/compare}} 2331 </div> 2332 <div class="d-flex flex-column" style="width: 44%;"> 2333 2334 2335 2336 <div class="dcc-flex-stock ml-auto mb-1"> 2337 <div class="dcc-product-list-specifications-stock-message"> 2338 {{#if isActive}} 2339 {{#if stockCheck}} 2340 <span class="dcc-custom-productlist-stockstatus dcc-stockstatus-instock"> 2341 <small>{{stock}} @Translate( "eCom Product - stock in - Text", "på lager" )</small> 2342 </span> 2343 {{else}} 2344 <span class="dcc-custom-productlist-stockstatus dcc-stockstatus-outofstock"> 2345 <small>@Translate( "eCom Product - stock out - Text", "Ikke på lager" )</small> 2346 </span> 2347 {{/if}} 2348 {{/if}} 2349 </div> 2350 </div> 2351 <div class="dcc-bottom-flex-wrapper"> 2352 2353 2354 {{#compare isUserAuthenticated '||' hasDirectSale}} 2355 <div class="dcc-flex-addtocart"> 2356 <div class="dcc-product-list-specifications-form-wrapper"> 2357 {{#if isActive}} 2358 {{#if isCallForPrice}} 2359 <button class="btn btn-block btn-call btn-secondary" data-target="#callForPrice-{{id}}" data-toggle="modal"> 2360 <i class="material-icons">phone</i> @Translate( "eCom Product - callforprice - Text", "Ring for pris" ) 2361 </button> 2362 {{else}} 2363 <form action="/system/data/cart" class="e-product-form js-e-product-form" method="post"> 2364 <input name="CartCmd" type="hidden" value="Add"> 2365 <input type="hidden" name="ProductID" value="{{id}}"> 2366 <input name="VariantID" type="hidden" value=""> 2367 <input name="UnitID" type="hidden" value=""> 2368 <input name="Redirect" type="hidden" value=""> 2369 <input type="hidden" value="false" name="EcomOrderLineFieldInput_IsConfigurable" /> 2370 <div class="dcc-product-list-add-to-cart-wrapper"> 2371 <input name="Quantity" type="number" value="1" autocomplete="off"> 2372 <button class="btn btn-primary" type="submit">@Translate( "eCom Product - Add To Cart - Button", "Add to cart" )</button> 2373 </div> 2374 </form> 2375 {{/if}} 2376 {{else}} 2377 <a class="btn btn-block btn-secondary" href="{{url}}"> 2378 <i class="material-icons">not_interested</i> @Translate( "eCom ProductList - NotforSale button - Text", "Varen er udgået" )</a> 2379 {{/if}} 2380 </div> 2381 </div> 2382 {{else}} 2383 {{#if isActive}} 2384 <div class="dcc-flex-addtocart text-right"> 2385 <a class="btn btn-secondary text-muted" href="{{url}}">@Translate( "eCom ProductList - ReadMore button - Text", "Læs mere" )</a> 2386 </div> 2387 {{else}} 2388 <a class="btn btn-block btn-secondary" href="{{url}}"> 2389 <i class="material-icons">not_interested</i> @Translate( "eCom ProductList - NotforSale button - Text", "Varen er udgået" )</a> 2390 {{/if}} 2391 2392 {{/compare}} 2393 </div> 2394 </div> 2395 </div> 2396 </div> 2397 2398 2399 <div class="d-flex mt-1"> 2400 2401 {{#if isActive}} 2402 {{#if isConfigurable}} 2403 <div class="small"> 2404 <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> 2405 </div> 2406 {{/if}} 2407 {{/if}} 2408 2409 {{#if isUserAuthenticated}} 2410 {{#if isActive}} 2411 <div class="small ml-auto"> 2412 <div class="dcc-product-list-item-add-to-favorites dropdown "> 2413 <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> 2414 <div class="dropdown-menu pt-0"> 2415 <h3 class="dropdown-header">@Translate( "eCom Product - Add to favorite list - Heading", "Add to ..." )</h3> 2416 <form action="" class="js-e-product-cc-list-form mt-1"> 2417 {{#each favoriteLists}} 2418 <div class="dropdown-item"> 2419 <label class="custom-checkbox custom-control m-0"> 2420 <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}}"> 2421 <span class="custom-control-indicator"></span> 2422 <span class="custom-control-description">{{name}}</span> 2423 </label> 2424 </div> 2425 {{/each}} 2426 </form> 2427 <div class="dropdown-divider"></div> 2428 <a class="dropdown-item" href="@PageView.Current().Area.Item[ "ExtranetListsPage" ]"> 2429 <i class="material-icons">add</i> @Translate( "eCom Product - Add new favorite list - Link", "Create a new list" )</a> 2430 </div> 2431 </div> 2432 </div> 2433 {{/if}} 2434 {{/if}} 2435 </div> 2436 </div> 2437 </div> 2438 </div> 2439 </div> 2440 2441 2442 </script> 2443 2444 </div> 2445 2446 <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"> 2447 @if ( specificationCategory.Any() == true || ( PIMspecificationCategory != null && PIMspecificationCategory.FieldValues != null ) ) 2448 { 2449 2450 2451 2452 @sectionStart( 2453 sectionClasses: "e-section pt-4 pb-3", 2454 sectionCollapse: false, 2455 contentClasses: "col-12", 2456 collapseToggleTextExpand: Translate( "eCom Product - View more - Text", "View more" ), 2457 collapseToggleTextCollapse: Translate( "eCom Product - View less - Text", "View less" ) 2458 ) 2459 <div class="col-12"> 2460 <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> 2461 2462 @if ( PIMspecificationCategory != null && PIMspecificationCategory.FieldValues.Any() ) 2463 { 2464 <p class="mb-1"> 2465 <strong class="font-headings">@Translate( String.Format( "productCategory_Render_Label_{0}", PIMspecificationCategory.Name ), PIMspecificationCategory.Name )</strong> 2466 </p> 2467 2468 <table class="dcc-product-detail-specifications-table mb-5 table"> 2469 @if (PIMspecificationCategory.FieldValues != null) 2470 { 2471 2472 foreach ( SpecificationField sf in PIMspecificationCategory.FieldValues ) 2473 { 2474 <tr style="line-height: 1.2;"> 2475 @if ( string.IsNullOrEmpty( sf.Value ) == false ) 2476 { 2477 <td class="dcc-product-detail-specifications-table-title" style="width: 50%"> 2478 <small>@sf.Name</small> 2479 </td> 2480 <td class="dcc-product-detail-specifications-table-value" style="width: 50%">@sf.Value.Replace( "U0022", "\"" )</td> 2481 } 2482 </tr> 2483 } 2484 } 2485 </table> 2486 } 2487 2488 @if ( specificationCategory != null ) 2489 { 2490 foreach ( SpecificationCategory sc in specificationCategory ) 2491 { 2492 if ( sc.FieldValues != null && sc.FieldValues.Any() ) 2493 { 2494 <p class="mb-1"> 2495 <strong class="font-headings">@Translate( String.Format( "productCategory_Render_Label_{0}", sc.Name ), sc.Name )</strong> 2496 </p> 2497 2498 <table class="dcc-product-detail-specifications-table mb-5 table"> 2499 @foreach ( SpecificationField sf in sc.FieldValues ) 2500 { 2501 <tr style="line-height: 1.2;"> 2502 @if ( string.IsNullOrEmpty( sf.Value ) == false ) 2503 { 2504 <td class="dcc-product-detail-specifications-table-title" style="width: 50%"> 2505 <small>@sf.Name</small> 2506 </td> 2507 <td class="dcc-product-detail-specifications-table-value" style="width: 50%">@sf.Value.Replace( "U0022", "\"" )</td> 2508 } 2509 </tr> 2510 } 2511 </table> 2512 } 2513 } 2514 } 2515 2516 2517 </div> 2518 2519 @sectionEnd() 2520 } 2521 2522 </div> 2523 @if ( configurationShow ) 2524 { 2525 <div class="tab-pane fade @(configurationShow ? "active show" : string.Empty)" id="dcc-productpage-tab-content-config" role="tabpanel" aria-labelledby="dcc-productpage-tab-config"> 2526 @{ 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"> 2527 @* 2528 <a class="close js-dcc-configurator-overview-mobile-handle p-1 d-block d-lg-none"><i class="material-icons">close</i></a> 2529 *@ 2530 <form action="/shop/cart" class="js-dcc-configurator-configuration-form" method="post"> 2531 2532 <div class="js-dcc-configurator-overview-container "> 2533 <script id="js-e-handlebars-tmpl-configurator-overview" type="text/x-handlebars-template"> 2534 <div class="dcc-configurator-overview-price mt-0 bg-light"> 2535 <div class="dcc-configurator-overview-price-base bg-light py-1 px-2 d-flex justify-content-between border-bottom" > 2536 <span> 2537 <h5 class="m-0 dcc-configurator-overview-price-lg">@Translate( "DCC - Configurator - Overview - Total Price", "Pris inkl. tilpasning" )</h5> 2538 </span> 2539 <span> 2540 <h5 class="m-0 dcc-configurator-overview-price-lg">@Context.Currency.Code @Translate( "eCom - Product Price - Ex. VAT - Text" )</h5> 2541 </span> 2542 </div> 2543 {{#if hasBeforePrice}} 2544 <div class="dcc-configurator-overview-price-base bg-light py-1 px-2 d-flex justify-content-between border-bottom" > 2545 <span> 2546 <h5 class="m-0 text-muted">@Translate( "DCC - Configurator - Overview - Base Price", "Basis" )</h5> 2547 </span> 2548 <span> 2549 <h5 class="m-0 text-muted text-line-through">{{{baseBeforePrice}}}</h5> 2550 </span> 2551 </div> 2552 <div class="dcc-configurator-overview-price-base bg-light py-1 px-2 d-flex justify-content-between border-bottom" > 2553 <span> 2554 <h5 class="m-0 text-muted dcc-configurator-overview-price-lg">@Translate( "DCC - Configurator - Overview - Discount Price", "Tilbudspris" )</h5> 2555 </span> 2556 <span> 2557 <h5 class="m-0 text-muted dcc-configurator-overview-price-lg">{{{basePrice}}}</h5> 2558 </span> 2559 </div> 2560 {{else}} 2561 <div class="dcc-configurator-overview-price-base bg-light py-1 px-2 d-flex justify-content-between border-bottom"> 2562 <span> 2563 <h5 class="m-0 text-muted">@Translate( "DCC - Configurator - Overview - Base Price", "Basis" )</h5> 2564 </span> 2565 <span> 2566 <h5 class="m-0 text-muted">{{{basePrice}}}</h5> 2567 </span> 2568 </div> 2569 {{/if}} 2570 {{#hasCategories categories}} 2571 <div class="dcc-configurator-overview-price-base bg-light py-1 px-2 border-bottom" > 2572 {{#each categories}} 2573 {{#isNotDefaultPartInCategory this}} 2574 <p class="mb-0 small"> 2575 <strong>{{label}}</strong> 2576 </p> 2577 <ul class="list-group list-group-flush m-0 p-0"> 2578 {{#each parts}} 2579 <li class="list-group-item bg-light border-0 small m-0 p-0"> 2580 <div class="container"> 2581 <div class="row"> 2582 <div class="col-8"> 2583 <h5 class="text-ellipsis text-muted"> 2584 {{#compare @@../key '===' 'keyboardsinternal'}} 2585 {{keyboardLang}} 2586 {{else}} 2587 {{#compare number '===' 'OSLOther'}} 2588 <span class="js-dcc-configurator-overview-custom-os-language-label">{{getCustomOsLanguagePartName partOsLanguage}}</span> 2589 {{else}} 2590 {{label}} 2591 {{/compare}} 2592 2593 {{/compare}} 2594 </h5> 2595 </div> 2596 <div class="col-4 pr-0 text-right"> 2597 <h5 class="text-muted"> 2598 {{#if isDefault}} 2599 @Translate("DCC - Configurator - List - Default - Text", "Basic") 2600 {{else}} 2601 {{#compare price '>' 0}}+{{/compare}}{{{priceFormatted}}} 2602 {{/if}} 2603 </h5> 2604 </div> 2605 </div> 2606 </div> 2607 </li> 2608 {{/each}} 2609 </ul> 2610 {{/isNotDefaultPartInCategory}} 2611 {{/each}} 2612 </div> 2613 {{/hasCategories}} 2614 {{#if price.intSupportPrice}} 2615 <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"> 2616 <span> 2617 <h5 class="m-0 text-muted"> 2618 @Translate( "DCC - Configurator - Overview - Service Fee", "Serviceafgift" ) 2619 <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" )"> 2620 <i class="material-icons material-icons-large ml-1">info</i> 2621 </span> 2622 </h5> 2623 </span> 2624 <span> 2625 <h5 class="m-0 text-muted">{{{price.strSupportPrice}}}</h5> 2626 </span> 2627 </div> 2628 {{/if}} 2629 {{#compare warranty.data.intPrice '>' 0}} 2630 <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"> 2631 <span> 2632 <h5 class="m-0 text-muted"> 2633 @Translate( "DCC - Configurator - Overview - Warranty - Header", "Udvidet garanti" ) 2634 </h5> 2635 </span> 2636 <span> 2637 <h5 class="m-0 text-muted">+{{{warranty.data.strPrice}}}</h5> 2638 </span> 2639 </div> 2640 {{/compare}} 2641 {{#compare autopilot.intPrice '>' 0}} 2642 <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"> 2643 <span> 2644 <h5 class="m-0 text-muted"> 2645 Autopilot 2646 </h5> 2647 </span> 2648 <span> 2649 <h5 class="m-0 text-muted">+{{{autopilot.strPrice}}}</h5> 2650 </span> 2651 </div> 2652 {{/compare}} 2653 <div class="dcc-configurator-overview-price-configured js-dcc-configurator-overview-price-configured py-1 px-2 mb-0 justify-content-between d-flex "> 2654 <span> 2655 <h5 class="dcc-configurator-overview-price-lg m-0">@Translate( "DCC - Configurator - Overview - Your Price", "Din pris" )</h5> 2656 </span> 2657 <span> 2658 <h5 class="m-0 dcc-configurator-overview-price-lg">{{{price.strPrice}}}</h5> 2659 </span> 2660 </div> 2661 </div> 2662 {{#if isLeasingAllowed}} 2663 <div class="card shadow-none border-0 bg-light"> 2664 <div class="card-header py-1 px-0 border-bottom bg-white" id="leasingCollapseHeader"> 2665 <h3 class="mb-0"> 2666 <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"> 2667 <span class="collapse-text font-weight-bold">@Translate( "DCC - Configurator - Overview - Leasing - Header", "Leasing" )</span> 2668 </a> 2669 </h3> 2670 </div> 2671 <div id="leasingCollapse" class="js-dcc-configurator-overview-leasing-collapse collapse {{#if leasing.open}}show{{/if}}" aria-labelledby="leasingCollapseHeader"> 2672 <div class="card-body py-1 bg-white"> 2673 <div class="small"> 2674 <div class="row"> 2675 <div class="col-12 mb-2 mb-lg-0 small"> 2676 <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> 2677 </div> 2678 </div> 2679 </div> 2680 </div> 2681 </div> 2682 </div> 2683 {{/if}} 2684 2685 @using Co3.Espresso.Base.Extensions 2686 @using Dynamicweb.Security.UserManagement 2687 2688 @if (User.IsExtranetUserLoggedIn() && autoPilotPrice > 0) 2689 { 2690 2691 <div class="card shadow-none border-0 bg-light"> 2692 <div class="card-header py-1 px-0 border-bottom bg-white" id="leasingCollapseHeader"> 2693 <h3 class="mb-0"> 2694 <a class="d-flex p-0 collapse-header" data-toggle="collapse" data-target="#autopilotCollapse" aria-expanded="{{#if autopilot.open}}true{{else}}false{{/if}}" aria-controls="autopilotCollapse"> 2695 <span class="collapse-text font-weight-bold"> 2696 @Translate("DCC - Configurator - Overview - Autopilot - Header", "Autopilot") 2697 </span> 2698 </a> 2699 </h3> 2700 </div> 2701 <div id="autopilotCollapse" class="js-dcc-configurator-overview-autopilot-collapse collapse {{#if autopilot.open}}show{{/if}}" aria-labelledby="autopilotCollapseHeader"> 2702 <div class="card-body py-1 bg-white"> 2703 <div class="small"> 2704 <div class="row"> 2705 <div class="col-12 col-lg-6 mb-2 mb-lg-0 small"> 2706 <label> 2707 <input class="js-dcc-configurator-overview-autopilot-checkbox" type="checkbox" data-price="@autoPilotPrice" {{#if autopilot.checked}}checked{{/if}}/> 2708 @Translate("DCC - Configurator - Overview - Autopilot - Add - Text", "Tilføj Autopilot") 2709 </label> 2710 </div> 2711 <div class="col-12 col-lg-6 mb-2 mb-lg-0 small text-right"> 2712 @Co3.DCC.Dw.Services.ProductService.Instance.GetPriceFormatted(autoPilotPrice) 2713 </div> 2714 </div> 2715 <div class="row"> 2716 <div class="col-12"> 2717 <div id="js-dcc-autopilot-config-collapse" class="collapse {{#if autopilot.checked}}show{{/if}}"> 2718 <div class="form-group my-1"> 2719 <label for="autopilotEmailConfig">@Translate("DCC - Configurator - Overview - Autopilot - Email - Text", "Email address")</label> 2720 <input type="email" class="form-control js-dcc-configurator-autopilot-email-value" id="autopilotEmailConfig" value="@(User.IsExtranetUserLoggedIn() ? User.GetCurrentUser().Email : string.Empty)"> 2721 </div> 2722 </div> 2723 </div> 2724 </div> 2725 </div> 2726 </div> 2727 </div> 2728 </div> 2729 2730 } 2731 <div class="dcc-configurator-overview-action mb-2 py-1"> 2732 <div class="row"> 2733 <div class="col-12 col-lg-4"> 2734 </div> 2735 <div class="col-12 col-lg-8"> 2736 <div class="dcc-flex-stock mt-1 mb-1 d-flex justify-content-end"> 2737 <div class="dcc-product-list-specifications-stock-message"> 2738 @if ( stockCheck ) 2739 { 2740 <span class="dcc-custom-product-details-stockstatus dcc-stockstatus-instock"> 2741 <small>@stockNumber @Translate( "eCom Product - stock in - Text", "på lager" )</small> 2742 </span> 2743 } 2744 else 2745 { 2746 <span class="dcc-custom-product-details-stockstatus dcc-stockstatus-outofstock"> 2747 <small>@Translate( "eCom Product - stock out - Text", "Ikke på lager" )</small> 2748 </span> 2749 } 2750 </div> 2751 </div> 2752 @if (hasPrice) 2753 { 2754 <div class="dcc-product-details-add-to-cart-wrapper"> 2755 <input name="Quantity" class="js-dcc-configurator-quantity" type="number" value="{{quantity}}" autocomplete="off"> 2756 2757 <button class="btn btn-primary" type="submit"> 2758 {{#if isEditing}} 2759 @Translate( "DCC - Configurator - Add To Cart - Update - Text", "Opdater" ) 2760 {{else}} 2761 @Translate( "DCC - Configurator - Add To Cart - Text", "Læg i kurv" ) 2762 {{/if}} 2763 </button> 2764 2765 2766 </div> 2767 } 2768 </div> 2769 </div> 2770 2771 2772 </div> 2773 2774 <input name="CartCmd" type="hidden" value="add" /> 2775 <input name="Redirect" type="hidden" value="false" /> 2776 <input name="ProductID" type="hidden" value="@GetString( "Ecom:Product.ID" )" /> 2777 <input id="VariantID" name="VariantID" type="hidden" value="@GetString( "Ecom:Product.VariantID" )"> 2778 <input id="UnitID" name="UnitID" type="hidden" value=""> 2779 2780 2781 <input class="js-dcc-configurator-orderline-field js-dcc-configurator-overview-leasing-input-rate" name="EcomOrderLineFieldInput_leasing_rate" type="hidden" value="{{leasing.rate}}" /> 2782 <input class="js-dcc-configurator-orderline-field js-dcc-configurator-overview-leasing-price-input" name="EcomOrderLineFieldInput_leasing_price" type="hidden" value="{{leasing.price}}" /> 2783 <input class="js-dcc-configurator-orderline-field js-dcc-configurator-overview-leasing-checked" name="EcomOrderLineFieldInput_leasing_checked" type="hidden" value="{{leasing.checked}}" /> 2784 2785 <input class="js-dcc-configurator-orderline-field js-dcc-configurator-overview-autopilot-email-input" name="EcomOrderLineFieldInput_AutopilotEmail" type="hidden" value="{{autopilot.email}}" /> 2786 <input class="js-dcc-configurator-orderline-field js-dcc-configurator-overview-autopilot-checked" name="EcomOrderLineFieldInput_Autopilot" type="hidden" value="{{autopilot.checked}}" /> 2787 2788 <input class="js-dcc-configurator-overview-has-configuration" type="hidden" value="{{hasConfiguration}}" name="EcomOrderLineFieldInput_HasConfiguration" /> 2789 {{#if hasConfiguration}} 2790 <input type="hidden" value="true" name="EcomOrderLineFieldInput_IsConfigurable" /> 2791 {{#each categories}} 2792 {{#each parts}} 2793 2794 <input name="{{../id}}" type="hidden" value="{{id}}"> 2795 <input name="EcomOrderLineFieldInput_BomItemProductCategory{{../id}}" type="hidden" value="{{../label}}" /> 2796 <input name="EcomOrderLineFieldInput_SlotName{{../id}}" type="hidden" value="{{slotName}}" /> 2797 <input name="EcomOrderLineFieldInput_isDefault{{../id}}" type="hidden" value="{{isDefault}}" /> 2798 2799 {{/each}} 2800 2801 {{#compare @@key '===' 'oslanguage'}} 2802 <input class="js-dcc-configurator-orderline-field js-dcc-configurator-overview-custom-os-language" name="EcomOrderLineFieldInput_OSLanguageCustom{{id}}" type="hidden" value="{{partOsLanguage}}" /> 2803 {{/compare}} 2804 {{/each}} 2805 2806 {{/if}} 2807 </script> 2808 </div> 2809 </form> 2810 </div> </div> </div> </div> </div> @sectionEnd() <script> 2811 @inherits RazorTemplateBase< RazorTemplateModel< Template > > 2812 @inherits Co3.Espresso.Website.TemplateBases.Pages.PageBase 2813 @using Dynamicweb.Security.UserManagement 2814 @using System.Linq 2815 @using System.Collections.Generic 2816 @using Dynamicweb.Ecommerce.Products; 2817 @using Co3.Espresso.Website.Services 2818 @using ProductService = Co3.Espresso.Website.Services.ProductService 2819 @using Co3.DCC.Dw.Models.FrontEnd 2820 @using Dynamicweb.Frontend 2821 @{ 2822 if ( productObject != null && productObject.Items != null ) 2823 { 2824 int configurableCounter = 3; 2825 foreach ( ProductItem item in productObject.Items ) 2826 { 2827 User user = Co3.DCC.Dw.Services.CustomerService.Instance.GetCurrentUser(); 2828 2829 if ( item != null ) 2830 { 2831 ConfigurationId configId = Co3.DCC.Dw.Services.ProductService.Instance.GetConfigurationIdByProductItem( productObject, item ); 2832 string configurationId = string.Empty; 2833 string itemName = string.IsNullOrEmpty( item.Name ) ? string.Empty : item.Name; 2834 2835 string groupId = itemName.ToLower().Replace( " ", string.Empty ).Replace( "|", "_" ); 2836 2837 configurableCounter++; 2838 2839 int sortKey = configurableCounter; 2840 2841 if ( itemName.Equals( Co3.DCC.Data.Utilities.Constants.KEYBOARD_INTERNAL_CONFIGURATION_GROUP_ID ) ) 2842 { 2843 sortKey = 0; 2844 } 2845 2846 if ( itemName.Split( '|' )[ 0 ].Equals( Co3.DCC.Data.Utilities.Constants.MEMORY_CONFIGURATION_GROUP_ID ) ) 2847 { 2848 sortKey = 1; 2849 } 2850 2851 string groupKey = sortKey + "_" + itemName.ToLower().Replace( " ", string.Empty ).Replace( "|", "_" ); 2852 2853 bool addGroup = true; 2854 2855 if ( configId != null && addGroup == true && JSON.configurables.ContainsKey( groupKey ) == false ) 2856 { 2857 JSON.configurables[ groupKey ] = new List< dynamic >(); 2858 2859 dynamic configurable = new 2860 { 2861 id = groupId, 2862 sortKey = sortKey, 2863 slot = itemName.Split( '|' )[ 0 ], 2864 editableName = itemName.ToLower(), 2865 bomId = item.Id, 2866 label = Translate( string.Format( "DCC - Configurator - List - Category - Label - {0}", itemName ), itemName ), 2867 configurationId = configurationId, 2868 parts = new List< dynamic >(), 2869 languageParts = new List< dynamic >(), 2870 keyboardLanguages = new List< dynamic >(), 2871 hasDefault = true, 2872 configId = configId, 2873 isOSConfigurable = isOSConfigurable, 2874 isLocked = configId.IsLocked, 2875 hasLanguages = itemName.Equals( Co3.DCC.Data.Utilities.Constants.KEYBOARD_INTERNAL_CONFIGURATION_GROUP_ID ), 2876 aidebug = item.Products.Count() 2877 }; 2878 if ( item.Products != null ) 2879 { 2880 List<object> partObjects = new List<object>(); 2881 2882 foreach ( Product part in item.Products.OrderByDescending( p => p.Stock ) ) 2883 { 2884 object partObj = getPartsObj( productObject, item, part, user ); 2885 2886 partObjects.Add(partObj); 2887 } 2888 2889 foreach ( object partObj in partObjects ) 2890 { 2891 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) ))) 2892 { 2893 if ( itemName.Equals( Co3.DCC.Data.Utilities.Constants.KEYBOARD_INTERNAL_CONFIGURATION_GROUP_ID ) == false ) 2894 { 2895 if ( partObj != null ) 2896 { 2897 configurable.parts.Add( partObj ); 2898 } 2899 } 2900 else 2901 { 2902 if ( partObj != null ) 2903 { 2904 configurable.languageParts.Add( partObj ); 2905 } 2906 } 2907 } 2908 } 2909 foreach ( Product part in item.Products.OrderByDescending( p => p.Stock ) ) 2910 { 2911 object partObj = getPartsObj( productObject, item, part, user, configurable.languageParts ); 2912 2913 if ( itemName.Equals( Co3.DCC.Data.Utilities.Constants.KEYBOARD_INTERNAL_CONFIGURATION_GROUP_ID ) == true ) 2914 { 2915 if ( partObj != null && configurable.parts.Count == 0 ) 2916 { 2917 configurable.parts.Add( partObj ); 2918 } 2919 } 2920 } 2921 2922 JSON.configurables[ groupKey ].Add( configurable ); 2923 } 2924 } 2925 } 2926 } 2927 } 2928 } 2929 2930 e4.data.set('dcc.configurator.data.json', @JsonService.Instance.ToJson( JSON )); 2931 </script> 2932 2933 @functions 2934 { 2935 2936 public object getPartsObj( Product productObject, ProductItem item, Product part, User user, dynamic languages = null ) 2937 { 2938 if ( user == null ) 2939 { 2940 return null; 2941 } 2942 Dynamicweb.Ecommerce.Products.ProductService dwProductService = new Dynamicweb.Ecommerce.Products.ProductService(); 2943 ConfigurationDetails configurationDetails = Co3.DCC.Dw.Services.ProductService.Instance.GetConfigurationDetails( productObject ); 2944 2945 if ( configurationDetails != null ) 2946 { 2947 ConfigurationGroupDetails configurationGroupDetails = Co3.DCC.Dw.Services.ProductService.Instance.GetConfigurationGroupDetails( productObject, part, user ); 2948 ConfigurationGroup partConfigurationGroup = new ConfigurationGroup(); 2949 ConfigurationId configId = Co3.DCC.Dw.Services.ProductService.Instance.GetConfigurationIdByProductItem( productObject, item ); 2950 2951 string configValue = string.Empty; 2952 string configUOM = string.Empty; 2953 string translationKey = string.Empty; 2954 2955 if ( configId != null ) 2956 { 2957 configValue = configId.Value; 2958 configUOM = configId.UOM; 2959 } 2960 2961 string productLink = ProductService.Instance.GetProductLink( part.PrimaryGroupId, part.Id ); 2962 productLink = SearchEngineFriendlyURLs.GetFriendlyUrl( productLink ); 2963 string partName = configurationDetails.Items.ContainsKey( part.Number ) ? configurationDetails.Items[ part.Number ].Description : part.Name; 2964 partName = ConfiguratorPartName( partName ); 2965 2966 string keyboardLangTranslated = string.Empty; 2967 string keyboardLangDefaultTranslated = string.Empty; 2968 2969 if ( partName == "OSLDefault" ) 2970 { 2971 string OSLDefaultTranslationKey = string.Format( "DCC - Configurator - List - OS Language - {0} - Label", Co3.DCC.Dw.Services.ProductService.Instance.GetCategoryValue( productObject, "ItemAttributes", "Software_Language" ) ); 2972 partName = Translate( OSLDefaultTranslationKey, Co3.DCC.Dw.Services.ProductService.Instance.GetCategoryValue( productObject, "ItemAttributes", "Software_Language" ) ); 2973 } 2974 2975 if ( item.Name.Equals( Co3.DCC.Data.Utilities.Constants.KEYBOARD_INTERNAL_CONFIGURATION_GROUP_ID ) ) 2976 { 2977 string keyboardLangStr = Co3.DCC.Dw.Services.ProductService.Instance.GetCategoryValue( part, "ItemAttributes", "Keyboard_Language" ); 2978 string keyboardDefaultLangStr = Co3.DCC.Dw.Services.ProductService.Instance.GetCategoryValue( productObject, "ItemAttributes", "Keyboard_Language" ); 2979 string translatedPartNameKey = string.Format( "ProductListItem_Keyboard_Language_ID_{0}", keyboardLangStr ); 2980 string translatedDefaultPartNameKey = string.Format( "ProductListItem_Keyboard_Language_ID_{0}", keyboardDefaultLangStr ); 2981 keyboardLangTranslated = Translate( translatedPartNameKey, keyboardLangStr ); 2982 keyboardLangDefaultTranslated = Translate( translatedDefaultPartNameKey, keyboardDefaultLangStr ); 2983 } 2984 2985 string itemNameSplit = item.Name.Split( '|' )[ 0 ]; 2986 2987 if ( part.Number == Co3.DCC.Data.Utilities.Constants.ECOMMERCE_PRODUCT_NOTHING_SELECTED_PRODUCTNUMBER ) 2988 { 2989 partName = Co3.DCC.Dw.Services.ProductService.Instance.GetDefaultPartName(productObject, item); 2990 2991 if (string.IsNullOrEmpty(partName)) 2992 { 2993 partName = Translate( "DCC - Configurator - List - Nothing Selected - Text", "Nothing Selected" ); 2994 } 2995 2996 //if ( item.Name == "DRIVES|1" ) 2997 //{ 2998 // partName = Co3.DCC.Dw.Services.ProductService.Instance.GetCategoryValue( productObject, "ItemAttributes", "HDDTEXT1" ); 2999 //} 3000 //else 3001 //{ 3002 // partName = Translate( "DCC - Configurator - List - Nothing Selected - Text", "Nothing Selected" ); 3003 //} 3004 } 3005 3006 3007 object partCondition = dwProductService.GetProductFieldValue( part, "Condition" ); 3008 3009 3010 string partConfigurationKey = $"{itemNameSplit}.{configValue}.{configUOM}.{partCondition}"; 3011 3012 bool partIsDefault = Co3.DCC.Dw.Services.ProductService.Instance.IsDefaultBOMProduct( configurationDetails, productObject, item, part ); 3013 3014 double partSupportPrice = 0; 3015 double partCombinedSupportPrice = 0; 3016 3017 if ( configurationGroupDetails != null ) 3018 { 3019 ConfigurationGroup specificConfigurationGroup = configurationGroupDetails.BOM != null ? configurationGroupDetails.BOM : configurationGroupDetails.Default; 3020 if ( specificConfigurationGroup != null ) 3021 { 3022 partSupportPrice = specificConfigurationGroup.SupportPrices.PriceByCurrency[ user.Currency ]; 3023 partCombinedSupportPrice = specificConfigurationGroup.SupportPrices.CombinedPriceByCurrency[ user.Currency ]; 3024 } 3025 } 3026 3027 Co3.DCC.Data.DAL.Models.Price originalPrice = Co3.DCC.Dw.Services.PriceService.Instance.GetProductPriceForBOM( productObject, part, user, item.Name ); 3028 3029 dynamic partObj = new 3030 { 3031 id = part.Id, 3032 number = part.Number, 3033 bomId = item.BomGroupId, 3034 variantId = part.VariantId, 3035 label = partName, 3036 itemNameSplit = itemNameSplit, 3037 slotName = item.Name, 3038 url = productLink, 3039 description = part.ShortDescription, 3040 isDefault = partIsDefault, 3041 hasDefault = false, 3042 isActive = part.IsActive, 3043 hasLanguages = item.Name.Equals( Co3.DCC.Data.Utilities.Constants.KEYBOARD_INTERNAL_CONFIGURATION_GROUP_ID ), 3044 inputType = "radio", 3045 defaultLanguage = keyboardLangDefaultTranslated, 3046 defaultLanguageLanguageTranslated = keyboardLangTranslated, 3047 price = originalPrice.PriceAmount, 3048 priceFormatted = originalPrice.PriceAmount.ToString( "N2" ), 3049 priceDiff = originalPrice.PriceAmount, 3050 priceDiffFormatted = Co3.DCC.Dw.Services.ProductService.Instance.GetPriceFormatted( originalPrice.PriceAmount ), 3051 originalPriceObj = new 3052 { 3053 price = originalPrice.PriceAmount, 3054 priceFormatted = originalPrice.PriceAmount.ToString( "N2" ) 3055 }, 3056 condition = partCondition, 3057 partConfigurationGroup = partConfigurationGroup, 3058 supportPrice = partSupportPrice, 3059 combinedSupportPrice = partCombinedSupportPrice, 3060 stock = part.Stock, 3061 languages = languages, 3062 keyboardLang = Co3.DCC.Dw.Services.ProductService.Instance.GetCategoryValue( part, "ItemAttributes", "Keyboard_Language" ), 3063 keyboardLangTranslated = keyboardLangTranslated, 3064 osLang = string.Format( "OSL{0}", Co3.DCC.Dw.Services.ProductService.Instance.GetCategoryValue( productObject, "ItemAttributes", "Software_Language" ) ), 3065 configurationValue = configurationGroupDetails, 3066 userCurrency = user.Currency, 3067 isDefaultDebug = partIsDefault 3068 }; 3069 3070 bool addPart = configurationGroupDetails != null || part.Id == "PROD1"; 3071 3072 if ( item.Name.Equals( Co3.DCC.Data.Utilities.Constants.KEYBOARD_INTERNAL_CONFIGURATION_GROUP_ID ) && part.Stock <= 0 && part.Id != "PROD1" ) 3073 { 3074 if ( !partIsDefault ) 3075 { 3076 addPart = false; 3077 } 3078 } 3079 3080 if ( addPart == true ) 3081 { 3082 return partObj; 3083 } 3084 } 3085 return null; 3086 } 3087 3088 } 3089 </div> 3090 } 3091 </div> 3092 </div> 3093 3094 @sectionEnd() 3095 3096 3097 @if ( string.IsNullOrEmpty( GetString( "Ecom:Product:Field.Marketingdescription.Value.Clean" ) ) == false || string.IsNullOrEmpty( GetString( "Ecom:Product:Field.ProductFeatures.Value.Clean" ) ) == false ) 3098 { 3099 @sectionStart( 3100 sectionClasses: "e-section pt-4 pb-4 dcc-product-detail-longdescription-container", 3101 sectionCollapse: true, 3102 contentClasses: "col-12 col-md-10 col-lg-6 mx-auto", 3103 collapseToggleTextExpand: Translate( "eCom Product - View more - Text", "View more" ), 3104 collapseToggleTextCollapse: Translate( "eCom Product - View less - Text", "View less" ) 3105 ) 3106 3107 <div class="col-12"> 3108 <h2 class="text-center">@Translate( "eCom Product - Egenskaber - Heading", "Egenskaber" )</h2> 3109 <p class="lead text-center">@GetString( "Ecom:Product:Field.Marketingdescription.Value.Clean" )</p> 3110 @GetString( "Ecom:Product:Field.ProductFeatures.Value.Clean" ) 3111 </div> 3112 3113 if ( string.IsNullOrEmpty( GetString( "Ecom:Product:Field.Video" ) ) == false ) 3114 { 3115 <div class="col-12 mt-3 text-center"> 3116 @if ( string.IsNullOrEmpty( GetString( "Ecom:Product:Field.VideoHeading" ) ) == false ) 3117 { 3118 <h2 class="mb-2">@GetString( "Ecom:Product:Field.VideoHeading" )</h2> 3119 } 3120 <div class="embed-responsive embed-responsive-16by9 mb-3"> 3121 <iframe class="embed-responsive-item" src="@GetString( "Ecom:Product:Field.Video" )" width="1080" height="608" frameborder="0" webkitallowfullscreen mozallowfullscreen allowfullscreen></iframe> 3122 </div> 3123 </div> 3124 } 3125 @sectionEnd() 3126 } 3127 3128 3129 3130 @sectionEnd() 3131 @sectionStart( 3132 sectionClasses: "e-section pt-4 pb-4", 3133 sectionCollapse: false, 3134 contentClasses: "col-12 col-md-10 col-lg-6 mx-auto" 3135 ) 3136 3137 <a id="condition"></a> 3138 <span class="dcc-product-details-badge mx-auto mb-2 @conditionClass"> 3139 <span class="dcc-product-details-badge-title">@condition</span> 3140 </span> 3141 @if ( conditionClass == "dcc-condition-01new" && !string.IsNullOrEmpty(Espresso.Area.Item.ConditionNew) ) 3142 { 3143 @RenderPageContent( Convert.ToInt32(Espresso.Area.Item.ConditionNew) ) 3144 } 3145 @if ( conditionClass == "dcc-condition-gold" && !string.IsNullOrEmpty(Espresso.Area.Item.ConditionGold)) 3146 { 3147 @RenderPageContent( Convert.ToInt32(Espresso.Area.Item.ConditionGold) ) 3148 } 3149 @if ( conditionClass == "dcc-condition-silver" && !string.IsNullOrEmpty(Espresso.Area.Item.ConditionSilver)) 3150 { 3151 @RenderPageContent( Convert.ToInt32(Espresso.Area.Item.ConditionSilver) ) 3152 } 3153 @if ( conditionClass == "dcc-condition-bronze" && !string.IsNullOrEmpty(Espresso.Area.Item.ConditionBronze)) 3154 { 3155 @RenderPageContent( Convert.ToInt32(Espresso.Area.Item.ConditionBronze) ) 3156 } 3157 @if ( conditionClass == "dcc-condition-02bulk" && !string.IsNullOrEmpty(Espresso.Area.Item.ConditionBulk)) 3158 { 3159 @RenderPageContent( Convert.ToInt32(Espresso.Area.Item.ConditionBulk) ) 3160 } 3161 @if ( conditionClass == "dcc-condition-demo" && !string.IsNullOrEmpty(Espresso.Area.Item.ConditionDemo)) 3162 { 3163 @RenderPageContent( Convert.ToInt32(Espresso.Area.Item.ConditionDemo) ) 3164 } 3165 @if ( conditionClass == "dcc-condition-gradea" && !string.IsNullOrEmpty(Espresso.Area.Item.ConditionGradeA)) 3166 { 3167 @RenderPageContent( Convert.ToInt32(Espresso.Area.Item.ConditionGradeA) ) 3168 } 3169 @if ( conditionClass == "dcc-condition-gradeb" && !string.IsNullOrEmpty(Espresso.Area.Item.ConditionGradeB)) 3170 { 3171 @RenderPageContent( Convert.ToInt32(Espresso.Area.Item.ConditionGradeB) ) 3172 } 3173 @if ( conditionClass == "dcc-condition-gradec" && !string.IsNullOrEmpty(Espresso.Area.Item.ConditionGradeC)) 3174 { 3175 @RenderPageContent( Convert.ToInt32(Espresso.Area.Item.ConditionGradeC) ) 3176 } 3177 @if ( conditionClass == "dcc-condition-04exdemo" && !string.IsNullOrEmpty(Espresso.Area.Item.ConditionExdemo)) 3178 { 3179 @RenderPageContent( Convert.ToInt32(Espresso.Area.Item.ConditionExdemo) ) 3180 } 3181 @if ( conditionClass == "dcc-condition-08ref" && !string.IsNullOrEmpty(Espresso.Area.Item.ConditionRefurbished)) 3182 { 3183 @RenderPageContent( Convert.ToInt32(Espresso.Area.Item.ConditionRefurbished) ) 3184 } 3185 @if ( conditionClass == "dcc-condition-premium" && !string.IsNullOrEmpty(Espresso.Area.Item.ConditionPremium)) 3186 { 3187 @RenderPageContent( Convert.ToInt32(Espresso.Area.Item.ConditionPremium) ) 3188 } 3189 3190 3191 @sectionEnd() 3192 3193 @* 3194 @if ( isExtranet ) 3195 { 3196 @sectionStart( 3197 sectionClasses: "e-section pt-4 pb-4 bg-light", 3198 sectionCollapse: false, 3199 contentClasses: "col-12 col-md-10 col-lg-6 mx-auto" 3200 ) 3201 3202 @RenderParagraphContent( 12003 ) 3203 3204 @sectionEnd() 3205 } 3206 *@ 3207 3208 @DCCProductListPlain( 3209 heading: Translate( "eCom Product - Recently viewed items - Heading", "Recently viewed items" ), 3210 productLoop: GetLoop( "eCom:Related.YouHaveSeenTheseProducts" ).Take( 4 ), 3211 sectionClasses: "e-section p-section p-section-border-top dcc-productlist-presentation-grid" 3212 ) 3213 3214 3215 <script type="application/ld+json"> 3216 { 3217 "@@context" : "http://schema.org", 3218 "@@type" : "Product", 3219 "description" : "@GetString("Ecom:Product.ShortDescription").StripHtml()", 3220 "mpn" : "@GetString("Ecom:Product.Number").StripHtml()", 3221 "name" : "@GetString("Ecom:Product.Name").StripHtml()", 3222 "image" : "@( GetGlobalValue( "Global:Request.Scheme" ) + "://" + GetGlobalValue( "Global:Request.Host" ) + GetString("Ecom:Product.ImageLarge.Clean") )", 3223 "offers" : { 3224 "@@type" : "Offer", 3225 "availability" : @( GetInteger( "Ecom:Product.Stock" ) > 0 ? "\"http://schema.org/InStock\"" : "\"http://schema.org/OutOfStock\"" ), 3226 "price" : "@GetDouble("Ecom:Product.Price.Price")", 3227 "priceCurrency" : "@EcomContext.Currency.Code" 3228 } 3229 } 3230 </script> 3231 3232 3233 @{ 3234 string productBreadCrumbLink = ProductService.Instance.GetProductLink( GetString( "Ecom:Product.PrimaryOrFirstGroupID" ), GetString( "Ecom:Product.ID" ) ); 3235 3236 if ( string.IsNullOrEmpty( productBreadCrumbLink ) ) 3237 { 3238 productBreadCrumbLink = string.Format( "Default.aspx?ID={0}&productid={1}", PageView.Current().Page.ID, GetString( "Ecom:Product.ID" ) ); 3239 } 3240 } 3241 3242 <code class="js-e-breadcrumb-item-append" data-text="@HttpUtility.HtmlAttributeEncode( GetString( "Ecom:Product.Name" ) )" data-link="@HttpUtility.HtmlAttributeEncode( productBreadCrumbLink )"></code> 3243 <code class="js-tracking-product-id d-none" data-text="@HttpUtility.HtmlAttributeEncode( GetString( "Ecom:Product.ID" ) )" >@GetString( "Ecom:Product.ID" )</code> 3244 3245 </div> 3246 3247 @sectionStart() 3248 3249 3250 @if ( configurationShow ) 3251 { 3252 <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> 3253 }