Error executing template "Designs/DS2016/eCom/ProductCatalog/Product2016.cshtml"
System.ArgumentNullException: Value cannot be null.
Parameter name: key
   at System.Collections.Concurrent.ConcurrentDictionary`2.TryGetValue(TKey key, TValue& value)
   at Dynamicweb.Ecommerce.Variants.VariantGroupService.GetProductRelations(String productId)
   at Dynamicweb.Ecommerce.Variants.VariantGroupService.GetVariantGroups(String languageId, String productId)
   at CompiledRazorTemplates.Dynamic.RazorEngine_672af1bbc945400f95e536f05512e93f.Execute() in D:\INETPUB\wwwroot\Files\Templates\Designs\DS2016\eCom\ProductCatalog\Product2016.cshtml:line 316
   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 @inherits ViewModelTemplate<ProductViewModel> 2 @using System; 3 @using DanskStandard.Domain.Enum; 4 @using Dynamicweb.Environment; 5 @using System.Linq; 6 @using System.Web; 7 @using Smartpage.ProductInformation.Helpers; 8 @using Dynamicweb; 9 @using Dynamicweb.Core; 10 @using Dynamicweb.Rendering; 11 @using Dynamicweb.Ecommerce.ProductCatalog; 12 @using Smartpage.ProductInformation; 13 @using DanskStandard.BusinessLayer.Provider; 14 15 @inherits ViewModelTemplate<ProductViewModel> 16 @using Newtonsoft.Json; 17 @using System; 18 @using System.Linq; 19 @using System.Web; 20 @using Dynamicweb; 21 @using Dynamicweb.Rendering; 22 @using Dynamicweb.Ecommerce.ProductCatalog; 23 24 25 @helper RenderBuyOptions(ProductViewModel product, IList<Dynamicweb.Ecommerce.Variants.VariantGroup> variantGroups) 26 { 27 //init values 28 var optionNames = new Dictionary<string, string>(); 29 var selectedOptionIds = new HashSet<string>(); 30 var optionSortOrder = new Dictionary<string, int>(); 31 32 string currencyCode = Dynamicweb.Ecommerce.Common.Context.Currency.Code; 33 string vatCountryCode2 = Dynamicweb.Ecommerce.Common.Context.Country.Code2; 34 35 foreach (var vg in variantGroups) 36 { 37 string groupId = vg.Id; 38 string _defaultSelectedOption = ""; 39 string _firstOption = ""; //set this to "selected" if no other options have the selected property 40 foreach (var vao in vg.GetVariantOptions(product.Id)) 41 { 42 string optionId = vao.Id; 43 if (_firstOption == "") 44 { 45 _firstOption = optionId; 46 } 47 if (!optionNames.ContainsKey(optionId)) 48 { 49 string optName = vao.Name; 50 if (groupId == "1616") //1616 = lang --> has sortOrder 51 { 52 optionSortOrder.Add(optionId, vao.SortOrder); 53 } 54 optionNames.Add(optionId, vao.Name); 55 56 } 57 58 if (_defaultSelectedOption == "") 59 { 60 _defaultSelectedOption = optionId; 61 } 62 } 63 if (_defaultSelectedOption == "") 64 { 65 _defaultSelectedOption = _firstOption; 66 } 67 selectedOptionIds.Add(_defaultSelectedOption); 68 } 69 70 @functions { 71 public class Variant : IComparable<Variant> 72 { 73 public string Id { get; set; } 74 public string Name { get; set; } 75 private string _price; 76 public string Price { get { return hasSubVariants() ? SubVariants.Any(v => v.Selected) ? SubVariants.First(v => v.Selected).Price : SubVariants.First().Price : _price; } set { _price = value; } } 77 public bool Selected { get; set; } 78 public int? SortOrder { get; set; } 79 public List<Variant> SubVariants { get; set; } 80 public bool hasSubVariants() { return SubVariants != null && SubVariants.Any(); } 81 public string getSerializedSubVariants() 82 { 83 SubVariants.Sort(); 84 return JsonConvert.SerializeObject(SubVariants.Select(v => new { Id = v.Id, Name = v.Name, Price = v.Price, Selected = v.Selected })); 85 } 86 public override int GetHashCode() { return Id.GetHashCode(); } 87 public override bool Equals(object obj) { return Id == ((Variant)obj).Id; } 88 public int CompareTo(Variant obj) { return (this.SortOrder != null) ? ((int)this.SortOrder).CompareTo(obj.SortOrder) : this.Name.CompareTo(obj.Name); } 89 } 90 } 91 //build variants 92 var pdfText = Dynamicweb.Frontend.PageView.Current().Area.Item["SpPDFText"] as string; 93 var variants = new Dictionary<string, List<Variant>>(); 94 95 var variantCombinations = Dynamicweb.Ecommerce.Services.VariantCombinations.GetVariantCombinations(product.Id); 96 97 foreach (var vc in variantCombinations) 98 { 99 string variationId = vc.VariantId; 100 101 var disabledVariantOptions = Dynamicweb.Frontend.PageView.Current().AreaSettings.GetList("SpVariantOptionsToDisable").SelectedValues; 102 103 // If any of the variant options contain disabled id then we skip iteration 104 if (disabledVariantOptions.Any(x => variationId.Contains(x))) 105 { 106 continue; 107 } 108 109 string price = vc.Product.GetPrice(currencyCode, vatCountryCode2).PriceWithoutVATFormatted; 110 111 string[] _optionIds = variationId.Split('.'); 112 string langId = _optionIds[0]; 113 string langNameStr = optionNames[langId]; 114 115 string formatId = _optionIds[1]; 116 string formatNameStr = optionNames[formatId]; 117 string formatHeaderStr = (formatId == "44_PDF" || formatId == "44_PDF3") ? "PDF" : optionNames[formatId]; 118 119 if (formatHeaderStr == "PDF") //pdf format 120 { 121 Variant format = new Variant() 122 { 123 Id = variationId, 124 Name = formatNameStr, 125 Price = price, 126 Selected = selectedOptionIds.Contains(formatId), 127 }; 128 129 Variant lang = new Variant() 130 { 131 Id = langId, 132 Name = langNameStr, 133 Selected = selectedOptionIds.Contains(langId), 134 SortOrder = optionSortOrder[langId], 135 SubVariants = new List<Variant>() { format } 136 }; 137 138 if (!variants.ContainsKey(formatHeaderStr)) 139 { 140 variants.Add(formatHeaderStr, new List<Variant>() { lang }); 141 } 142 else 143 { 144 var vaList = variants[formatHeaderStr]; 145 if (vaList.Contains(lang)) 146 { //update sub 147 vaList.Single(v => v.Equals(lang)).SubVariants.Add(format); 148 } 149 else //new lang 150 { 151 vaList.Add(lang); 152 } 153 } 154 155 } 156 else //normal format 157 { 158 Variant lang_format = new Variant() 159 { 160 Id = variationId, 161 Name = langNameStr, 162 Price = price, 163 Selected = selectedOptionIds.Contains(langId), 164 }; 165 166 if (!variants.ContainsKey(formatHeaderStr)) 167 { 168 variants.Add(formatHeaderStr, new List<Variant>() { lang_format }); 169 } 170 else 171 { 172 variants[formatHeaderStr].Add(lang_format); 173 } 174 175 } 176 } 177 178 179 //build html output 180 int counter = 0; 181 int variantsCount = variants.Keys.Count; 182 foreach (string formatHeader in variants.Keys) 183 { 184 counter++; 185 List<Variant> vaList = variants[formatHeader]; 186 vaList.Sort(); 187 Variant selectedVariant = null; 188 string _c = (formatHeader == "PDF") ? "js-sel-halfvariant" : "js-sel-fullvariant"; 189 190 <div class="show-desktop"> 191 <div class="row"> 192 <div class="col-md-4"> 193 <p class="margin-bottom-5 font-family-bold-and-color-blue"> 194 @formatHeader 195 @if (formatHeader.Contains("PDF")) 196 { 197 <i class="question-mark no-tooltip-arrow variant-tooltip" data-toggle="tooltip" data-placement="right" data-html="true" title="@pdfText"></i> 198 } 199 </p> 200 </div> 201 <div class="col-md-4"></div> 202 <div class="col-md-2"></div> 203 <div class="col-md-2"></div> 204 </div> 205 </div> 206 207 <div class="show-mobile"> 208 <h2 class="font-family-bold-and-color-blue"> 209 @formatHeader 210 @if (formatHeader.Contains("PDF")) 211 { 212 <i class="question-mark no-tooltip-arrow variant-tooltip" data-toggle="tooltip" data-placement="right" data-html="true" title="@pdfText"></i> 213 } 214 </h2> 215 </div> 216 217 <div class="row js-variant-container"> 218 219 <div class="col-md-4"> 220 221 222 <div class="pos-relative"> 223 224 <span class="select-title-label-text">@Translate("Smartpage:mobile.addtocart.Select.title.label", "Sprog") </span> 225 226 <select class="desktop-select @_c"> 227 @foreach (Variant variant in vaList) 228 { 229 if (variant.Selected) { selectedVariant = variant; } 230 string sel = (variant.Selected) ? "selected=\"selected\"" : ""; 231 string vari = variant.hasSubVariants() ? "data-variations = \"" + HttpUtility.HtmlAttributeEncode(variant.getSerializedSubVariants()) + "\"" : ""; 232 string price = variant.hasSubVariants() ? "" : "data-price=\"" + variant.Price + "\""; 233 <option class="font-family-bold-and-color-blue" value="@variant.Id" @vari @sel @price>@variant.Name</option> 234 } 235 </select> 236 </div> 237 </div> 238 239 <div class="col-md-4"> 240 @if (selectedVariant != null && selectedVariant.hasSubVariants()) //show (sub)format select 241 { 242 List<Variant> subVariants = selectedVariant.SubVariants; 243 244 string hideOptions = subVariants.Count > 1 ? "" : "hidden"; 245 246 subVariants.Sort(); 247 <div class="pos-relative @hideOptions"> 248 <span class="select-title-label-text">@Translate("Smartpage:mobile.addtocart.Select.title.Amount.label", "Antal Enheder") </span> 249 250 <select class="desktop-select js-sel-fullvariant"> 251 @foreach (Variant subvariant in subVariants) 252 { 253 string sel = (subvariant.Selected) ? "selected=\"selected\"" : ""; 254 <option value="@subvariant.Id" @sel data-price="@subvariant.Price">@subvariant.Name</option> 255 } 256 </select> 257 </div> 258 } 259 </div> 260 261 <div class="show-desktop"> 262 <div class="col-md-2 pos-relative "> 263 @if (selectedVariant != null) 264 { 265 <p class="addtocart-modal-price-desktop font-size-medium-and-color-blue"> 266 @Translate("Smartpage:Modal.addtocart.price.label", "Pris") 267 <span class="js-variant-price display-block">@selectedVariant.Price</span> 268 </p> 269 270 } 271 </div> 272 </div> 273 274 <div class="col-md-2 show-mobile"> 275 <div class="margin-top-15 font-size-medium-and-color-blue"> 276 @if (selectedVariant != null) 277 { 278 @Translate("Smartpage:Productbuymodal.Price.Placeholder", "Pris: ") <span class="js-variant-price">@selectedVariant.Price</span> 279 } 280 </div> 281 </div> 282 283 <div class="show-desktop"> 284 <div class="col-md-2"> 285 <button class="width-120 btn btn-primary js-add-to-basket pull-right hidden-print"> 286 @Translate("SmartPage:Product.Buy", "Læg i kurv") 287 </button> 288 </div> 289 </div> 290 <div class="col-md-2 show-mobile"> 291 <br /> 292 <button class="margin-bottom-30 margin-top-0 btn btn-primary js-add-to-basket hidden-print margin-top-15" style="width: 100%"> 293 @Translate("SmartPage:Product.Buy", "Læg i kurv") 294 </button> 295 @if (variantsCount != counter) 296 { 297 <div style="border-bottom: 3px solid #E1E1E1"></div> 298 } 299 </div> 300 </div> 301 } 302 } 303 304 305 306 @{ 307 // AE 20200512: Workaround for setting product title 308 Pageview.Meta.Title = Model.Name; 309 310 var product = Model; 311 var productInformationService = new ProductInformationService(); 312 var productInformation = productInformationService.GetProductInformation(product.Id, product.VariantId, product.LanguageId); 313 314 var standardLanguages = string.Empty; 315 316 var variantGroups = Dynamicweb.Ecommerce.Services.VariantGroups.GetVariantGroups(Dynamicweb.Ecommerce.Common.Context.LanguageID, product.Id); 317 318 var variantLanguages = variantGroups.SingleOrDefault(v => v.Id == "1616"); 319 if (variantLanguages != null) 320 { 321 standardLanguages = string.Join(" - ", variantLanguages.GetVariantOptions(product.Id).Select(o => o.Name)); 322 } 323 } 324 325 @{ 326 bool isDanish = Dynamicweb.Frontend.PageView.Current().Area.CultureInfo.Name == "da-DK"; 327 var previewHtmlExists = Converter.ToBoolean(Helper.GetFieldValue("SpHasPreview", product.ProductFields)); 328 var previewPdfExists = Converter.ToBoolean(Helper.GetFieldValue("SpHasPdfPreview", product.ProductFields)); 329 string designURL = "/Files/Templates/Designs/" + Pageview.Layout.Design.Name.TrimEnd('/'); 330 var productIDSelector = product.Id; 331 var comitteeLoop = productInformation.Committees; 332 string descriptionTextOverlay = isDanish ? Converter.ToString(Helper.GetFieldValue("ENGLISHTITLE", product.ProductFields)) : string.Empty; 333 string descriptionText = isDanish ? Converter.ToString(Helper.GetFieldValue("DanishTitle", product.ProductFields)) : Converter.ToString(Helper.GetFieldValue("ENGLISHTITLE", product.ProductFields)); 334 bool descriptionIsEmpty = string.IsNullOrWhiteSpace(descriptionText); 335 bool harmonizingExists = productInformation.ShowDirectiveCE || productInformation.ShowDirectiveHarmonized || productInformation.HasBrIds || Converter.ToBoolean(Helper.GetFieldValue("AxMotherHarmonized", product.ProductFields)) || productInformation.MotherIsHarmonized; 336 string titleCSSClass = descriptionIsEmpty ? "col-sm-9" : "col-sm-12"; 337 string generalCSSClass = harmonizingExists ? "col-sm-5" : "col-sm-8"; 338 var underRevision = productInformation.UnderRevision; 339 bool showRevision = underRevision.Any() && productInformation.UnderRevisionCount > 0; 340 bool hasCourses = productInformation.HasSPServiceProductsRelated && isDanish; 341 var extendedBtnClass = hasCourses ? "has-ext-btns" : ""; 342 var isServicePlus = productInformation.MisType == "Course" || productInformation.MisType == "Workshop" || productInformation.MisType == "Advice"; 343 var serviceType = isServicePlus ? "serviceplus" : "standard"; 344 var productImage = string.Empty; 345 346 foreach (var image in product.ImagePatternImages) 347 { 348 if (image.Name == "ImagePattern.Big") 349 { 350 productImage = image.Value; 351 } 352 } 353 354 bool productImageExists = !string.IsNullOrEmpty(productImage); 355 var productTitle = product.Name; 356 string productAjaxPageID = Converter.ToString(Pageview.Area.Item["AjaxProductPageLink"]); 357 string productPageID = Converter.ToString(Pageview.Area.Item["ProductPageId"]); 358 359 bool lastVisitedIsAjax = Converter.ToString(Dynamicweb.Frontend.PageView.Current().GlobalTags.GetTagByName("Smartpage:LatestProductListPageID")?.Value) == productAjaxPageID; 360 361 string lastVisitedPage = Converter.ToString(Dynamicweb.Frontend.PageView.Current().GlobalTags.GetTagByName("Smartpage:LatestProductListUrl")?.Value); 362 bool existingLastVisited = System.Web.HttpContext.Current.Request.RawUrl.ToString() == lastVisitedPage || lastVisitedIsAjax; 363 string lastVisitedPageName = Converter.ToString(Dynamicweb.Frontend.PageView.Current().GlobalTags.GetTagByName("Smartpage:LatestProductListName")?.Value); 364 365 var previewPath = string.Format("/Default.aspx?ID={0}&product={1}&&disablestatistics=true", Converter.ToString(Pageview.Area.Item["SpPreviewPage"]), productIDSelector); 366 367 string priceFormatted = product.Price.PriceWithoutVat.ToString("N"); 368 string currencySymbol = Dynamicweb.Ecommerce.Common.Context.Currency.Symbol; 369 370 if (!descriptionIsEmpty) 371 { 372 Pageview.Meta.AddTag("description", descriptionText.Length > 160 ? descriptionText.Substring(0, 160).Replace("\n", "") + "..." : descriptionText.Replace("\n", "")); 373 } 374 375 } 376 377 <div class="top-breadcrumbs-container hidden-print"> 378 <div class="container"> 379 <div class="row"> 380 <div class="col-sm-8"> 381 @if (!existingLastVisited && !string.IsNullOrEmpty(lastVisitedPage) && !string.IsNullOrEmpty(lastVisitedPageName)) 382 { 383 <ul class="list-inline top-breadcrumbs" data-breadcrumbs-type="self"> 384 <li> 385 <a href="@lastVisitedPage">@lastVisitedPageName</a> 386 </li> 387 <li> 388 @productTitle 389 </li> 390 </ul> 391 } 392 else 393 { 394 @RenderNavigation(new { template = "LastLevelBreadCrumbs.xslt", startLevel = 2, expandmode = "pathonly", productName = product.Name, sameVisited = existingLastVisited }) 395 } 396 </div> 397 <div class="col-sm-4"> 398 <div class="print-btns hidden-xs pull-right"> 399 @{ 400 string query = Converter.ToString(System.Web.HttpContext.Current.Request.QueryString); 401 string currentURL = "/Default.aspx?" + query; 402 string printLink = Dynamicweb.Environment.Helpers.LinkHelper.ReplaceQueryString(currentURL, "pagesize", "100"); 403 printLink = Dynamicweb.Environment.Helpers.LinkHelper.ReplaceQueryString(printLink, "print", "true"); 404 string xmlLink = Dynamicweb.Environment.Helpers.LinkHelper.ReplaceQueryString(currentURL, "xml", "true"); 405 string onlyShowHundredProductsInXML = Dynamicweb.Environment.Helpers.LinkHelper.ReplaceQueryString(xmlLink, "pagesize", "100"); } 406 @{ 407 if (query.Contains("print=true")) 408 { 409 <script type="text/javascript"> 410 window.onload = function () { 411 window.print(); 412 } 413 </script> 414 } 415 else 416 { 417 <a href="@printLink" class="hidden-print" target="_blank"> 418 <i class="custom-icon-print"></i> 419 </a> 420 } 421 } 422 <a href="@onlyShowHundredProductsInXML" class="hidden-print" target="_blank"> 423 <i class="custom-icon-xml"></i> 424 </a> 425 </div> 426 427 </div> 428 </div> 429 </div> 430 </div> 431 432 <div class="container"> 433 434 <div class="row"> 435 @{ 436 var associatedProducts = ProductRelationProvider.GetRelatedProducts(product); 437 var handbookContainedLoop = productInformation.ContainedIn; 438 var shadowProductsFromProductId = productInformation.ShadowProductsFromProductId; 439 bool hasRightColumnContent = associatedProducts.Count > 0 || handbookContainedLoop.Any() || (shadowProductsFromProductId.Any() && productInformation.MisType == "Standard"); 440 string firstColumnClass = hasRightColumnContent ? "col-sm-8" : "col-sm-12"; 441 string secondColumnClass = hasRightColumnContent ? "col-sm-4" : "display-none js-second-column"; 442 } 443 <div class="@firstColumnClass"> 444 <div id="productlist"> 445 <div class="js-product-informations product-informations" data-type="@serviceType"> 446 <div class="arrow-container"> 447 <i class="productlist-arrow-mob arrow-right productlist-align-arrow-right"></i> 448 </div> 449 <div class="hidden-print modal fade js-modal-buy" tabindex="-1" role="dialog" id="js-modal-buy-@productIDSelector"> 450 <div class="modal-dialog modal-buy"> 451 <div class="modal-content"> 452 453 <div class="show-desktop"> 454 <div class="modal-header"> 455 <h3 class="modal-title"> 456 @productTitle 457 </h3> 458 <div class="margin-top-0 remove-bold-and-add-line-h-1 pad-left-18"> 459 @HttpContext.Current.Server.HtmlEncode(descriptionText) 460 </div> 461 <div class="margin-top-15" style="border-bottom: 6px solid #E1E1E1"></div> 462 <button type="button" class="close" data-dismiss="modal"><span aria-hidden="true">&times;</span><span class="sr-only">Close</span></button> 463 </div> 464 </div> 465 <div class="show-mobile"> 466 <div class="modal-header"> 467 <h3 class="modal-title"> 468 @productTitle 469 </h3> 470 <div class="margin-top-0 remove-bold-and-add-line-h-1 pad-left-18"> 471 @HttpContext.Current.Server.HtmlEncode(descriptionText) 472 </div> 473 <button type="button" class="close" data-dismiss="modal"><span aria-hidden="true">&times;</span><span class="sr-only">Close</span></button> 474 </div> 475 </div> 476 477 <div class="modal-body"> 478 <div class="col-sm-12"> 479 480 <div class="table table-condensed" id="js-table-@productIDSelector"> 481 <div class="js-ajax-buy-table-content"> 482 <!-- ajax content --> 483 @if (!productInformation.ValidToBuy) 484 { 485 <p> 486 @Translate("Smartpage:Product.NotValidToBuy", "Standarden kan bestilles ved kontakt til Forlag og Kundecenter på telefon +45 39 96 61 31 eller mail <a href='mailto:dssalg@ds.dk'>dssalg@ds.dk</a>") 487 </p> 488 } 489 else 490 { 491 @: @RenderBuyOptions(product, variantGroups) 492 } 493 </div> 494 </div> 495 496 </div> 497 </div> 498 @{ 499 string hideContinueToCheckoutClass = Dynamicweb.Ecommerce.Common.Context.Cart != null && Dynamicweb.Ecommerce.Common.Context.Cart.OrderLines.Any() ? "js-continue-to-checkout" : "js-continue-to-checkout hidden"; 500 } 501 <div class="modal-footer"> 502 <div class="show-desktop"> 503 <div class="center-btns"> 504 <button type="button" class="btn btn-primary" data-dismiss="modal">@Translate("Smartpage:ProductList.Buy.ContinueShopping", "Fortsæt med at handle")</button> 505 <a href="/Default.aspx?ID=@GetPageIdByNavigationTag("CartPage")" class="btn btn-default @hideContinueToCheckoutClass">@Translate("Smartpage:ProductList.Buy.GoToCheckout", "Gå til checkout")</a> 506 </div> 507 </div> 508 <div class="show-mobile"> 509 <div class="row"> 510 <div class="col-xs-12"> 511 <button type="button" class="btn btn-primary width-100" data-dismiss="modal">@Translate("Smartpage:ProductList.Buy.ContinueShopping", "Fortsæt med at handle")</button> 512 </div> 513 <div class="col-xs-12"> 514 <a href="/Default.aspx?ID=@GetPageIdByNavigationTag("CartPage")" class="width-100 btn btn-default @hideContinueToCheckoutClass">@Translate("Smartpage:ProductList.Buy.GoToCheckout", "Gå til checkout")</a> 515 </div> 516 </div> 517 </div> 518 519 520 </div> 521 </div><!-- /.modal-content --> 522 </div><!-- /.modal-dialog --> 523 </div><!-- /.modal --> 524 @if (previewHtmlExists) 525 { 526 <div class="hidden-print modal fade js-modal-preview-html" tabindex="-1" role="dialog" id="js-preview-modal-@productIDSelector" data-preview-path="@previewPath"> 527 <div class="modal-dialog modal-preview-box"> 528 <div class="modal-content"> 529 <div class="modal-header"> 530 <a href="#" class="pull-right close-preview" data-dismiss="modal">@Translate("Smartpage:ProductList.Modal.ClosePreview", "Luk preview") <span class="close-icon">&times;</span></a> 531 </div> 532 <div class="modal-body"></div> 533 </div><!-- /.modal-content --> 534 </div><!-- /.modal-dialog --> 535 </div><!-- /.modal --> 536 } 537 @if (previewPdfExists) 538 { 539 <div class="hidden-print modal fade js-modal-preview-pdf" data-preview-path="@(previewPath + "&pdf=1")" data-target-pdf="@(string.Format("/admin/public/Download.aspx?file=/Files/Files/Products/{0}_attachPV.pdf&ForceDownload=false", productIDSelector))" data-target-canvas="js-canvas-@productIDSelector" tabindex="-1" role="dialog" id="js-pdf-preview-modal-@productIDSelector"> 540 <div class="modal-dialog modal-preview-box"> 541 <div class="modal-content"> 542 <div class="modal-header"> 543 <div class="btn-group" role="group" aria-label="..."> 544 <button type="button" class="js-prev-btn btn btn-default">@Translate("Smartpage:Modal.Prev", "Prev")</button> 545 <button type="button" class="js-current-page btn btn-default">1</button> 546 <button type="button" class="js-next-btn btn btn-default">@Translate("Smartpage:Modal.Next", "Next")</button> 547 </div> 548 <a href="#" class="pull-right close-preview" data-dismiss="modal">@Translate("Smartpage:ProductList.Modal.ClosePreview", "Luk preview") <span class="close-icon">&times;</span></a> 549 </div> 550 <div class="modal-body"> 551 <canvas id="js-canvas-@productIDSelector" class="img-responsive"></canvas> 552 </div> 553 </div><!-- /.modal-content --> 554 </div><!-- /.modal-dialog --> 555 </div> 556 } 557 <div class="productlist-content-titles"> 558 <ul class="nav nav-tabs hidden-print productlist-content-ul-mob" role="tablist"> 559 <li role="presentation"> 560 <a href='#js-start-@product.Id' aria-controls="profile" role="tab" data-toggle="tab">@RenderProductTypeSingle(productInformation.MisType)</a> 561 </li> 562 @if (previewHtmlExists) 563 { 564 <li role="presentation"> 565 <a href="javascript:void(0);" class="preview-button" data-toggle="modal" data-target="#js-preview-modal-@product.Id"> 566 @Translate("Smartpage:ProductList.Detail.PreviewHtml", "Preview HTML") 567 </a> 568 </li> 569 } 570 @if (previewPdfExists) 571 { 572 <li role="presentation"> 573 <a href="javascript:void(0);" class="preview-button" data-toggle="modal" data-target="#js-pdf-preview-modal-@product.Id"> 574 @Translate("Smartpage:ProductList.Detail.PreviewPdf", "Preview PDF") 575 </a> 576 </li> 577 } 578 @if (productInformation.HasDirective || harmonizingExists) 579 { 580 <li role="presentation"> 581 <a href="#js-law-@productIDSelector" data-toggle="tab" role="tab"> 582 @Translate("Smartpage:ProductList.Detail.Law", "Lovgivgning") 583 </a> 584 </li> 585 } 586 <li class="active" role="presentation"> 587 <a href='#js-details-@product.Id' aria-controls="profile" role="tab" data-toggle="tab">@Translate("Smartpage:ProductList.Details.Title", "Detaljer")</a> 588 </li> 589 <li class="watch-line pull-right js-tab-li show-checkbox-on-mobile"> 590 @{ 591 var cart = Dynamicweb.Ecommerce.Common.Context.Cart; 592 bool cartComplete = false; 593 594 if (cart != null && cart.Complete) 595 { 596 cartComplete = true; 597 } 598 599 if (!cartComplete && productInformation.ProductStatus.WebMonitor) 600 { 601 <div class="checkbox-inline"> 602 <label for="js-watch-@productIDSelector" class="checkbox-label-style-custom checkbox-watch js-subscription-create hidden-print" data-type="Dia2" data-toggle="tooltip" title='@Translate("SmartPage:Product.Monitor.Information", "Du kan overvåge standarden og få information direkte i din indboks")'> 603 @Translate("SmartPage:Product.Monitor", "Overvåg") 604 <input type="checkbox" id="js-watch-@productIDSelector" class="checkbox-style-custom checkbox-input js-checkbox-watch"> 605 <span class="checkbox-checkmark"></span> 606 607 </label> 608 </div> 609 } 610 } 611 </li> 612 </ul> 613 </div> 614 <!-- end general info --> 615 <div class="pre-content"> 616 <form class="col-sm-12 padding-10"> 617 <input type="hidden" class="js-sel-product-id" name="ProductID" value="@product.Id" /> 618 <input type="hidden" class="js-sel-variant-id" name="VariantID" value="@product.VariantId" /> 619 <div class="row"> 620 @if (!descriptionIsEmpty) 621 { 622 titleCSSClass = "col-sm-12"; 623 } 624 <h1 class="@titleCSSClass product-title h2"> 625 @productTitle 626 627 @{ 628 DanskStandard.Domain.Enum.StatusCode statusCode; 629 if (Enum.TryParse(productInformation.ProductStatus.Code, out statusCode)) 630 { 631 if (statusCode != StatusCode.Current) 632 { 633 <span class="display-block-xs status-title">(@RenderStatusCodeSingle(productInformation, product.ProductFields))</span> 634 } 635 } 636 } 637 </h1> 638 @if (descriptionIsEmpty) 639 { 640 <div class="col-sm-3 add-to-no-description"> 641 @if (productInformation.ValidToBuy) 642 { 643 <button class="btn-50 margin-bottom-0 btn btn-primary pull-right hidden-print" data-toggle="modal" data-target="#js-modal-buy-@productIDSelector"> 644 @Translate("SmartPage:Product.Buy", "Læg i kurv") 645 </button> 646 } 647 </div> 648 } 649 @if (!descriptionIsEmpty) 650 { 651 var descriptionClass = productImageExists ? "col-sm-7" : "col-sm-8"; 652 if (productImageExists) 653 { 654 <div class="col-sm-1"> 655 <img src="@productImage" class="img-responsive hidden-print" alt="@productTitle)" /> 656 </div> 657 } 658 <div class="product-info-text @descriptionClass"> 659 @if (!string.IsNullOrEmpty(descriptionTextOverlay)) 660 { 661 <p data-toggle="tooltip" title="@HttpContext.Current.Server.HtmlEncode(descriptionTextOverlay)">@HttpContext.Current.Server.HtmlEncode(descriptionText)</p> 662 } 663 else 664 { 665 <p>@HttpContext.Current.Server.HtmlEncode(descriptionText)</p> 666 } 667 </div> 668 <div class="col-sm-4 @extendedBtnClass"> 669 @*@RenderHasCoursesSingle(hasCourses, productInformation, product)*@ 670 @if (productInformation.ValidToBuy) 671 { 672 <button class="btn btn-primary pull-right hidden-print add-to-cart" data-toggle="modal" data-target="#js-modal-buy-@productIDSelector"> 673 @Translate("SmartPage:Product.Buy", "Læg i kurv") 674 <i class="new-basket-icon"></i> 675 </button> 676 } 677 </div> 678 } 679 </div> 680 <hr class="product-divider margin-top-30 margin-bottom-30" /> 681 <div class="row"> 682 <div class="col-sm-4"> 683 <div class="product-details-list"> 684 <div class="prefix">@Translate("Smartpage:ProductList.StatusCodeText", "Status"):</div> 685 <div class="list-content regular"> 686 @RenderStatusCodeSingle(productInformation, product.ProductFields) 687 </div> 688 </div> 689 <div class="product-details-list"> 690 <div class="prefix">@Translate("Smartpage:ProductList.Type", "Type"):</div> 691 <div class="list-content regular"> 692 @RenderProductTypeSingle(productInformation.MisType) 693 </div> 694 </div> 695 <div class="product-details-list"> 696 <div class="prefix">@Translate("Smartpage:ProductList.Language", "Sprog"):</div> 697 <div class="list-content"> 698 @standardLanguages 699 </div> 700 </div> 701 </div> 702 <div class="@generalCSSClass"> 703 @{ 704 var productGroupRelations = Dynamicweb.Ecommerce.Services.ProductGroups.GetProductGroupRelations(product.Id); 705 var associatedGroups = Dynamicweb.Ecommerce.Services.ProductGroups.GetRelatedGroups(productGroupRelations); 706 707 if (associatedGroups.Any(i => i.Id.Contains("COMMITTEEDS"))) 708 { 709 <div class="product-details-list"> 710 <div class="prefix">@Translate("Smartpage:ProductList.Category", "Kategori"):</div> 711 <div class="list-content"> 712 713 @foreach (var group in associatedGroups.Where(i => i.Id.Contains("COMMITTEEDS"))) 714 { 715 if (!string.IsNullOrWhiteSpace(group.Id)) 716 { 717 var currentGroup = Dynamicweb.Ecommerce.Services.ProductGroups.GetGroup(group.Id); 718 var groupIsNull = currentGroup == null; 719 720 if (!groupIsNull) 721 { 722 var parentLanguageIsNull = currentGroup.ParentGroupsDefaultLanguage == null; 723 if (!parentLanguageIsNull) 724 { 725 if (currentGroup.ParentGroupsDefaultLanguage.Count > 0) 726 { 727 if (currentGroup.ParentGroupsDefaultLanguage != null) 728 { 729 if (currentGroup.ParentGroupsDefaultLanguage.FirstOrDefault() != null) 730 { 731 string parentId = currentGroup.ParentGroupsDefaultLanguage.FirstOrDefault().Id; 732 if (parentId != null) 733 { 734 Dynamicweb.Ecommerce.Products.Group parent = Dynamicweb.Ecommerce.Services.ProductGroups.GetGroup(parentId); 735 if (parent != null) 736 { 737 <a href="/Default.aspx?ID=@Converter.ToString(Pageview.Area.Item["ProductPageId"])&amp;groupid=@parent.Id"> 738 @parent.Name 739 </a> 740 } 741 } 742 } 743 else 744 { 745 @Translate("Smartpage:ProductList.ParentGroup", "Parent group not found") 746 } 747 } 748 } 749 } 750 751 } 752 } 753 } 754 755 </div> 756 </div> 757 } 758 } 759 @if (showRevision) 760 { 761 <div class="product-details-list"> 762 <div class="prefix">@Translate("Smartpage:ProductList.Revision", "Revision"):</div> 763 <div class="list-content"> 764 @RenderUnderRevisionSingle(underRevision, "list-unstyled list-inline", isDanish) 765 </div> 766 </div> 767 } 768 769 @if (productInformation.RevisionOf.Any()) 770 { 771 <div class="product-details-list"> 772 <div class="prefix">@Translate("SmartPage:Product.RevisionOf", "Revision af"):</div> 773 <div class="list-content"> 774 <ul class="list-unstyled margin-top-0 margin-bottom-0"> 775 @foreach (var related in productInformation.RevisionOf) 776 { 777 var extraInfo = Pageview.Page.ID != 1 ? related.DanishTitle : related.EnglishTitle; 778 var productLink = "/Default.aspx?ID=" + Converter.ToString(Pageview.Area.Item["ProductPageId"]) + "&amp;ProductID=" + related.ProductId; 779 <li> 780 <a data-original-title="@extraInfo" data-toggle="tooltip" href='@productLink'> 781 @related.ProductName 782 </a> 783 </li> 784 } 785 </ul> 786 </div> 787 </div> 788 } 789 790 @RenderReplaceBySingle(productInformation) 791 @if (productInformation.ValidToBuy) 792 { 793 <div class="product-details-list"> 794 <div class="prefix">@Translate("Smartpage:ProductList.Price", "Pris"):</div> 795 <div class="list-content"> 796 @currencySymbol @priceFormatted 797 </div> 798 </div> 799 } 800 </div> 801 @if (harmonizingExists) 802 { 803 <div class="col-sm-3 harmonizing-section"> 804 <strong class="product-detail-list-title">@Translate("Smartpage:ProductList.Harmony.Text", "Harmonisering"):</strong> 805 @RenderHarmonizingSingle(productInformation, product) 806 </div> 807 } 808 </div> 809 810 </form> 811 </div> 812 <!-- end general info --> 813 <div class="tab-content"> 814 <div class="tab-pane" role="tabpanel" id='js-start-@product.Id'> 815 <!-- general info --> 816 </div> 817 @if (productInformation.HasDirective || harmonizingExists) 818 { 819 <div class="tab-pane details-pane js-law-panel" role="tabpanel" id='js-law-@product.Id'> 820 <!-- law info --> 821 <hr class="product-divider margin-top-10 margin-bottom-30" /> 822 <h4 class="margin-top-0">@Translate("Smartpage:ProductList.Detail.Law", "Lovgivgning")</h4> 823 @{ 824 var standardDirectivesNames = productInformation.StandardDirectives; 825 if (Converter.ToBoolean(productInformation.StandardDirectivesCount) && standardDirectivesNames.Count > 0) 826 { 827 <h5 class="margin-top-0">@Translate("SmartPage:Product.HarmonizedUnder", "Harmoniseret under:")</h5> 828 <ul class="list-unstyled"> 829 @foreach (var item in standardDirectivesNames) 830 { 831 <li> 832 @if (isDanish) 833 { 834 @item.Name 835 } 836 else 837 { 838 @item.NameUK 839 } 840 <br /> 841 <br /> 842 </li> 843 } 844 </ul> 845 } 846 } 847 848 @{ 849 if (productInformation.ShowDirectiveHarmonized) 850 { 851 var standardDirectivesLinks = productInformation.StandardDirectives; 852 <h5 class="margin-top-0">@Translate("SmartPage:Product.HarmonizedStandards", "Harmoniserede standarder"):</h5> 853 <ul class="list-unstyled"> 854 @foreach (var item in standardDirectivesLinks) 855 { 856 <li> 857 <a href="@item.Link" target="_blank"> 858 @item.Link 859 </a> 860 </li> 861 } 862 </ul> 863 } 864 } 865 866 @if (Converter.ToBoolean(Helper.GetFieldValue("AxMotherHarmonized", product.ProductFields))) 867 { 868 var replacingLoop = productInformation.Replacings?.Where(r => r.HasDirectives && (r.ProductStatusCode == "Extended" || r.ProductStatusCode == "Withdrawn")); 869 if (replacingLoop != null && replacingLoop.Any()) 870 { 871 System.Text.StringBuilder sb = new System.Text.StringBuilder(); 872 sb.Append("<ul class='list-unstyled'>"); 873 foreach (var item in replacingLoop) 874 { 875 var link = "/default.aspx?Id=" + Converter.ToString(Pageview.Area.Item["ProductPageId"]) + "&ProductId=" + item.ProductId; 876 sb.Append("<li>"); 877 sb.Append(" <a href=\"" + link + "\">" + item.ProductName + "</a>"); 878 sb.Append("</li>"); 879 } 880 sb.Append("</ul>"); 881 882 <text> 883 @string.Format(Converter.ToString(Pageview.Area.Item["MotherHarmonized"]), sb.ToString()) 884 </text> 885 } 886 887 } 888 @if (productInformation.ShowDirectiveCE || productInformation.ShowDirectiveHarmonized || Converter.ToBoolean(Helper.GetFieldValue("AxMotherHarmonized", product.ProductFields)) || productInformation.MotherIsHarmonized) 889 { 890 <h5 class="margin-top-0">@Translate("Smartpage:ProductList.Links", "Links")</h5> 891 <ul class="list-unstyled"> 892 @if (productInformation.ShowDirectiveCE) 893 { 894 <li> 895 <a href="@Pageview.Area.Item["CELink"]" target="_blank" data-toggle="tooltip" title='@Translate("SmartPage:Product.ToolTip.CE", "Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat.")'>@Translate("SmartPage:Product.Button.CE", "Læs mere om CE-mærkning")</a> 896 </li> 897 } 898 @if (productInformation.ShowDirectiveHarmonized || Converter.ToBoolean(Helper.GetFieldValue("AxMotherHarmonized", product.ProductFields))) 899 { 900 <li> 901 <a href="@Pageview.Area.Item["HarmonizedLink"]" target="_blank" data-toggle="tooltip" title='@Translate("SmartPage:Product.ToolTip.Harmonized", "Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat.")'>@Translate("SmartPage:Product.Button.Harmonized", "Læs mere om harmoniserede standarder")</a> 902 </li> 903 } 904 </ul> 905 } 906 @if (productInformation.HasBrIds) 907 { 908 <div class="br-15-content"> 909 @Converter.ToString(Pageview.Area.Item["BR15Text"]) 910 </div> 911 } 912 </div> 913 } 914 <div class="tab-pane active details-pane js-details-panel" role="tabpanel" id='js-details-@product.Id'> 915 <!-- details --> 916 @if (!string.IsNullOrEmpty(Converter.ToString(Helper.GetFieldValue("SpSalesText", product.ProductFields)))) 917 { 918 <hr class="product-divider margin-top-10 margin-bottom-20" /> 919 <div class="row"> 920 <div class="col-sm-12"> 921 <div> 922 @Converter.ToString(Helper.GetFieldValue("SpSalesText", product.ProductFields)) 923 </div> 924 </div> 925 </div> 926 } 927 <hr class="product-divider margin-top-10 margin-bottom-20" /> 928 <div class="row"> 929 <div class="col-sm-12"> 930 @if (isDanish) 931 { 932 if (!string.IsNullOrEmpty(Converter.ToString(Helper.GetFieldValue("DSDKScope", product.ProductFields)))) 933 { 934 <h4 class="margin-top-0">@Translate("Smartpage:ProductList.Details.Description", "Beskrivelse")</h4> 935 <div class="description"> 936 @Converter.ToString(Helper.GetFieldValue("DSDKScope", product.ProductFields)).Replace("\n", "<br />") 937 </div> 938 } 939 else 940 { 941 <h4 class="margin-top-0">@Translate("Smartpage:ProductList.Details.Description", "Beskrivelse")</h4> 942 <div class="description margin-bottom-0"> 943 @Converter.ToString(Helper.GetFieldValue("DSUKScope", product.ProductFields)).Replace("\n", "<br />") 944 </div> 945 } 946 } 947 else 948 { 949 <h4 class="margin-top-0">@Translate("Smartpage:ProductList.Details.Description", "Beskrivelse")</h4> 950 <div class="description"> 951 @Converter.ToString(Helper.GetFieldValue("DSUKScope", product.ProductFields)).Replace("\n", "<br />") 952 </div> 953 } 954 955 </div> 956 </div> 957 @{ 958 int count = 0; 959 960 if (showRevision) 961 { 962 count++; 963 } 964 if (productInformation.Replacings != null && productInformation.Replacings.Where(p => p.ProductLevel == 0).Any()) 965 { 966 count++; 967 } 968 @*if (associatedProducts.Count > 0) 969 { 970 count++; 971 }*@ 972 973 string classCss = "col-sm-12"; 974 switch (count) 975 { 976 case 2: 977 classCss = "col-sm-6"; 978 break; 979 case 3: 980 classCss = "col-sm-4"; 981 break; 982 case 4: 983 classCss = "col-sm-3"; 984 break; 985 case 0: 986 classCss = "hide"; 987 break; 988 } 989 } 990 @if (classCss != "hide") 991 { 992 <hr class="product-divider margin-top-30 margin-bottom-30" /> 993 } 994 <div class="row"> 995 996 @if (showRevision) 997 { 998 <div class="@classCss"> 999 <h4 class="margin-top-0">@Translate("SmartPage:Product.UnderRevision", "Under revision")</h4> 1000 @RenderUnderRevisionSingle(underRevision, "list-unstyled", isDanish) 1001 </div> 1002 } 1003 1004 @{ 1005 var replacing = productInformation.Replacings?.Where(p => p.ProductLevel == 0); 1006 if (replacing != null && replacing.Any()) 1007 { 1008 <div class="@classCss"> 1009 <h4 class="margin-top-0">@Translate("SmartPage:Product.Replacing", "Erstatter"):</h4> 1010 1011 <ul class="list-unstyled"> 1012 @foreach (var item in replacing) 1013 { 1014 <li> 1015 <a href="/Default.aspx?ID=@Pageview.Area.Item["ProductPageId"]&amp;ProductID=@item.ProductId"> 1016 @item.ProductName 1017 </a> 1018 </li> 1019 } 1020 </ul> 1021 </div> 1022 } 1023 } 1024 1025 1026 </div> 1027 <hr class="product-divider margin-top-30 margin-bottom-30" /> 1028 <div class="row"> 1029 <div class="col-sm-12 regular-details"> 1030 @RenderGeneralDetailsSingle(product, productInformation, associatedGroups) 1031 </div> 1032 </div> 1033 @{ 1034 1035 var handbookContainsLoop = ProductRelationProvider.GetHandbookContainsProducts(product); 1036 var shadowProductsLoop = productInformation.ShadowProducts; 1037 @*var shadowProductsFromProductId = productInformation.ShadowProductsFromProductId;*@ 1038 1039 if (handbookContainsLoop.Any() || shadowProductsLoop.Any() || shadowProductsFromProductId.Any()) 1040 { 1041 @*<hr class="product-divider margin-top-30 margin-bottom-30" />*@ 1042 <div class="row"> 1043 @if (handbookContainsLoop.Any()) 1044 { 1045 <div class="col-sm-6"> 1046 <h4 class="margin-top-0">@Translate("SmartPage:Product.HandbookContains", "Håndbogen indeholder")</h4> 1047 <ul class="list-unstyled margin-bottom-0"> 1048 @foreach (var item in handbookContainsLoop) 1049 { 1050 string groupId = string.Empty; 1051 if (item.Groups.Any()) 1052 { 1053 groupId = item.Groups.First().Id; 1054 } 1055 var handbookContainsProductInformation = productInformationService.GetProductInformation(item.Id, item.VariantId, item.LanguageId); 1056 <li> 1057 @if (handbookContainsProductInformation.ProductStatus.Code == DanskStandard.Domain.Enum.StatusCode.Withdrawn.ToString()) 1058 { 1059 1060 if (isDanish) 1061 { 1062 <a class="repealed" href="/Default.aspx?ID=@Pageview.Area.Item["ProductPageId"]&amp;GroupID=@groupId&amp;ProductID=@item.Id" data-toggle="tooltip" title="@Translate("SmartPage:Product.Withdrawn", "Tilbagetrukket"): @Converter.ToString(Dynamicweb.Ecommerce.Services.Products.GetProductFieldValue(item, "DanishTitle"))"> 1063 @item.Name 1064 </a> 1065 } 1066 else 1067 { 1068 <a class="repealed" href="/Default.aspx?ID=@Pageview.Area.Item["ProductPageId"]&amp;GroupID=@groupId&amp;ProductID=@item.Id" data-toggle="tooltip" title="@Translate("SmartPage:Product.Withdrawn", "Tilbagetrukket"): @Converter.ToString(Dynamicweb.Ecommerce.Services.Products.GetProductFieldValue(item, "ENGLISHTITLE"))"> 1069 @item.Name 1070 </a> 1071 } 1072 } 1073 else 1074 { 1075 if (isDanish) 1076 { 1077 <a href="/Default.aspx?ID=@Pageview.Area.Item["ProductPageId"]&amp;GroupID=@groupId&amp;ProductID=@item.Id" data-toggle="tooltip" title="@HttpContext.Current.Server.HtmlEncode(Converter.ToString(Dynamicweb.Ecommerce.Services.Products.GetProductFieldValue(item, "DanishTitle")))"> 1078 @item.Name 1079 </a> 1080 } 1081 else 1082 { 1083 <a href="/Default.aspx?ID=@Pageview.Area.Item["ProductPageId"]&amp;GroupID=@groupId&amp;ProductID=@item.Id" data-toggle="tooltip" title="@HttpContext.Current.Server.HtmlEncode(Converter.ToString(Dynamicweb.Ecommerce.Services.Products.GetProductFieldValue(item, "ENGLISHTITLE")))"> 1084 @item.Name 1085 </a> 1086 } 1087 } 1088 </li> 1089 } 1090 </ul> 1091 </div> 1092 } 1093 @if (shadowProductsLoop.Any() || shadowProductsFromProductId.Any()) 1094 { 1095 1096 1097 if (shadowProductsLoop.Any() && productInformation.MisType == "PartOf") 1098 { 1099 <div class="col-sm-6"> 1100 <h4 class="margin-top-0">@Translate("SmartPage:Product.ShadowProducts.Standards", "omhandler")</h4> 1101 <ul class="list-unstyled margin-bottom-0"> 1102 @foreach (var item in shadowProductsLoop) 1103 { 1104 <li> 1105 <a href="/Default.aspx?ID=@Pageview.Area.Item["ProductPageId"]&amp;ProductID=@item.ProductId"> 1106 @item.ProductName 1107 </a> 1108 </li> 1109 } 1110 </ul> 1111 </div> 1112 } 1113 @*else if (shadowProductsFromProductId.Any() && productInformation.MisType == "Standard") 1114 { 1115 <div class="col-sm-6"> 1116 <h4 class="margin-top-0">@Translate("SmartPage:Product.ShadowProducts.Handbooks", "Guides og vejledninger")</h4> 1117 <ul class="list-unstyled margin-bottom-0"> 1118 @foreach (var item in shadowProductsFromProductId) 1119 { 1120 <li> 1121 <a href="/Default.aspx?ID=@Pageview.Area.Item["ProductPageId"]&amp;ProductID=@item.RelatedProductId"> 1122 @item.ProductName @item.ProductTitle 1123 </a> 1124 </li> 1125 } 1126 </ul> 1127 </div> 1128 }*@ 1129 1130 } 1131 </div> 1132 } 1133 } 1134 1135 1136 1137 <hr class="product-divider margin-top-20 margin-bottom-30" /> 1138 1139 <div class="row"> 1140 @if (!string.IsNullOrEmpty(Converter.ToString(Helper.GetFieldValue("TechnicalCommittee", product.ProductFields))) || comitteeLoop.Any()) 1141 { 1142 <div class="col-sm-6"> 1143 <h4 class="margin-top-0">@Translate("Smartpage:ProductList.Details.ComitteeSectionTitle", "Udvalgte og komite")</h4> 1144 <div class="row"> 1145 @RenderComitteeLoopSingle(comitteeLoop) 1146 @RenderSComitteeSingle(Converter.ToString(Helper.GetFieldValue("TechnicalCommittee", product.ProductFields))) 1147 </div> 1148 </div> 1149 } 1150 1151 1152 </div> 1153 </div> 1154 </div> 1155 1156 </div> 1157 </div> 1158 </div> 1159 <div class="@secondColumnClass"> 1160 @if (associatedProducts.Count > 0) 1161 { 1162 <div class="product-page-related-products"> 1163 <h3>@Translate("SmartPage:Product.OtherAssociatedProducts", "Andre relevante standarder")</h3> 1164 <ul class="list-unstyled"> 1165 @foreach (var item in associatedProducts) 1166 { 1167 string groupId = string.Empty; 1168 if (item.Groups.Any()) 1169 { 1170 groupId = item.Groups.First().Id; 1171 } 1172 <li> 1173 @{ 1174 string title = string.Empty; 1175 string link = "/Default.aspx?ID=" + Pageview.Area.Item["ProductPageId"] + "&amp;GroupID=" + groupId + "&amp;ProductID=" + item.Id; 1176 if (isDanish) 1177 { 1178 title = Converter.ToString(Dynamicweb.Ecommerce.Services.Products.GetProductFieldValue(item, "DanishTitle")); 1179 } 1180 else 1181 { 1182 title = Converter.ToString(Dynamicweb.Ecommerce.Services.Products.GetProductFieldValue(item, "ENGLISHTITLE")); 1183 } 1184 <div class="related-product"> 1185 <div> 1186 <a class="related-product-link" href="@link" data-toggle="tooltip" title="@title"> 1187 @item.Name 1188 </a> 1189 <div> 1190 @title 1191 </div> 1192 </div> 1193 <div> 1194 <a class="btn feature-readmore" href='@link'></a> 1195 </div> 1196 </div> 1197 <hr /> 1198 } 1199 </li> 1200 } 1201 </ul> 1202 </div> 1203 } 1204 @if (handbookContainedLoop.Any()) 1205 { 1206 <div class="product-page-contained-in"> 1207 <h3>@Translate("SmartPage:Product.ContainedIn", "Indgår i")</h3> 1208 <ul class="list-unstyled margin-bottom-0"> 1209 @foreach (var item in handbookContainedLoop.Where(x => !string.IsNullOrEmpty(x.ProductId))) 1210 { 1211 var toolTip = isDanish ? item.DanishTitle : item.EnglishTitle; 1212 string link = "/Default.aspx?ID=" + Pageview.Area.Item["ProductPageId"] + "&amp;ProductID=" + item.ProductId; 1213 1214 <li> 1215 <div class="contained-in-product"> 1216 <div> 1217 <a class="contained-in-link" href="@link" data-toggle="tooltip" title='@toolTip'> 1218 @item.ProductName 1219 </a> 1220 <div> 1221 @toolTip 1222 </div> 1223 </div> 1224 <div> 1225 <a class="btn feature-readmore" href='@link'></a> 1226 </div> 1227 </div> 1228 <hr /> 1229 </li> 1230 } 1231 </ul> 1232 </div> 1233 } 1234 @if (shadowProductsFromProductId.Any() && productInformation.MisType == "Standard") 1235 { 1236 <div class="product-page-guides"> 1237 <h3>@Translate("SmartPage:Product.ShadowProducts.Handbooks", "Guides og vejledninger")</h3> 1238 <ul class="list-unstyled margin-bottom-0"> 1239 @foreach (var item in shadowProductsFromProductId) 1240 { 1241 string link = "/Default.aspx?ID=" + Pageview.Area.Item["ProductPageId"] + "&amp;ProductID=" + item.RelatedProductId; 1242 <li> 1243 <div class="guides-product"> 1244 <div class="align-self-flex-start"> 1245 <img class="guide-image" src="/Files/Templates/Designs/DS2016/Assets/images/guide-icon.png" alt="" /> 1246 </div> 1247 <div class="width-100"> 1248 <a class="guides-link" href="@link"> 1249 @item.ProductName 1250 </a> 1251 <div> 1252 @item.ProductTitle 1253 </div> 1254 </div> 1255 <div> 1256 <a class="btn feature-readmore" href='@link'></a> 1257 </div> 1258 </div> 1259 <hr /> 1260 </li> 1261 } 1262 </ul> 1263 </div> 1264 } 1265 <div class="js-customer-who-also-products hide" data-url="Default.aspx?Id=@GetPageIdByNavigationTag("SeenProductsPage")&PId=@Model.Id"></div> 1266 </div> 1267 </div> 1268 1269 @if (Pageview.AreaSettings.GetItems("SpBottomBoxes") != null && Pageview.AreaSettings.GetItems("SpBottomBoxes").Count > 0) 1270 { 1271 <div class="row bottom-boxes"> 1272 <h1 class="headline">@Translate("Smartpage:ProductPage.BottomBoxes.Header", "Hjælp og vejledning")</h1> 1273 @foreach (var item in Pageview.AreaSettings.GetItems("SpBottomBoxes").Where(i => i.GetFile("Image") != null)) 1274 { 1275 string image = item.GetFile("Image").Path; 1276 <div class="col-sm-4 bottom-box"> 1277 <a href="@item.GetValue("Link")"> 1278 <div class="read-more-box"> 1279 @if (!string.IsNullOrWhiteSpace(image)) 1280 { 1281 <img class="img-responsive read-more-image" src="@image"/> 1282 } 1283 <h3 class="read-more-title">@item.GetValue("Title")</h3> 1284 1285 <div class="row"> 1286 <div class="read-more-description col-sm-12"> 1287 @item.GetValue("Description") 1288 </div> 1289 </div> 1290 <button class="btn feature-readmore"></button> 1291 </div> 1292 </a> 1293 </div> 1294 } 1295 </div> 1296 } 1297 </div> 1298 1299 <div class="container header-container"> 1300 <div id="spp_productlist"> 1301 <div class="modal fade js-spp-productslist-modal js-close-after-adding-to-cart" id="OpenSPProductsList" tabindex="-1" role="dialog"> 1302 <div class="modal-dialog large js-spp-modal-size"> 1303 <div class="modal-content js-service-product-informations"> 1304 <div class="modal-header"> 1305 <div class="js-no-recommendation-wrapper"> 1306 <div class="spp-header js-spp-modal-productlist-header"> 1307 @Translate("SmartPage:Product.Modal.SPPProductlistHeader", "Standardplus liste overskrift") 1308 </div> 1309 <div class="spp-header js-spp-modal-header-productname"> 1310 </div> 1311 </div> 1312 <div class="js-recommendation-wrapper hide"> 1313 <div class="spp-header"> 1314 @Translate("SmartPage:Product.Modal.SPPProductlistHeader.Recommendation", "Relevante kurser og rådgivning") 1315 </div> 1316 </div> 1317 <button type="button" class="close" data-dismiss="modal"><span aria-hidden="true">&times;</span><span class="sr-only">Close</span></button> 1318 </div> 1319 <div class="modal-body"> 1320 <div class="row"> 1321 <a href="#" class="js-spp-modal-back col-sm-12"><i class="glyphicon glyphicon-backward"></i> @Translate("SmartPage:Product.Modal.Back", "Gå til listevisning")</a> 1322 </div> 1323 <div class="row"> 1324 <div class="js-spp-modal-content spp-modal-content col-sm-12"><!-- ajax indhold --></div> 1325 </div> 1326 @*<div class="spp-productlist js-spp-modal-original-content row"></div>*@ 1327 @*<div class="js-spp-contactme-content row">*@<!-- ajax indhold -->@*</div>*@ 1328 </div> 1329 <div class="modal-footer"> 1330 <div class="standard-plus-disturb pull-left js-standard-plus-disturb hide"> 1331 <div class="checkbox"> 1332 <label> 1333 <input class="js-standard-plus-checkbox" type="checkbox"> 1334 @Translate("SmartPage:DoNotDistrub", "Vis ikke denne igen") 1335 </label> 1336 </div> 1337 </div> 1338 <div class="center-btns"> 1339 <button class="btn btn-default js-spp-close-btn-modal" data-dismiss="modal" aria-hidden="true">@Translate("SmartPage:Product.Modal.Close", "Luk")</button> 1340 </div> 1341 </div> 1342 </div> 1343 </div> 1344 </div> 1345 </div> 1346 </div> 1347 1348 @helper RenderHasCoursesSingle(bool hasCourses, Smartpage.ProductInformation.Model.ProductInformation productInformation, ProductViewModel product) 1349 { 1350 if (hasCourses) 1351 { 1352 var cssClass = productInformation.ValidToBuy ? "" : "pull-right"; 1353 var standardPlusProductLink = Converter.ToString(Pageview.Area.Item["StandardPlusPage"]) + "&ProductId=" + product.Id; 1354 <a href="@standardPlusProductLink" data-product-id='@product.Id' class="btn margin-bottom-0 btn-default width-45percent js-spp-productlist-btn @cssClass" style="margin-right:10px" data-product-name='@product.Name' data-toggle="tooltip" 1355 title='@Translate("SmartPage:Product.SeeServiceProductsCourceAndAdviceTooltip", "Kursus og rådgivning tooltip")'>@Translate("SmartPage:ProductList.Courses", "Kurser")</a> 1356 } 1357 } 1358 1359 1360 @helper RenderUnderRevisionSingle(List<Smartpage.ProductInformation.Model.Replacing> revisionLoop, string className, bool isDanish) 1361 { 1362 <ul class='@className'> 1363 @foreach (var item in revisionLoop) 1364 { 1365 var toolTip = !isDanish ? item.EnglishTitle : item.DanishTitle; 1366 <li> 1367 <a href="/Default.aspx?ID=@Pageview.Area.Item["ProductPageId"]&amp;ProductID=@item.ProductId" data-toggle="tooltip" title='@toolTip'>@item.ProductName</a> 1368 </li> 1369 } 1370 </ul> 1371 } 1372 1373 @helper RenderSComitteeSingle(string technicalComittee) 1374 { 1375 if (!string.IsNullOrEmpty(technicalComittee)) 1376 { 1377 var techLink = technicalComittee.Replace("DS/", ""); 1378 // Replace remaining part of URL as to avoid 404 when linking to brand site 1379 techLink = "http://www.ds.dk/" + techLink.Split('/')[0]; 1380 1381 <div class="col-sm-6"> 1382 <p class="small-title">@Translate("Smartpage:ProductList.Details.TechnicalComittee", "Dansk udvalg")</p> 1383 <a href="@techLink" target="_blank">@technicalComittee</a> 1384 </div> 1385 } 1386 } 1387 1388 @helper RenderComitteeLoopSingle(List<Smartpage.ProductInformation.Model.ProjectCommittee> comitteeLoop) 1389 { 1390 if (comitteeLoop.Any()) 1391 { 1392 <div class="col-sm-6"> 1393 <p class="small-title">@Translate("SmartPage:ProductList.Details.Comittee", "Komite")</p> 1394 <ul class="list-unstyled"> 1395 @*Only show distinct*@ 1396 @foreach (var i in comitteeLoop.GroupBy(x => x.Committee).Select(g => g.First())) 1397 { 1398 <li>@i.Committee</li> 1399 } 1400 </ul> 1401 </div> 1402 } 1403 } 1404 1405 @helper RenderGeneralDetailsSingle(ProductViewModel product, Smartpage.ProductInformation.Model.ProductInformation productInformation, IEnumerable<Dynamicweb.Ecommerce.Products.Group> associatedGroups) 1406 { 1407 DateTime publishDate = Converter.ToDateTime(Helper.GetFieldValue("ItemPublished", product.ProductFields)); 1408 DateTime acceptedDate = Converter.ToDateTime(Helper.GetFieldValue("DSPUBACCEPTDATE", product.ProductFields)); 1409 DateTime withdrawnDate = Converter.ToDateTime(Helper.GetFieldValue("WITHDRAWDATE", product.ProductFields)); 1410 DateTime sqlNullDate = Convert.ToDateTime("1/1/1901 00:00:00 AM");@* to avoid empty date in sql, that does not match DateTime.MinValue *@ 1411 <p><strong>@Translate("Smartpage:ProductList.Details.NoOfPages", "Antal sider"):</strong> @Converter.ToString(Helper.GetFieldValue("NumberOfPages", product.ProductFields))</p> 1412 if (publishDate != DateTime.MinValue && DateTime.Compare(sqlNullDate, publishDate) != 0) 1413 { 1414 <p><strong>@Translate("Smartpage:ProductList.Details.Published", "Udgivet"):</strong> @publishDate.ToString("yyyy-MM-dd")</p> 1415 } 1416 if (acceptedDate != DateTime.MinValue && DateTime.Compare(sqlNullDate, acceptedDate) != 0) 1417 { 1418 <p><strong>@Translate("Smartpage:ProductList.Details.AcceptanceDate", "Godkendelsesdato"):</strong> @acceptedDate.ToString("yyyy-MM-dd")</p> 1419 } 1420 if (withdrawnDate != DateTime.MinValue && DateTime.Compare(sqlNullDate, withdrawnDate) != 0) 1421 { 1422 <p><strong>@Translate("SmartPage:Ecom.RevokedDate", "Ophævelsesdato"):</strong> @withdrawnDate.ToString("yyyy-MM-dd")</p> 1423 } 1424 1425 var standardRelations = productInformation.StandardRelations; 1426 if (standardRelations.Any()) 1427 { 1428 var isFirst = true; 1429 <p> 1430 <strong> 1431 @Translate("SmartPage:Product.StandardRelation", "Standard relation") 1432 <i class="question-mark" data-toggle="tooltip" title='@Translate("SmartPage:Product.ToolTip.InternationalRelations", "Standardens sammenhæng med europæiske og internationale standarder. IDT betyder at standarden er identisk med de nævnte europæiske og internationale standarder. MOD betyder er standarden er modificeret i forhold til de nævnte internationale standarder. Fx i form af ændringer eller tilføjelse til standardens indhold. NEQ betyder at standarden ikke svarer til de nævnte internationale standarder ift. teknisk indhold og struktur. En mindre del af indholdet kan dog bygge på de nævnte internationale standarder.")'></i> 1433 : 1434 </strong> 1435 @foreach (var relation in standardRelations) 1436 { 1437 if (!isFirst) 1438 { 1439 <br /> 1440 } 1441 if (!string.IsNullOrEmpty(relation.EuroPubProductName)) 1442 { 1443 <span>@relation.EuroPubProductName</span> 1444 } 1445 if (!string.IsNullOrEmpty(relation.InternatPubProductName)) 1446 { 1447 <span>@relation.InternatPubProductName</span> 1448 } 1449 isFirst = false; 1450 1451 } 1452 </p> 1453 } 1454 if (associatedGroups.Where(g => System.Text.RegularExpressions.Regex.IsMatch(g.Name, @"^\d+")).Any()) 1455 { 1456 <p> 1457 <strong>@Translate("Smartpage:ProductList.Details.ICS", "ICS"):</strong> 1458 @foreach (var item in associatedGroups.Where(g => System.Text.RegularExpressions.Regex.IsMatch(g.Name, @"^\d+"))) 1459 { 1460 <span> 1461 <a href="/Default.aspx?ID=@Pageview.Area.Item["ProductPageId"]&amp;GroupID=@item.Id"> 1462 @item.Name 1463 </a> 1464 </span> 1465 } 1466 </p> 1467 } 1468 <p><strong>@Translate("SmartPage: Product.ItemNumber", "Varenummer"):</strong> @product.Number</p> 1469 1470 if (productInformation.ShowExpectedRevokedDate) 1471 { 1472 <p><strong>@Translate("SmartPage:Ecom.ExpectedRevokedDate", "Forventes ophævet"): </strong>@Converter.ToDateTime(Helper.GetFieldValue("LATESTDATETOWITHDRAW", product.ProductFields)).ToString("dd-MM-yyyy")</p> 1473 } 1474 1475 } 1476 1477 @helper RenderReplaceBySingle(Smartpage.ProductInformation.Model.ProductInformation product) 1478 { 1479 var replacedBy = product.ReplacedBy; 1480 if (replacedBy.Any()) 1481 { 1482 <div class="product-details-list"> 1483 <div class="prefix">@Translate("SmartPage:Product.ReplacedBy", "Erstattet af"):</div> 1484 <div class="list-content"> 1485 <ul class="list-unstyled margin-bottom-0 margin-top-0"> 1486 @foreach (var item in replacedBy) 1487 { 1488 var itemLink = "/Default.aspx?ID=" + Converter.ToString(Pageview.Area.Item["ProductPageId"]) + "&amp;ProductID=" + @item.ProductId; 1489 var toolTip = Pageview.Page.AreaId == 3 ? item.DanishTitle : item.EnglishTitle; 1490 <li> 1491 <a href="@itemLink" data-toggle="tooltip" title='@toolTip'>@item.ProductName</a> 1492 </li> 1493 } 1494 </ul> 1495 </div> 1496 </div> 1497 } 1498 } 1499 1500 1501 @helper RenderHarmonizingSingle(Smartpage.ProductInformation.Model.ProductInformation productInformation, ProductViewModel product) 1502 { 1503 var isHarmonized = false; 1504 <p class="harmony-links"> 1505 @if (productInformation.ShowDirectiveCE) 1506 { 1507 isHarmonized = true; 1508 <span class="badge badge-harmony"> 1509 @Translate("Smartpage.ProductList.Harmony.CE", "CE") 1510 <i class="question-mark" data-toggle="tooltip" title='@Translate("SmartPage:Product.ToolTip.CE", "Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat.")'></i> 1511 </span> 1512 } 1513 @if (productInformation.ShowDirectiveHarmonized) 1514 { 1515 isHarmonized = true; 1516 <span class="badge badge-harmony"> 1517 @Translate("Smartpage.ProductList.Harmony.Harmonized", "Harmonizeret") 1518 <i class="question-mark" data-toggle="tooltip" title='@Translate("SmartPage:Product.ToolTip.Harmonized", "Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat.")'></i> 1519 </span> 1520 } 1521 1522 @foreach (var br in productInformation.BrIds) 1523 { 1524 <span class="badge badge-harmony"> 1525 @Translate("Smartpage.ProductList.Harmony." + br, br) 1526 <i class="question-mark" data-toggle="tooltip" title="@Translate("SmartPage.Product.ToolTip." + br, "Bygningsreglementet " + br)"></i> 1527 </span> 1528 } 1529 </p> 1530 1531 var replacing = productInformation.Replacings?.Where(p => p.ProductLevel == 0); 1532 1533 if (productInformation.MotherIsHarmonizedCE) 1534 { 1535 var replacingLoop = productInformation.Replacings?.Where(r => r.HasDirectiveCE); 1536 if (replacingLoop != null && replacingLoop.Any()) 1537 { 1538 System.Text.StringBuilder sb = new System.Text.StringBuilder(); 1539 sb.Append("<ul class='list-unstyled margin-top-0'>"); 1540 foreach (var item in replacingLoop) 1541 { 1542 var link = "/default.aspx?Id=" + Converter.ToString(Pageview.Area.Item["ProductPageId"]) + "&ProductId=" + item.ProductId; 1543 sb.Append("<li>"); 1544 sb.Append(" <a href=\"" + link + "\">" + item.ProductName + "</a>"); 1545 sb.Append("</li>"); 1546 } 1547 sb.Append("</ul>"); 1548 1549 1550 <text> 1551 @string.Format(Converter.ToString(Pageview.Area.Item["HarmonizedAndCEApproved"]), sb.ToString()) 1552 </text> 1553 } 1554 } 1555 1556 else if (!isHarmonized && (Converter.ToBoolean(Helper.GetFieldValue("AxMotherHarmonized", product.ProductFields)) || productInformation.MotherIsHarmonized)) 1557 { 1558 var replacingLoop = productInformation.Replacings?.Where(r => r.HasDirectives && (r.ProductStatusCode == "Extended" || r.ProductStatusCode == "Withdrawn")); 1559 if (replacingLoop != null && replacingLoop.Any()) 1560 { 1561 System.Text.StringBuilder sb = new System.Text.StringBuilder(); 1562 sb.Append("<ul class='list-unstyled margin-top-0'>"); 1563 foreach (var item in replacingLoop) 1564 { 1565 var link = "/default.aspx?Id=" + Converter.ToString(Pageview.Area.Item["ProductPageId"]) + "&ProductId=" + item.ProductId; 1566 sb.Append("<li>"); 1567 sb.Append(" <a href=\"" + link + "\">" + item.ProductName + "</a>"); 1568 sb.Append("</li>"); 1569 } 1570 sb.Append("</ul>"); 1571 1572 <text> 1573 @string.Format(Converter.ToString(Pageview.Area.Item["MotherHarmonized"]), sb.ToString()) 1574 </text> 1575 } 1576 } 1577 } 1578 1579 @helper RenderProductTypeSingle(string type) 1580 { 1581 switch (type) 1582 { 1583 case "Course": 1584 @:@Translate("Smartpage:Product.MisType.Course", "Kurser") 1585 break; 1586 case "Workshop": 1587 @:@Translate("Smartpage:Product.MisType.Workshop", "Workshop") 1588 break; 1589 case "Advice": 1590 @:@Translate("Smartpage:Product.MisType.Advice", "Rådvigning") 1591 break; 1592 case "Standard": 1593 @:@Translate("SmartPage:Product.MisType.Standard", "Standard") 1594 break; 1595 case "PartOf": 1596 @:@Translate("SmartPage:Product.MisType.PartOf", "Håndbog") 1597 break; 1598 case "Supplementary": 1599 @:@Translate("SmartPage:Product.MisType.Supplementary", "Tillæg") 1600 break; 1601 case "CorrectionSheet": 1602 @:@Translate("SmartPage:Product.MisType.CorrectionSheet", "Rettelsesblad") 1603 break; 1604 case "Appendix": 1605 @:@Translate("SmartPage:Product.MisType.Appendix", "Bilag") 1606 break; 1607 } 1608 } 1609 @helper RenderStatusCodeSingle(Smartpage.ProductInformation.Model.ProductInformation productInformation, Dictionary<string, FieldValueViewModel> productFields) 1610 { 1611 DanskStandard.Domain.Enum.StatusCode statusCode; 1612 if (Enum.TryParse(productInformation.ProductStatus.Code, out statusCode)) 1613 { 1614 switch (statusCode) 1615 { 1616 case StatusCode.Current: 1617 @:@Translate("SmartPage:Product.StatusCode.Current", "Gældende") 1618 break; 1619 case StatusCode.Draft: 1620 @:@Translate("SmartPage:Product.StatusCode.Draft", "Forslag") 1621 break; 1622 case StatusCode.Extended: 1623 var statusText = Translate("SmartPage:Product.StatusCode.Extended", "Forlænget"); 1624 if (productInformation.ShowExpectedRevokedDate) 1625 { 1626 statusText += Converter.ToDateTime(Helper.GetFieldValue("LATESTDATETOWITHDRAW", productFields)).ToString("dd-MM-yyyy"); 1627 } 1628 @statusText 1629 break; 1630 case StatusCode.Withdrawn: 1631 @:@Translate("SmartPage:Product.StatusCode.Withdrawn", "Tilbagetrukket") 1632 break; 1633 } 1634 } 1635 } 1636 1637 @using Dynamicweb.Rendering; 1638 @using Dynamicweb.Ecommerce.ProductCatalog; 1639 @using Dynamicweb; 1640 @using SmartPage.Dynamicweb.Helper; 1641 1642 @{ 1643 string removeLink = Dynamicweb.Frontend.SearchEngineFriendlyURLs.GetFriendlyUrl(base.Pageview.ID); 1644 } 1645 1646 <!-- Modal --> 1647 <div class="modal fade js-subscription-not-loggedin" tabindex="-1" role="dialog"> 1648 <div class="modal-dialog"> 1649 <div class="modal-content"> 1650 <div class="modal-header"> 1651 <button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button> 1652 <h4 class="modal-title">@Translate("SmartPage:Product.Modal.Header.NotLoggedIn", "Du er ikke logget ind")</h4> 1653 </div> 1654 <div class="modal-body"> 1655 <p class="js-monitoring hide">@Translate("SmartPage:Product.Modal.Text.NotLoggedIn.Monitoring", "Du skal være logget ind for at kunne melde til overvågning")</p> 1656 <p class="js-subscription hide">@Translate("SmartPage:Product.Modal.Header.NotLoggedIn.Subscription", "Du skal være logget ind for at kunne melde til abonnement")</p> 1657 </div> 1658 <div class="modal-footer"> 1659 <div class="center-btns"> 1660 <button class="btn" data-dismiss="modal" aria-hidden="true">@Translate("SmartPage:Product.Modal.Close", "Luk")</button> 1661 <button class="btn btn-info js-close" aria-hidden="true">@Translate("SmartPage:Product.Modal.Login", "Login")</button> 1662 </div> 1663 </div> 1664 </div> 1665 <!-- /.modal-content --> 1666 </div> 1667 <!-- /.modal-dialog --> 1668 </div> 1669 <!-- /.modal --> 1670 <!-- Modal --> 1671 <div class="modal fade js-subscription-no-access" tabindex="-1" role="dialog"> 1672 <div class="modal-dialog"> 1673 <div class="modal-content"> 1674 <div class="modal-header"> 1675 <button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button> 1676 <h4 class="modal-title">@Translate("SmartPage:Product.Modal.Header.Problems", "Ingen adgang")</h4> 1677 </div> 1678 <div class="modal-body"> 1679 <p class="js-monitoring hide">@Translate("SmartPage:Product.Modal.Text.Problems.Monitoring", "Der er problemer med at føje til overvågning - forsøg venligst igen senere")</p> 1680 <p class="js-subscription hide">@Translate("SmartPage:Product.Modal.Text.Problems.Subscription", "Der er problemer med at føje til abonnement - forsøg venligst igen senere")</p> 1681 </div> 1682 <div class="modal-footer"> 1683 <div class="center-btns"> 1684 <button class="btn" data-dismiss="modal" aria-hidden="true">@Translate("SmartPage:Product.Modal.Close", "Luk")</button> 1685 </div> 1686 </div> 1687 </div> 1688 <!-- /.modal-content --> 1689 </div> 1690 <!-- /.modal-dialog --> 1691 </div> 1692 <!-- /.modal --> 1693 <!-- Modal --> 1694 <div class="modal fade js-subscription-exists" tabindex="-1" role="dialog"> 1695 <div class="modal-dialog"> 1696 <div class="modal-content"> 1697 <div class="modal-header"> 1698 <button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button> 1699 <h4 class="modal-title"> 1700 <span class="js-monitoring">@Translate("SmartPage:Product.Modal.Header.MonitoringExists", "Overvågning")</span> 1701 <span class="js-subscription">@Translate("SmartPage:Product.Modal.Header.SubscriptionExists", "Abonnement")</span> 1702 </h4> 1703 </div> 1704 <div class="modal-body"> 1705 <div class="js-monitoring hide"> 1706 <div class="js-exists"> 1707 <div class="js-subject"> 1708 <p>@Translate("SmartPage:Product.Modal.Text.MonitoringExistsSubject", "Du overvåger allerede dette emne")</p> 1709 </div> 1710 <div class="js-standard"> 1711 <p>@Translate("SmartPage:Product.Modal.Text.MonitoringExistsStandard", "Du overvåger allerede denne standard")</p> 1712 </div> 1713 </div> 1714 <div class="js-not-exists"> 1715 <div class="js-subject"> 1716 <p>@Translate("SmartPage:Product.Modal.Text.MonitoringNotExistsSubject", "Er du sikker på at du vil overvåge dette emne?")</p> 1717 </div> 1718 <div class="js-standard"> 1719 <p>@Translate("SmartPage:Product.Modal.Text.MonitoringNotExistsStandard", "Er du sikker på at du vil overvåge denne standard?")</p> 1720 </div> 1721 </div> 1722 </div> 1723 <div class="js-subscription hide"> 1724 <div class="js-exists"> 1725 <div class="js-subject"> 1726 <p>@Translate("SmartPage:Product.Modal.Text.SubscriptionExistsSubject", "Du abonnerer allerede dette emne")</p> 1727 </div> 1728 <div class="js-standard"> 1729 <p>@Translate("SmartPage:Product.Modal.Text.SubscriptionExistsStandard", "Du abonnerer allerede denne standard")</p> 1730 </div> 1731 </div> 1732 <div class="js-not-exists"> 1733 <div class="js-subject"> 1734 <p>@Translate("SmartPage:Product.Modal.Text.SubscriptionNotExistsSubject", "Er du sikker på at du vil abonnere på dette emne?")</p> 1735 </div> 1736 <div class="js-standard"> 1737 <p>@Translate("SmartPage:Product.Modal.Text.SubscriptionNotExistsStandard", "Er du sikker på at du vil abonnere på denne standard?")</p> 1738 </div> 1739 </div> 1740 </div> 1741 </div> 1742 <div class="modal-footer"> 1743 <div class="center-btns"> 1744 <button class="btn" data-dismiss="modal" aria-hidden="true">@Translate("SmartPage:Product.Modal.Close", "Luk")</button> 1745 <button class="btn btn-primary js-not-exists js-confirm-subscription js-monitoring" data-dismiss="modal" aria-hidden="true">@Translate("SmartPage:Product.Modal.Button.Monitoring", "Overvåg")</button> 1746 <button class="btn btn-primary js-not-exists js-confirm-subscription js-subscription" data-dismiss="modal" aria-hidden="true">@Translate("SmartPage:Product.Modal.Button.Subscription", "Abonnér")</button> 1747 </div> 1748 </div> 1749 </div> 1750 <!-- /.modal-content --> 1751 </div> 1752 <!-- /.modal-dialog --> 1753 </div> 1754 <!-- /.modal --> 1755 <!-- Modal --> 1756 <div class="modal fade js-subscription-confirmation" tabindex="-1" role="dialog"> 1757 <div class="modal-dialog"> 1758 <div class="modal-content"> 1759 <div class="modal-header"> 1760 <button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button> 1761 <h4 class="modal-title js-subscription">@Translate("SmartPage:Product.Modal.Header.SubscriptionConfirm", "Bekræftelse af abonnement")</h4> 1762 <h4 class="modal-title js-monitoring">@Translate("SmartPage:Product.Modal.Header.MonitoringConfirm", "Bekræftelse af overvågning")</h4> 1763 </div> 1764 <div class="modal-body"> 1765 <div class="js-subscription"> 1766 <div class="js-success "> 1767 <div class="js-success-subject"> 1768 <p>@Translate("SmartPage:Product.Modal.Text.SubscriptionSuccessSubject", "Du abonnerer nu på dette emne!")</p> 1769 </div> 1770 <div class="js-success-standard"> 1771 <p>@Translate("SmartPage:Product.Modal.Text.SubscriptionSuccessStandard", "Du abonnerer nu på denne standard!")</p> 1772 </div> 1773 </div> 1774 <div class="js-failure"> 1775 <p>@Translate("SmartPage:Product.Modal.Text.SubscriptionFailure", "Det lykkedes ikke aktivere abonnementet - prøv venligst igen senere eller kontakt os")</p> 1776 </div> 1777 </div> 1778 <div class="js-monitoring"> 1779 <div class="js-success"> 1780 <div class="js-success-subject"> 1781 <p>@Translate("SmartPage:Product.Modal.Text.MonitoringSuccessSubject", "Du overvåger nu dette emne!")</p> 1782 </div> 1783 <div class="js-success-standard"> 1784 <p>@Translate("SmartPage:Product.Modal.Text.MonitoringSuccessStandard", "Du overvåger nu denne standard!")</p> 1785 </div> 1786 1787 </div> 1788 <div class="js-failure"> 1789 <p>@Translate("SmartPage:Product.Modal.Text.MonitoringFailure", "Det lykkedes ikke at melde til overvågning - prøv venligst igen senere eller kontakt os")</p> 1790 </div> 1791 </div> 1792 </div> 1793 <div class="modal-footer"> 1794 <div class="center-btns"> 1795 <button class="btn btn-primary js-monitoring" data-dismiss="modal" aria-hidden="true">@Translate("SmartPage:Product.Modal.Close", "Luk")</button> 1796 <a href="@QueryHelper.ReplaceQueryStringParam(removeLink, "action", "subscribe")" class="btn btn-primary js-subscription">@Translate("SmartPage:Product.Modal.Close", "Luk")</a> 1797 </div> 1798 </div> 1799 </div> 1800 <!-- /.modal-content --> 1801 </div> 1802 <!-- /.modal-dialog --> 1803 </div> 1804 <!-- /.modal --> 1805 <!-- Modal --> 1806 <div id="delete-subscription" class="modal fade" tabindex="-1" role="dialog"> 1807 <div class="modal-dialog"> 1808 <div class="modal-content"> 1809 <div class="modal-header"> 1810 <button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button> 1811 <h4 class="modal-title">@Translate("SmartPage:Product.Modal.Header.Unsubscribe", "Afmeld")</h4> 1812 </div> 1813 <div class="modal-body"> 1814 <div class="js-monitoring hide"> 1815 <p>@Translate("SmartPage:Product.Text.Header.MonitoringUnsubscribe", "Er du sikker på at du vil afmelde overvågning?")</p> 1816 </div> 1817 <div class="js-subscription hide"> 1818 <p>@Translate("SmartPage:Product.Modal.Header.SubscriptionUnsubscribe", "Er du sikker på at du vil afmelde abonnementet?")</p> 1819 </div> 1820 </div> 1821 <div class="modal-footer"> 1822 <div class="center-btns"> 1823 <button class="btn" data-dismiss="modal" aria-hidden="true">@Translate("SmartPage:Product.Modal.Button.Dismiss", "Fortryd")</button> 1824 <button class="btn btn-primary js-btn-delete-subscription">@Translate("SmartPage:Product.Modal.Button.Unsubscribe", "Afmeld")</button> 1825 </div> 1826 </div> 1827 </div> 1828 </div> 1829 </div> 1830 1831 <!-- Modal --> 1832 <div id="unsubscribe-error" class="modal fade" tabindex="-1" role="dialog"> 1833 <div class="modal-dialog"> 1834 <div class="modal-content"> 1835 <div class="modal-header"> 1836 <button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button> 1837 <h4 class="modal-title">@Translate("SmartPage:Product.Modal.Header.UnsubscriptionFailure", "Afmelding fejlet")</h4> 1838 </div> 1839 <div class="modal-body"> 1840 <p>@Translate("SmartPage:Product.Modal.Text.UnsubscriptionFailure", "Det var ikke muligt at afmelde - prøv venligst igen senere eller tag kontakt til Dansk Standard")</p> 1841 <p>@Translate("SmartPage:Product.Modal.Text.CheckLoggedIn", "Vær sikker på at du er logget ind")</p> 1842 </div> 1843 <div class="modal-footer"> 1844 <div class="center-btns"> 1845 <button class="btn btn-info" data-dismiss="modal" aria-hidden="true">@Translate("SmartPage:Product.Modal.Close", "Luk")</button> 1846 </div> 1847 </div> 1848 </div> 1849 </div> 1850 </div> 1851 1852 @SnippetStart("JavaScript") 1853 <script type="text/javascript"> 1854 var item, subscriptionType; 1855 1856 function showNeededText(result) { 1857 if (result.d.SubscriptionExists) { 1858 $(".js-subscription-exists .js-exists").show(); 1859 $(".js-subscription-exists .js-not-exists").hide(); 1860 1861 if (item.subscriptionType == "Dia2" || item.subscriptionType == "Emne2") { 1862 if (item.subscriptionType == "Dia2") { 1863 $(".js-standard").show(); 1864 $(".js-subject").hide(); 1865 } 1866 else if (item.subscriptionType == "Emne2") { 1867 $(".js-standard").hide(); 1868 $(".js-subject").show(); 1869 } 1870 } 1871 else if (item.subscriptionType == "Dia1" || item.subscriptionType == "Emne1") { 1872 if (item.subscriptionType == "Dia1") { 1873 $(".js-standard").show(); 1874 $(".js-subject").hide(); 1875 } 1876 else if (item.subscriptionType == "Emne1") { 1877 $(".js-standard").hide(); 1878 $(".js-subject").show(); 1879 } 1880 } 1881 1882 } else { 1883 $(".js-subscription-exists .js-exists").hide(); 1884 $(".js-subscription-exists .js-not-exists").show(); 1885 if (item.subscriptionType == "Dia2" || item.subscriptionType == "Emne2") { 1886 if (item.subscriptionType == "Dia2") { 1887 $(".js-standard").show(); 1888 $(".js-subject").hide(); 1889 } 1890 else if (item.subscriptionType == "Emne2") { 1891 $(".js-standard").hide(); 1892 $(".js-subject").show(); 1893 } 1894 } 1895 else if (item.subscriptionType == "Dia1" || item.subscriptionType == "Emne1") { 1896 if (item.subscriptionType == "Dia1") { 1897 $(".js-standard").show(); 1898 $(".js-subject").hide(); 1899 } 1900 else if (item.subscriptionType == "Emne1") { 1901 $(".js-standard").hide(); 1902 $(".js-subject").show(); 1903 } 1904 } 1905 } 1906 $(".js-subscription-exists").modal('show'); 1907 } 1908 $(document).ready(function () { 1909 $(".js-btn-subscription").click(function (event) { 1910 subscriptionType = $(this).attr("data-type"); 1911 item = { 1912 id: $(this).attr("data-id"), 1913 subscriptionType: subscriptionType 1914 }; 1915 1916 if (item.subscriptionType == "Dia2" || item.subscriptionType == "Emne2") { 1917 $(".modal .js-monitoring").removeClass("hide"); 1918 $(".modal .js-subscription").addClass("hide"); 1919 } else if (item.subscriptionType == "Dia1" || item.subscriptionType == "Emne1") { 1920 $(".modal .js-monitoring").addClass("hide"); 1921 $(".modal .js-subscription").removeClass("hide"); 1922 } 1923 }); 1924 1925 $(".js-subscription-create").click(function () { 1926 var productContainer = $(this).closest(".js-product-informations"); 1927 subscriptionType = $(this).attr("data-type"); 1928 itemObj = { 1929 id: $(this).attr("data-id"), 1930 subscriptionType: subscriptionType 1931 }; 1932 1933 if (itemObj.subscriptionType == "Dia2" || itemObj.subscriptionType == "Emne2") { 1934 $(".modal .js-monitoring").removeClass("hide"); 1935 $(".modal .js-subscription").addClass("hide"); 1936 } else if (itemObj.subscriptionType == "Dia1" || itemObj.subscriptionType == "Emne1") { 1937 $(".modal .js-monitoring").addClass("hide"); 1938 $(".modal .js-subscription").removeClass("hide"); 1939 } 1940 1941 item = { 1942 productId: $("input[name=ProductID]", productContainer).val(), 1943 variantId: $("input[name=VariantID]", productContainer).val(), 1944 subscriptionType: subscriptionType 1945 }; 1946 1947 $.ajax({ 1948 type: 'POST', 1949 url: '/Services/SubscriptionService.asmx/SubscriptionExists', 1950 data: JSON.stringify(item), 1951 contentType: "application/json; charset=utf-8", 1952 dataType: 'json', 1953 processdata: true, 1954 beforeSend: function () { startLoading(); }, 1955 complete: function (jqXHR, status) { endLoading(); }, 1956 success: function (result) { 1957 1958 if (result.d.Success) { 1959 showNeededText(result); 1960 } else if (!result.d.IsLoggedIn) { 1961 $(".js-subscription-not-loggedin").modal('show'); 1962 } else { 1963 $(".js-subscription-no-access").modal('show'); 1964 } 1965 } 1966 }); 1967 return false; 1968 }); 1969 1970 $(".js-group-subscription-create").click(function () { 1971 1972 $.ajax({ 1973 type: 'POST', 1974 url: '/Services/SubscriptionService.asmx/SubscriptionGroupExists', 1975 data: JSON.stringify(item), 1976 contentType: "application/json; charset=utf-8", 1977 dataType: 'json', 1978 processdata: true, 1979 beforeSend: function () { startLoading(); }, 1980 complete: function (jqXHR, status) { endLoading(); }, 1981 success: function (result) { 1982 1983 if (result.d.Success) { 1984 showNeededText(result); 1985 1986 } else if (!result.d.IsLoggedIn) { 1987 $(".js-subscription-not-loggedin").modal('show'); 1988 } else { 1989 $(".js-subscription-no-access").modal('show'); 1990 } 1991 } 1992 }); 1993 1994 return false; 1995 }); 1996 1997 $(".js-btn-delete-subscription").click(function (event) { 1998 console.log(item); 1999 $.ajax({ 2000 type: 'POST', 2001 url: '/Services/SubscriptionService.asmx/DeleteSubscription', 2002 data: JSON.stringify(item), 2003 contentType: "application/json; charset=utf-8", 2004 dataType: 'json', 2005 processdata: true, 2006 beforeSend: function () { startLoading(); }, 2007 complete: function (jqXHR, status) { endLoading(); }, 2008 success: function (result) { 2009 2010 if (result.d.Success) { 2011 window.location.href = "@QueryHelper.ReplaceQueryStringParam(removeLink, "action", "remove")"; 2012 } else { 2013 $('#delete-subscription').modal('hide'); 2014 $('#unsubscribe-error').modal('show'); 2015 } 2016 } 2017 }); 2018 }); 2019 2020 $(".js-confirm-subscription").click(function () { 2021 $(".js-subscription-exists").modal("hide"); 2022 2023 var url; 2024 if (item.hasOwnProperty("productId")) { 2025 url = '/Services/SubscriptionService.asmx/CreateSubscription'; 2026 } else { 2027 item.languageId = _languageId; 2028 url = '/Services/SubscriptionService.asmx/CreateGroupSubscription'; 2029 } 2030 2031 $.ajax({ 2032 type: 'POST', 2033 url: url, 2034 data: JSON.stringify(item), 2035 contentType: "application/json; charset=utf-8", 2036 dataType: 'json', 2037 processdata: true, 2038 beforeSend: function () { startLoading(); }, 2039 complete: function (jqXHR, status) { endLoading(); }, 2040 success: function (result) { 2041 2042 if (result.d.Success) { 2043 $(".js-subscription-confirmation .js-success").removeClass("hide"); 2044 $(".js-subscription-confirmation .js-failure").addClass("hide"); 2045 2046 if (item.subscriptionType == "Dia2" || item.subscriptionType == "Emne2") { 2047 if (item.subscriptionType == "Dia2") { 2048 $(".js-success-standard").show(); 2049 $(".js-success-subject").hide(); 2050 } 2051 else if (item.subscriptionType == "Emne2") { 2052 $(".js-success-standard").hide(); 2053 $(".js-success-subject").show(); 2054 } 2055 } 2056 else if (item.subscriptionType == "Dia1" || item.subscriptionType == "Emne1") { 2057 if (item.subscriptionType == "Dia1") { 2058 $(".js-success-standard").show(); 2059 $(".js-success-subject").hide(); 2060 } 2061 else if (item.subscriptionType == "Emne1") { 2062 $(".js-success-standard").hide(); 2063 $(".js-success-subject").show(); 2064 } 2065 } 2066 } else { 2067 $(".js-subscription-confirmation .js-success").addClass("hide"); 2068 $(".js-subscription-confirmation .js-failure").removeClass("hide"); 2069 } 2070 $(".js-subscription-confirmation").modal('show'); 2071 } 2072 }); 2073 2074 return false; 2075 }); 2076 2077 $(".js-subscription-not-loggedin .js-close").click(function () { 2078 $(".js-subscription-not-loggedin").modal('hide'); 2079 $("#LoginBox").modal('show'); 2080 }); 2081 }); 2082 </script> 2083 @SnippetEnd("JavaScript") 2084 2085 2086 @SnippetStart("JavaScript") 2087 <script src='@designURL/assets/plugins/pdf.js/minified/compatibility.js'></script> 2088 <script src='@designURL/assets/plugins/pdf.js/minified/pdf.js'></script> 2089 <script> 2090 document.dispatchEvent(new Event('Smartpage:ProductPageLoaded')); 2091 </script> 2092 @SnippetEnd("JavaScript")