Denne side understøttes ikke optimalt i Internet Explorer. Vi anbefaler derfor, at du benytter en anden browser (fx Google Chrome, Edge, Firefox etc.)
Error executing template "Designs/Bolind/eCom/ProductCatalog/basic_Pim.cshtml"
System.InvalidOperationException: Sequence contains no elements
   at System.Linq.Enumerable.First[TSource](IEnumerable`1 source)
   at CompiledRazorTemplates.Dynamic.RazorEngine_cf8ae037646c4e018853eec6b8df0114.Execute() in E:\Solutions\Bolind\Web\Live\Files\Templates\Designs\Bolind\eCom\ProductCatalog\basic_Pim.cshtml:line 58
   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 @using System.Globalization 2 @using NLWI.Core.Factory 3 @using System.Linq; 4 @using Bolind.Web.CustomCode 5 @using Bolind.Web.CustomCode.CDN 6 @using Bolind.Web.CustomCode.Ecom.NonProducts.Fees 7 @using Bolind.Web.CustomCode.Ecom.NonProducts.Fittings 8 @using Bolind.Web.CustomCode.Ecom.NonProducts.Insurances 9 @using Bolind.Web.CustomCode.Ecom.ProductInformation 10 @using Bolind.Web.Files.Templates.Designs.Bolind.eCom.ProductCatalog.Model 11 @using Dynamicweb.Ecommerce 12 @using Dynamicweb.Ecommerce.Common 13 @using Dynamicweb.Ecommerce.Prices 14 @using Dynamicweb.Ecommerce.Products 15 @using Dynamicweb.Security.UserManagement.Synchronization 16 @using NORRIQ.Seo.Canonical 17 @using Newtonsoft.Json 18 @using NLWI.Platforms.Dynamicweb9.Specs.ViewModels 19 @inherits Dynamicweb.Rendering.ViewModelTemplate<Dynamicweb.Ecommerce.ProductCatalog.ProductViewModel> 20 @{ 21 // Configuration 22 var basicPimPrefix = "PDP "; 23 var isReplacementSearch = System.Web.HttpContext.Current.Request.QueryString["isReplacementSearch"] != null; 24 25 // Specs 26 var specs = Model.GetSpecifications(); 27 var specsToList = new HashSet<string>(specs.GetByKey("WebListFields").Value.Split(new[] { "," }, StringSplitOptions.RemoveEmptyEntries)); 28 var minPurchase = Model.GetMinPurchase(); 29 var stockFactor = Model.GetStockFactor(); 30 var escapeMinPurch = Model.GetEscapeMinPurch(); 31 var unit = Model.GetUnitId(); 32 var fittings = Model.GetFittings(); 33 var replacementProductsIds = Model.GetReplacementProducts(); 34 var listPrice = Model.GetListPrice(); 35 var ABC = Model.GetAbcCategory(); 36 var extraWarranty = Model.IsExtraWarrantyMarked(); 37 var betterchoise = Model.IsBolindBetterChoise(); 38 var isCampaign = Model.IsCampaign(); 39 var relatedProducts = Model.GetRelatedProducts(); 40 var spareParts = Model.GetSpareParts(); 41 var listedSpecs = specs.GetAvailableKeys().Where(a => specsToList.Contains(a) || specsToList.Count == 0).ToList(); 42 var vatPercent = Model.Price.VATPercent; 43 var taxProducts = Model.GeTaxProducts(); 44 var splashSpecs = specs.GetAllByKey("WebSplash").FirstOrDefault(); 45 var splash = splashSpecs?.GetReferenceSpecification(); 46 var showSplash = splash != null && Model.ShowSplash(); 47 var isExtendedPdp = Model.IsExtendedPdp(); 48 var quantityPrices = Model.GetQuantityPrices(); 49 var hasLongDeliveryTime = Model.HasLongDeliveryTime(); 50 var hasManyInStock = Model.HasManyInStock(); 51 var isOperatingGoodsGroup = Model.IsOperatingGoodsGroup(); 52 var isAppliances = Model.IsAppliances(); 53 var stockAmount = Model.DFStockAmount(); 54 var extendedFields = new HashSet<string>(specs.GetByKey("WebDetailFields").Value.Split(',')); 55 var altText = Model.GetAltText(); 56 var hasInsurance = Model.GetInsuranceField() != ""; 57 var perfionId = Model.GetPerfionId(); 58 var productId = Services.ProductGroups.GetProductGroupRelations(Model.Id).First()?.GroupId; 59 var productGroup = Services.ProductGroups.GetGroup(productId); 60 // For extendedPDP 61 var brandName = specs.GetByKey("Brandname").Value; 62 var energyLabel = specs.GetByKey("Energilabel").Value; 63 var energyClass = specs.GetByKey("Energiklasse").Value; 64 var energyColor = specs.GetByKey("EnergiFarve").Value; 65 var supplierProductNumber = specs.GetByKey("Leverandørensvarenummer").Value; 66 var producType = specs.GetByKey("Produkttype").Value; 67 var salesBullets = specs.GetByKey("Bullets").Value.Split(new[] { ";" }, StringSplitOptions.RemoveEmptyEntries); 68 var documentationSecurityPaper = specs.GetByKey("Sikkerhedsdatablad"); 69 var documentationProductPaper = specs.GetByKey("Produktdatablad"); 70 var documentationLink = specs.GetByKey("Link"); 71 var productSheetPdf = specs.GetByKey(""); // TODO add key for Product Sheet Pdf-path 72 var brandLogoGuid = Model.ProductFields["BrandLogoGuid"]?.Value?.ToString(); 73 var energyClassGuid = Model.ProductFields["EnergyClassGuid"]?.Value?.ToString(); 74 var hasEnergyClass = !string.IsNullOrEmpty(energyClassGuid); 75 var sustainableLogoGuidsString = Model.ProductFields["SustainableLogos"]?.Value?.ToString(); 76 var sustainableLogoGuids = new List<string>(); 77 var mainIsCoolDown = Model.GetIsMainProductCoolDown(); 78 if (!string.IsNullOrEmpty(sustainableLogoGuidsString)) 79 { 80 sustainableLogoGuids = sustainableLogoGuidsString.Split(';').ToList(); 81 } 82 83 var showRelatedFirst = productGroup.ProductGroupFieldValues.GetProductGroupFieldValue("ShowAlternativeFirst").Value; 84 while (!showRelatedFirst.Equals(true) && productGroup.ParentGroups.FirstOrDefault() != null) 85 { 86 productGroup = productGroup.ParentGroups.FirstOrDefault(); 87 showRelatedFirst = productGroup.ProductGroupFieldValues.GetProductGroupFieldValue("ShowAlternativeFirst").Value; 88 } 89 90 var energyLabelNew = specs.GetByKey("EnergilabelNEW").Value; 91 var hasNewEnergyLabel = false; 92 93 if (!string.IsNullOrEmpty(energyLabelNew)) 94 { 95 DateTime newEnergilabelActiveFromSpec; 96 DateTime oldEnergilabelActiveToSpec; 97 98 if (DateTime.TryParse(specs.GetByKey("EnergilabelActiveTo").Value, out oldEnergilabelActiveToSpec) && oldEnergilabelActiveToSpec.Date > DateTime.Now.Date) 99 { 100 energyLabel = string.Empty; 101 } 102 103 if (DateTime.TryParse(specs.GetByKey("EnergilabelActiveFrom").Value, out newEnergilabelActiveFromSpec) && newEnergilabelActiveFromSpec.Date <= DateTime.Now.Date) 104 { 105 energyLabel = energyLabelNew; 106 hasNewEnergyLabel = true; 107 } 108 } 109 110 var allowZeroPrice = Model.AllowZeroPrice(); 111 112 // Services 113 var urlService = ObjectFactory.GetInstance<IProductUrlService>(); 114 115 // Variables 116 var B2C = Pageview.IsB2C(); 117 var images = new List<ProductSpecification>(); 118 119 var variantCodes = Model.GetVariants(); 120 121 var primaryPhoto = specs.GetByKey("Primærfoto"); 122 if (primaryPhoto != null && !string.IsNullOrEmpty(primaryPhoto.Value)) 123 { 124 images.Add(primaryPhoto); 125 } 126 127 foreach (var img in specs.GetAllByKey("AlternativeBilleder")) 128 { 129 if (!string.IsNullOrEmpty(img.Value) && !images.Any(i => string.Equals(i.Value, img.Value))) 130 { 131 images.Add(img); 132 } 133 } 134 135 var actionColor = B2C ? "btn-success" : "btn-danger"; 136 137 var extended = isExtendedPdp ? "extended" : "simple"; 138 var priceWithVat = Model.Price.PriceWithVat.ToString("#.00"); 139 140 // Produktblade 141 var basePath = System.Web.Hosting.HostingEnvironment.ApplicationPhysicalPath; 142 var produktbladUrl = basePath + "Files\\Reports\\Produktblade\\Produktblade\\" + Model.Number + ".pdf"; 143 bool showProduktblad = System.IO.File.Exists(produktbladUrl); 144 145 var produktbladsPdfUrl = "/files/reports/produktblade/produktblade/" + Model.Number + ".pdf"; 146 147 } 148 149 @{ 150 var variants = new List<CustomVariant>(); 151 if (variantCodes.Any()) 152 { 153 var productService = ObjectFactory.GetInstance<ProductService>(); 154 foreach (var code in variantCodes) 155 { 156 var p = productService.GetProductById(Model.Id, code, true); 157 var autoId = productService.GetProductFieldValue(p, "NiqProductAutoId") as int? ?? 0; 158 var isCoolDownProduct = productService.GetProductFieldValue(p, "IsCoolDownProduct") as bool? ?? false; 159 var textOne = Model.GetSpecificationsForSpecificProduct(autoId).GetByKey("VariantTextOne")?.Value ?? ""; 160 var textTwo = Model.GetSpecificationsForSpecificProduct(autoId).GetByKey("VariantTextTwo")?.Value ?? ""; 161 variants.Add(new CustomVariant(code, textOne, textTwo, isCoolDownProduct)); 162 } 163 } 164 165 } 166 @if (Pageview.User != null) 167 { 168 <favorite-list ref="favoriteList"></favorite-list> 169 } 170 <product-details-simple-pim default-variant="@Model.VariantId" 171 :main-is-cool-down="@mainIsCoolDown.ToString().ToLower()" 172 item-number="@Model.Id" 173 :variants='@(variantCodes != null && variantCodes.Any() ? JsonConvert.SerializeObject(variants) : "[]")' 174 :images='@JsonConvert.SerializeObject(images.Select(a => a.Value).ToArray())' 175 :fullimages='@JsonConvert.SerializeObject(images.Select(a => Pageview.CdnWrap($"/Admin/Public/GetImage.ashx?Width=2000&amp;Height=1600&amp;Crop=5&amp;Compression=90&amp;Image={a.Value}")).ToArray())' 176 inline-template> 177 178 <div class="extended basic_pim" v-bind:class="{'initialized': initialized }" itemscope="" itemtype="https://schema.org/Product"> 179 <section class="basic_pim-head"> 180 @if (isExtendedPdp) 181 { 182 <h1 itemprop="name"> 183 <span class="brand">@brandName</span> 184 <small>@producType, @supplierProductNumber</small> 185 </h1> 186 187 } 188 else 189 { 190 <h1 itemprop="name"> 191 @Model.Name 192 @if (Model.ProductFields.Where(a => a.Key.Contains("Desc")).Any()) 193 { 194 <small> 195 @foreach (var i in Model.ProductFields.Where(a => a.Key.Contains("Desc"))) 196 { 197 <text>@i.Value.Value </text> 198 } 199 </small> 200 } 201 </h1> 202 } 203 @if (brandLogoGuid != null) 204 { 205 <img src="@Pageview.CdnWrap($"/Files/Images/Ecom/Brands/{brandLogoGuid}.png")" alt="@brandName" class="img-fluid" /> 206 } 207 </section> 208 <section class="basic_pim-pdp"> 209 <div class="basic_pim-media"> 210 @if (showSplash) 211 { 212 var splashShape = splash.GetByKey("WebSplashShape").Value.ToLower(); 213 var splashColor = splash.GetByKey("WebSplashColor").Value.ToLower(); 214 var splashText = splash.GetByKey("WebSplashText").Value; 215 <span class="label-top @splashShape-@splashColor-lg"> 216 <span class="splash-title">@splashText</span> 217 </span> 218 } 219 @if (betterchoise) 220 { 221 <div style="position: absolute; z-index: 5; display: flex; bottom: 130px; left: 50px"> 222 <span class="label-bolig"> 223 <img src="@Pageview.CdnWrap("/Files/Images/Graphics/betterchoise.png")" 224 class="img-fluid" 225 alt="@Translate(basicPimPrefix + "betterchoise", "betterchoise")"/> 226 </span> 227 </div> 228 } 229 <div class="label-wrap"> 230 231 232 @if (extraWarranty) 233 { 234 <span class="label-ExtraWarranty"> 235 <img src="@Pageview.CdnWrap("/Files/Images/Graphics/reklamationsret.png")" 236 class="img-fluid" 237 title="@Translate(basicPimPrefix + "UdvidetGarantiText", "Udvidet Garanti")" 238 alt="@Translate(basicPimPrefix + "Reklamationsret", "Reklamationsret")" style="height: 150px"/> 239 </span> 240 } 241 </div> 242 <gallery :items="$attrs.fullimages" :index="index" @@close="index = null"> 243 </gallery> 244 <template v-if="$attrs.images.length > 1"> 245 <slick ref="slick" 246 class="basic_pim-images basic_pim-slick-images" 247 id="pdp-images" title="@Translate(basicPimPrefix + "Zoom In", "Se billede")" 248 :options="slickPimOptionsImages"> 249 <picture class="basic_pim-image" v-for="(image, imageIndex) in $attrs.images" :key="imageIndex" @@click="setIndex(imageIndex)"> 250 <source media="(max-width:767.98px)" :srcset="'@Pageview.CdnWrap("/Admin/Public/GetImage.ashx?Width=300&amp;Height=250&amp;Compression=85&amp;Crop=5&amp;Image=")' + image"> 251 <source media="(max-width:991.98px)" :srcset="'@Pageview.CdnWrap("/Admin/Public/GetImage.ashx?Width=400&amp;Height=350&amp;Compression=85&amp;Crop=5&amp;Image=")' + image"> 252 <img :src="'@Pageview.CdnWrap("/Admin/Public/GetImage.ashx?Width=538&amp;Height=508&amp;Compression=85&amp;Crop=5&amp;Image=")' + image" alt="@altText" class="img-fluid" itemprop="image"/> 253 </picture> 254 </slick> 255 <slick ref="slick" class="basic_pim-thumbs" id="pdp-thumbs" :options="slickPimOptionsThumbs"> 256 <figure v-for="thumb in $attrs.images" class="basic_pim-thumb"> 257 <img :src="'@Pageview.CdnWrap("/Admin/Public/GetImage.ashx?Width=50&amp;Height=50&amp;Compression=85&amp;Crop=5&amp;Image=")' + thumb" alt="@altText" class="img-fluid"/> 258 </figure> 259 </slick> 260 </template> 261 <template v-if="$attrs.images.length == 1"> 262 <div class="basic_view-images"> 263 <picture class="basic_pim-image" title="@Translate(basicPimPrefix + "Zoom In", "Se billede")" v-for="(image, imageIndex) in $attrs.images" :key="imageIndex" @@click="setIndex(imageIndex)"> 264 <source media="(max-width:767.98px)" :srcset="'@Pageview.CdnWrap("/Admin/Public/GetImage.ashx?Width=300&amp;Height=250&amp;Compression=85&amp;Crop=5&amp;Image=")' + image"> 265 <source media="(max-width:991.98px)" :srcset="'@Pageview.CdnWrap("/Admin/Public/GetImage.ashx?Width=400&amp;Height=350&amp;Compression=85&amp;Crop=5&amp;Image=")' + image"> 266 <img :src="'@Pageview.CdnWrap("/Admin/Public/GetImage.ashx?Width=538&amp;Height=508&amp;Compression=85&amp;Crop=5&amp;Image=")' + image" alt="@altText" class="img-fluid" itemprop="image"> 267 </picture> 268 </div> 269 </template> 270 <template v-if="$attrs.images.length == 0"> 271 @{ 272 var pdpImage = "/Files/Images/Default.png"; 273 } 274 <div class="basic_pim-image image-default"> 275 <picture class="basic_view-images"> 276 <source media="(max-width:48rem)" srcset="@Pageview.CdnWrap($"/Admin/Public/GetImage.ashx?Width=300&amp;Height=250&amp;Compression=85&amp;Crop=5&amp;Image={pdpImage}")"> 277 <source media="(max-width:80rem)" srcset="@Pageview.CdnWrap($"/Admin/Public/GetImage.ashx?Width=400&amp;Height=350&amp;Compression=85&amp;Crop=5&amp;Image={pdpImage}")"> 278 <img src="@Pageview.CdnWrap($"/Admin/Public/GetImage.ashx?Width=538&amp;Height=508&amp;Compression=85&amp;Crop=5&amp;Image={pdpImage}")" alt="@Translate(basicPimPrefix + "No product picture", "No product picture")" class="img-fluid" itemprop="image"> 279 </picture> 280 </div> 281 </template> 282 </div> 283 <div class="basic_pim-content @extended"> 284 285 @if (isExtendedPdp) 286 { 287 <section class="salespoints"> 288 <div> 289 @if (Model.ProductFields.Where(a => a.Key.Contains("Desc")).Any()) 290 { 291 <header> 292 <h2> 293 @foreach (var i in Model.ProductFields.Where(a => a.Key.Contains("Desc"))) 294 { 295 <text>@i.Value.Value </text> 296 } 297 </h2> 298 </header> 299 } 300 @if (salesBullets.Any()) 301 { 302 <main> 303 <ul class="list-unstyled listed"> 304 @foreach (var bullet in salesBullets) 305 { 306 <li>@bullet</li> 307 } 308 </ul> 309 </main> 310 } 311 </div> 312 313 <div> 314 @if (hasEnergyClass) 315 { 316 <div class="energy energy-align"> 317 <div class="energy-label energy-label-align"> 318 <div class="energy-in"> 319 <img src="@Pageview.CdnWrap("/Files/Images/Ecom/EnergyClass/" + energyClassGuid + ".png")" 320 class="img-fluid" 321 style="height: 40px;"/> 322 </div> 323 </div> 324 </div> 325 if (!string.IsNullOrEmpty(energyLabel)) 326 { 327 <div class="energybookmark"> 328 <a href="@Pageview.SearchFriendlyUrl#energylabel">@Translate("EU-Datablad", "EU-Datablad")</a> 329 </div> 330 } 331 } 332 333 @{ 334 if (showProduktblad) 335 { 336 <div class="energybookmark"> 337 <a href="@produktbladsPdfUrl" target="_blank"><img class="pdf-icon" src="/src/bolind/icons/pdf.svg" alt="PDF icon"/><br/>@Translate("Product-sheet", "Produktark")</a> 338 </div> 339 } 340 } 341 342 </div> 343 </section> 344 <ul class="list-unstyled stroked list-nav"> 345 <li> 346 <a href="@Pageview.SearchFriendlyUrl#spec">@Translate(basicPimPrefix + "Se specs", "Se alle specifikationer")</a> 347 </li> 348 <li> 349 <a href="@Pageview.SearchFriendlyUrl#desc">@Translate(basicPimPrefix + "Se beskrivelse", "Se produktbeskrivelse")</a> 350 </li> 351 </ul> 352 } 353 @if (isReplacementSearch) 354 { 355 string originalSearchQuery = System.Web.HttpContext.Current.Request["originalSearchQuery"]; 356 357 <p class="alert alert-warning alert-icon"> 358 <svg class="larger"> 359 <use xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="/Files/dist/icons/icons.svg#info-circle"></use> 360 </svg> 361 <span class="wrap"> 362 <span class="strong"> 363 @Translate(basicPimPrefix + "Erstatningsvare-title", "Erstatningsvare") 364 </span><br/> 365 366 <span> 367 @Translate(basicPimPrefix + "Du har søgt på dette varenummer", "Du har søgt på dette varenummer") @originalSearchQuery, @Translate(basicPimPrefix + "som er udgået.", "som er udgået.") 368 <br/> 369 @Translate(basicPimPrefix + "Varen er erstattet af den viste vare") @Model.Number, @Translate(basicPimPrefix + "som svarer til den udgåede.") 370 </span> 371 </span> 372 </p> 373 } 374 @if (hasEnergyClass && !isExtendedPdp) 375 { 376 <section class="salespoints"> 377 <div></div> 378 <div> 379 <div class="energy"> 380 <div class="energy-label"> 381 <div class="energy-in"> 382 <img src="@Pageview.CdnWrap("/Files/Images/Ecom/EnergyClass/" + energyClassGuid + ".png")" 383 class="img-fluid" 384 style="height: 40px;"/> 385 </div> 386 </div> 387 </div> 388 @if (!string.IsNullOrEmpty(energyLabel)) 389 { 390 <div class="energybookmark"> 391 <a href="@Pageview.SearchFriendlyUrl#energylabel">@Translate("EU-Datablad", "EU-Datablad")</a> 392 </div> 393 } 394 </div> 395 </section> 396 } 397 @if (B2C || Pageview.User != null) 398 { 399 <div class="pricing" itemprop="offers" itemscope itemtype="https://schema.org/Offer"> 400 <div class="priceinfo"> 401 <p> 402 @{ 403 foreach (var logoGuid in sustainableLogoGuids) 404 { 405 if (!string.IsNullOrEmpty(logoGuid)) 406 { 407 <img src="@Pageview.CdnWrap("/Files/Images/Graphics/" + logoGuid + ".png")" 408 class="img-fluid" 409 style="max-height: 75px; margin-right: 8px" /> 410 } 411 } 412 } 413 </p> 414 <p class="basic_pim-sku iconed" itemprop="sku"> 415 <svg> 416 <use xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="/Files/dist/icons/icons.svg#barcode"></use> 417 </svg> 418 @Translate(basicPimPrefix + "Product number", "Product number"): @Model.Number 419 </p> 420 421 @if (!mainIsCoolDown) 422 { 423 if (isOperatingGoodsGroup) 424 { 425 <p class="stockstatus" alt="Red" v-if="notInStock()"> 426 <svg> 427 <use xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="/Files/dist/icons/icons.svg#truck"></use> 428 </svg> 429 <span> 430 @if (ABC == "A") 431 { 432 @Translate(basicPimPrefix + "Ikke på lager A", "Ikke på lager") 433 } 434 else if (ABC == "B") 435 { 436 @Translate(basicPimPrefix + "Ikke på lager B", "Ikke på lager") 437 } 438 else if (ABC == "C") 439 { 440 @Translate(basicPimPrefix + "Ikke på lager C", "Ikke på lager") 441 } 442 </span> 443 </p> 444 445 <p class="stockstatus" alt="A" v-if="manyInStock(@minPurchase, @stockFactor)"> 446 <svg> 447 <use xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="/Files/dist/icons/icons.svg#truck"></use> 448 </svg> 449 <span>{{stock}} @Translate(basicPimPrefix + " DF på lager", "på lager")</span> 450 </p> 451 452 <p class="stockstatus" alt="B" v-if="!manyInStock(@minPurchase, @stockFactor) && !notInStock()"> 453 <svg> 454 <use xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="/Files/dist/icons/icons.svg#truck"></use> 455 </svg> 456 <span>@Translate(basicPimPrefix + "Få på lager", "Få på lager")</span> 457 </p> 458 459 } 460 else if (isAppliances) 461 { 462 <p class="stockstatus" alt="Red" v-if="notInStock()"> 463 <svg> 464 <use xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="/Files/dist/icons/icons.svg#truck"></use> 465 </svg> 466 <span> 467 @if (ABC == "A") 468 { 469 @Translate(basicPimPrefix + "Ikke på lager A", "Ikke på lager") 470 } 471 else if (ABC == "B") 472 { 473 @Translate(basicPimPrefix + "Ikke på lager B", "Ikke på lager") 474 } 475 else if (ABC == "C") 476 { 477 @Translate(basicPimPrefix + "Ikke på lager C", "Ikke på lager") 478 } 479 </span> 480 </p> 481 482 <p class="stockstatus" alt="A" v-if="manyInStock(1, 3)"> 483 <svg> 484 <use xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="/Files/dist/icons/icons.svg#truck"></use> 485 </svg> 486 <span>{{stock}} @Translate(basicPimPrefix + " DF på lager", "på lager")</span> 487 </p> 488 489 <p class="stockstatus" alt="B" v-if="!manyInStock(1, 3) && !notInStock()"> 490 <svg> 491 <use xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="/Files/dist/icons/icons.svg#truck"></use> 492 </svg> 493 <span>@Translate(basicPimPrefix + "Få på lager", "Få på lager")</span> 494 </p> 495 <div v-if="wagStock>0" class="stockstatus"> 496 <svg style="fill: #004c6a" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 640 512"> 497 <path d="M0 488V171.3c0-26.2 15.9-49.7 40.2-59.4L308.1 4.8c7.6-3.1 16.1-3.1 23.8 0L599.8 111.9c24.3 9.7 40.2 33.3 40.2 59.4V488c0 13.3-10.7 24-24 24H568c-13.3 0-24-10.7-24-24V224c0-17.7-14.3-32-32-32H128c-17.7 0-32 14.3-32 32V488c0 13.3-10.7 24-24 24H24c-13.3 0-24-10.7-24-24zm488 24l-336 0c-13.3 0-24-10.7-24-24V432H512l0 56c0 13.3-10.7 24-24 24zM128 400V336H512v64H128zm0-96V224H512l0 80H128z"/> 498 </svg> 499 <span>{{ wagStock }} @Translate(basicPimPrefix + " wag på lager", "på fjernlager")</span> 500 </div> 501 } 502 else 503 { 504 if (!string.IsNullOrEmpty(ABC) && !B2C) 505 { 506 <p class="stockstatus" alt="@ABC"> 507 @if (ABC == "A") 508 { 509 <svg> 510 <use xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="/Files/dist/icons/icons.svg#truck"></use> 511 </svg> 512 <span>@Translate("ABC A Text", "Kort leveringstid")</span> 513 } 514 @if (ABC == "B") 515 { 516 <svg> 517 <use xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="/Files/dist/icons/icons.svg#truck"></use> 518 </svg> 519 <span>@Translate("ABC B Text", "Forvent leveringstid")</span> 520 } 521 </p> 522 } 523 } 524 525 if (isOperatingGoodsGroup && hasLongDeliveryTime) 526 { 527 <div> 528 <p> 529 <a href="#related-products" class="long-delivery-time"> 530 @Translate(basicPimPrefix + "Lang leveringstid", "Denne vare har lang leveringstid. Se alternative her") 531 </a> 532 </p> 533 </div> 534 } 535 } 536 </div> 537 <div class="prices"> 538 @if (Pageview.User != null) 539 { 540 <async-price class-type="asyncprice-pdp" 541 default-price-without-vat="@Model.Price.PriceWithoutVat" 542 product-id="@Model.Id" 543 :variant-id="variantId" 544 unit-of-measure="@unit" 545 :list-price="@JsonConvert.SerializeObject(listPrice)" 546 price-group="" 547 is-campaign="@isCampaign" 548 @@update-stock="setLiveStock" 549 :is-cool-down-product="isCoolDown" 550 :allow-zero-price="@allowZeroPrice.ToString().ToLower()"> 551 </async-price> 552 } 553 else if (B2C) 554 { 555 <p class="listprice" v-if="showListPrice(@listPrice, @Model.Price.PriceWithVat)"> 556 @Translate("product_listPrice", "Vejledende pris:") <span>@listPrice.ToString("#.00")</span> 557 </p> 558 <p class="price"> 559 <template v-if="'@isCampaign' == 'True'"> 560 <span class="price-campaigntext">@Translate(basicPimPrefix + "Campaign_price", "Kampagnepris")</span> 561 </template> 562 <span itemprop="price" class="price-actual" content="@priceWithVat"> 563 @priceWithVat 564 </span><span itemprop="priceCurrency" content="@Context.Currency.Code" class="hide"></span> 565 </p> 566 <p class="priceper"> 567 @Translate("product_pricePer", "Pris pr.") @unit.ToLower() @Translate("product_inclVat", "inkl. moms") 568 </p> 569 570 if (quantityPrices.Any()) 571 { 572 <ul class="list-inline qtyPrices"> 573 <li> 574 @Translate(basicPimPrefix + "quantity_prices_ex_moms", "Flerstk priser vises ekskl. moms") 575 </li> 576 @foreach (var quantityPrice in quantityPrices) 577 { 578 if (Model.Price.PriceWithVat > quantityPrice.Price) 579 { 580 <li> 581 <span>@Translate(basicPimPrefix + "Price pr. unit", "Fra") @quantityPrice.Quantity @unit.ToLower() </span> 582 <span class="qtyprice">{{@quantityPrice.Price | currency(true)}}</span> 583 </li> 584 } 585 } 586 </ul> 587 } 588 } 589 </div> 590 </div> 591 if (Model.GetProduct().IsActive) 592 { 593 <div class="basic_pim-action"> 594 <div class="basic_pim-buying"> 595 @if (mainIsCoolDown) 596 { 597 <substitute-products inline-template :item-number="'@Model.Number'"> 598 <div class="alert-wrapper" v-if="productList.length>0"> 599 <p class="alert alert-success"> 600 <b>@Translate("Substitutes", "Erstatningsvarer")</b> 601 <template v-for="(p,i) in productList"> 602 <div style="display: flex; cursor: pointer; margin-top: 8px;" @@click="clickSubProduct(p.Url)"> 603 <img src="/files/images/ecom/icons/product.png" width="20" height="20"/> 604 <div style="margin-left: 12px"> 605 <div style="font-size: 16px; font-weight: 500"> 606 {{p.Name}} 607 </div> 608 <div style="font-size: 12px; font-weight: 500"> 609 Varenr. {{p.Number}} 610 </div> 611 </div> 612 </div> 613 </template> 614 </p> 615 </div> 616 </substitute-products> 617 } 618 @{ 619 if (hasInsurance) 620 { 621 <div class="alert-wrapper"> 622 <p class="alert alert-success"> 623 <svg class="icon"> 624 <use xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="/Files/dist/icons/icons.svg#file-contract"></use> 625 </svg> 626 <strong>@Translate("Insurance news tag", "NYHED")</strong> @Translate("Insurance can be choosed", "På denne vare kan der tilkøbes forsikring") 627 </p> 628 </div> 629 } 630 } 631 @foreach (var i in Model.GeTaxProducts()) 632 { 633 <p class="charge"> 634 <span class="charge-name"> 635 @i.Name: 636 </span> 637 <span class="charge-price"> 638 @if (B2C) 639 { 640 @((i.Price + (vatPercent / 100 * i.Price)).ToString("#.00")) 641 } 642 else 643 { 644 @(i.Price.ToString("#.00")) 645 } 646 </span> 647 </p> 648 } 649 @if (minPurchase > 1) 650 { 651 <p class="minQty"> 652 <svg> 653 <use xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="/Files/dist/icons/icons.svg#info-circle"></use> 654 </svg> 655 <span> 656 @Translate("product_minPurchase", "Sælges kun i hele kolli á:") @minPurchase @unit.ToLower() 657 </span> 658 </p> 659 660 } 661 @if (Model.Variants != null && Model.Variants.Any()) 662 { 663 <div class="basic_pim-variants"> 664 <div class="basic_pim-variant"> 665 <div class="form-group"> 666 <label for="@Model.Id"> 667 @Translate(basicPimPrefix + "Variants", "Variants") 668 </label> 669 <select autocomplete="off" v-model="variant1" class="form-control" id="variantdropdown"> 670 <option selected value="">@Translate(basicPimPrefix + "PickVariant select", "- Vælg -")</option> 671 <option v-for="(variant,index) in variant1Options" :key="index">{{variant.variant1}}</option> 672 </select> 673 </div> 674 <div v-if="variant2Options.length > 0" class="form-group"> 675 <select v-model="variant2" class="form-control"> 676 <option value="">@Translate(basicPimPrefix + "PickVariant select", "- Vælg -")</option> 677 <option v-for="variant in variant2Options">{{variant.variant2}}</option> 678 </select> 679 </div> 680 </div> 681 </div> 682 } 683 <div class="basic_pim-buttons"> 684 <template> 685 @if (Pageview.User != null) 686 { 687 <favorite-item product-id="@Model.Id" 688 language-id="@Model.LanguageId" 689 :variant-id="variantId" 690 ref="favoriteItem"> 691 </favorite-item> 692 } 693 </template> 694 <template v-if="!noVariantPicked"> 695 <add-to-basket-rounding class="addtobasketrounding-pdp" 696 ref="basket" 697 :is-cool-down-product="isCoolDown" 698 button-class="btn @actionColor btn-icon" 699 product-id="@Model.Id" 700 :variant-id="variantId" 701 language-id="@Model.LanguageId" 702 min-purchase="@minPurchase" 703 escape-min-purch="@escapeMinPurch" 704 :has-montage="hasMontage" 705 :missing-variant="missingVariant" 706 unit-of-measure="@unit" 707 :is-b2c="@B2C.ToString().ToLower()"> 708 </add-to-basket-rounding> 709 </template> 710 </div> 711 </div> 712 </div> 713 } 714 else 715 { 716 <div class="alert-wrapper"> 717 <p class="alert alert-info"> 718 <svg> 719 <use xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="/files/dist/icons/icons.svg#tools"> 720 </use> 721 </svg> 722 @Translate("product-inactive", "Produktet er inaktivt og kan derfor ikke lægges i indkøbskurven.") 723 </p> 724 </div> 725 } 726 } 727 else 728 { 729 <div class="pricing"> 730 <div class="priceinfo"> 731 <p> 732 @{ 733 foreach (var logoGuid in sustainableLogoGuids) 734 { 735 if (!string.IsNullOrEmpty(logoGuid)) 736 { 737 <img src="@Pageview.CdnWrap("/Files/Images/Graphics/" + logoGuid + ".png")" 738 class="img-fluid" 739 style="max-height: 75px; margin-right: 8px"/> 740 } 741 } 742 } 743 </p> 744 <p class="basic_pim-sku iconed"> 745 <svg> 746 <use xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="/Files/dist/icons/icons.svg#barcode"></use> 747 </svg> 748 @Translate(basicPimPrefix + "Product number", "Product number"): <span itemprop="sku">@Model.Number</span> 749 </p> 750 </div> 751 </div> 752 <div class="basic_pim-action"> 753 <div class="basic_pim-buying"> 754 <div class="basic_pim-unauthed"> 755 756 <label class="btn btn-danger btn-lg btn-icon" for="login-toggle"> 757 <svg> 758 <use xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="/Files/dist/icons/icons.svg#user"></use> 759 </svg> 760 @Translate(basicPimPrefix + "Log in to see prices", "Log ind for at se priser og handle") 761 </label> 762 </div> 763 </div> 764 </div> 765 } 766 </div> 767 </section> 768 769 @if (showRelatedFirst.Equals(true)) 770 { 771 <section class="basic_view-related-wrap"> 772 @if (spareParts != null && spareParts.Any()) 773 { 774 <section class="basic_listview basic_view-related"> 775 <template> 776 <header> 777 <h2> 778 @Translate(basicPimPrefix + "Spare parts", "Spare parts") 779 </h2> 780 </header> 781 <div class="basic_listview-grid related"> 782 @foreach (var sparePartRelation in spareParts) 783 { 784 var sparePart = sparePartRelation.Product; 785 var url = urlService.GetProductUri(sparePart.Id, sparePart.VariantId); 786 var sparePartUnitId = sparePart.GetUnitId(); 787 var sparePartProductImage = sparePart.GetPrimaryImage(); 788 789 if (string.IsNullOrEmpty(sparePartProductImage)) 790 { 791 sparePartProductImage = "/Files/Images/Default.png"; 792 } 793 var sparePartListPrice = sparePart.GetListPrice(); 794 var sparePartMinPurchase = sparePart.GetMinPurchase(); 795 var sparePartEscapeMinPurch = sparePart.GetEscapeMinPurch(); 796 var sparePartABC = sparePart.GetAbcCategory(); 797 var sparePartIsCoolDown = sparePart.GetIsMainProductCoolDown(); 798 var sparePartDescriptions = sparePart.ProductFieldValues.Where(a => a.GetFieldName().Contains("Desc")).ToList(); 799 var sparePartIsCampaign = sparePart.IsCampaign(); 800 var sparePartPriceWithVat = sparePart.Price.PriceWithVAT.ToString("#.00"); 801 var sparePartAltText = sparePart.GetAltText(); 802 803 <article class="basic_view-related--product" ppp="@sparePart.Id"> 804 <div class="innerwrap"> 805 <a href="@url.PathAndQuery"> 806 <figure> 807 <img src="@Pageview.CdnWrap($"/Admin/Public/GetImage.ashx?Width=250&amp;Height=130&amp;Compression=85&amp;Crop=5&amp;Image={sparePartProductImage}")" 808 alt="@sparePartAltText" 809 itemprop="image" 810 class="img-fluid"/> 811 </figure> 812 </a> 813 <header> 814 <div> 815 <a href="@url.PathAndQuery" itemprop="url"> 816 <h1 itemprop="name">@sparePart.Name</h1> 817 <p itemprop="description"> 818 @if (sparePartDescriptions.Any()) 819 { 820 <span> 821 @foreach (var i in sparePartDescriptions) 822 { 823 @i.Value 824 } 825 </span> 826 } 827 </p> 828 </a> 829 <p class="sku"><span itemprop="sku">@Translate(basicPimPrefix + "Product Number", "Product Number") @sparePart.Number</span></p> 830 </div> 831 </header> 832 </div> 833 <footer> 834 <div class="basic_listview-pricing"> 835 @if (Pageview.User != null) 836 { 837 <async-price class-type="asyncprice-plp" 838 default-price-without-vat="@sparePart.Price.PriceWithoutVAT" 839 :is-cool-down-product="@sparePartIsCoolDown.ToString().ToLower()" 840 product-id="@sparePart.Id" 841 :variant-id="variantId" 842 unit-of-measure="@sparePartUnitId" 843 :list-price="@JsonConvert.SerializeObject(sparePartListPrice)" 844 is-campaign="@sparePartIsCampaign" 845 @@update-stock="setLiveStock"> 846 </async-price> 847 } 848 else if (B2C) 849 { 850 <p class="listprice" v-if="showListPrice(@sparePartListPrice, @sparePart.Price.PriceWithVAT)"> 851 @Translate("product_listPrice", "Vejledende pris:") <span>@sparePartListPrice.ToString("#.00")</span> 852 </p> 853 <p class="price"> 854 <template v-if="'@sparePartIsCampaign' == 'True'"> 855 <span class="price-campaigntext">@Translate(basicPimPrefix + "Campaign_price", "Kampagnepris")</span> 856 </template> 857 <span itemprop="price" class="price-actual" content="@sparePartPriceWithVat"> 858 @sparePartPriceWithVat 859 </span><span itemprop="priceCurrency" content="@Context.Currency.Code" class="hide"></span> 860 </p> 861 <p class="priceper"> 862 @Translate("product_pricePer", "Pris pr.") @unit.ToLower() @Translate("product_inclVat", "inkl. moms") 863 </p> 864 } 865 <div class="basic_listview-delivery only-grid"> 866 @if (!string.IsNullOrEmpty(sparePartABC)) 867 { 868 if (Pageview.User != null) 869 { 870 <p class="stockstatus" alt="@sparePartABC"> 871 @if (sparePartABC == "A") 872 { 873 <svg> 874 <use xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="/Files/dist/icons/icons.svg#truck"></use> 875 </svg> 876 <span>@Translate("ABC A Text", "Kort leveringstid")</span> 877 } 878 @if (sparePartABC == "B") 879 { 880 <svg> 881 <use xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="/Files/dist/icons/icons.svg#truck"></use> 882 </svg> 883 <span>@Translate("ABC B Text", "Forvent leveringstid")</span> 884 } 885 </p> 886 } 887 } 888 @if (sparePartMinPurchase > 1) 889 { 890 <p class="minQty"> 891 <svg> 892 <use xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="/Files/dist/icons/icons.svg#info-circle"></use> 893 </svg> 894 <span> 895 @Translate("product_minPurchase", "Sælges kun i hele kolli á:") @sparePartMinPurchase @sparePartUnitId.ToLower() 896 </span> 897 </p> 898 899 } 900 </div> 901 <div class="basic_listview-buttons"> 902 <div class="@(B2C ? "b2c" : "b2b")"> 903 @if ((B2C || Pageview.User != null) && sparePart.VariantCount == 0) 904 { 905 <add-to-basket-rounding class="addtobasketrounding-plp" 906 button-class="btn @actionColor btn-icon icon-only" 907 product-id="@sparePart.Id" 908 variant-id="@sparePart.VariantId" 909 language-id="@sparePart.LanguageId" 910 min-purchase="@sparePartMinPurchase" 911 :is-cool-down-product="@sparePartIsCoolDown.ToString().ToLower()" 912 escape-min-purch="@sparePartEscapeMinPurch" 913 :has-montage="false" 914 :missing-variant="false" 915 unit-of-measure="@sparePartUnitId" 916 :is-b2c="@B2C.ToString().ToLower()"> 917 </add-to-basket-rounding> 918 } 919 else 920 { 921 <a class="btn @actionColor" href="@url.PathAndQuery"> 922 @Translate("Show product", "Vis vare") 923 </a> 924 } 925 </div> 926 </div> 927 </div> 928 </footer> 929 </article> 930 } 931 </div> 932 </template> 933 </section> 934 } 935 936 @if (relatedProducts != null && relatedProducts.Any()) 937 { 938 <section class="basic_listview basic_view-related" id="related-products"> 939 <template> 940 <header> 941 <h2> 942 @Translate(basicPimPrefix + "Related Products", "Related Products") 943 </h2> 944 </header> 945 <div class="basic_listview-grid related"> 946 @foreach (var related in relatedProducts) 947 { 948 var relatedProduct = related.Product; 949 var url = urlService.GetProductUri(relatedProduct.Id, relatedProduct.VariantId); 950 var relatedUnitId = relatedProduct.GetUnitId(); 951 var relatedProductImage = relatedProduct.GetPrimaryImage(); 952 953 if (string.IsNullOrEmpty(relatedProductImage)) 954 { 955 relatedProductImage = "/Files/Images/Default.png"; 956 } 957 var relatedListPrice = relatedProduct.GetListPrice(); 958 var relatedMinPurchase = relatedProduct.GetMinPurchase(); 959 var relatedEscapeMinPurch = relatedProduct.GetEscapeMinPurch(); 960 var relatedIsCoolDown = relatedProduct.GetIsMainProductCoolDown(); 961 var relatedABC = relatedProduct.GetAbcCategory(); 962 var relatedProductDescriptions = relatedProduct.ProductFieldValues.Where(a => a.GetFieldName().Contains("Desc")).ToList(); 963 var relatedIsCampaign = relatedProduct.IsCampaign(); 964 var relatedPriceWithVat = relatedProduct.Price.PriceWithVAT.ToString("#.00"); 965 var relatedAltText = relatedProduct.GetAltText(); 966 967 <article class="basic_view-related--product" ppp="@relatedProduct.Id"> 968 <div class="innerwrap"> 969 <a href="@url.PathAndQuery"> 970 <figure> 971 <img src="@Pageview.CdnWrap($"/Admin/Public/GetImage.ashx?Width=250&amp;Height=130&amp;Compression=85&amp;Crop=5&amp;Image={relatedProductImage}")" 972 alt="@relatedAltText" 973 itemprop="image" 974 class="img-fluid"/> 975 </figure> 976 </a> 977 <header> 978 <div> 979 <a href="@url.PathAndQuery" itemprop="url"> 980 <h1 itemprop="name">@relatedProduct.Name</h1> 981 <p itemprop="description"> 982 @if (relatedProductDescriptions.Any()) 983 { 984 <span> 985 @foreach (var i in relatedProductDescriptions) 986 { 987 @i.Value 988 } 989 </span> 990 } 991 </p> 992 </a> 993 <p class="sku"><span itemprop="sku">@Translate(basicPimPrefix + "Product Number", "Product Number") @relatedProduct.Number</span></p> 994 </div> 995 </header> 996 </div> 997 <footer> 998 <div class="basic_listview-pricing"> 999 @if (Pageview.User != null) 1000 { 1001 <async-price class-type="asyncprice-plp" 1002 default-price-without-vat="@relatedProduct.Price.PriceWithoutVAT" 1003 product-id="@relatedProduct.Id" 1004 :variant-id="variantId" 1005 :is-cool-down-product="@relatedIsCoolDown.ToString().ToLower()" 1006 unit-of-measure="@relatedUnitId" 1007 :list-price="@JsonConvert.SerializeObject(relatedListPrice)" 1008 is-campaign="@relatedIsCampaign" 1009 @@update-stock="setLiveStock"> 1010 </async-price> 1011 } 1012 else if (B2C) 1013 { 1014 <p class="listprice" v-if="showListPrice(@relatedListPrice, @relatedProduct.Price.PriceWithVAT)"> 1015 @Translate("product_listPrice", "Vejledende pris:") <span>@relatedListPrice.ToString("#.00")</span> 1016 </p> 1017 <p class="price"> 1018 <template v-if="'@relatedIsCampaign' == 'True'"> 1019 <span class="price-campaigntext">@Translate(basicPimPrefix + "Campaign_price", "Kampagnepris")</span> 1020 </template> 1021 <span itemprop="price" class="price-actual" content="@relatedPriceWithVat"> 1022 @relatedPriceWithVat 1023 </span><span itemprop="priceCurrency" content="@Context.Currency.Code" class="hide"></span> 1024 </p> 1025 <p class="priceper"> 1026 @Translate("product_pricePer", "Pris pr.") @unit.ToLower() @Translate("product_inclVat", "inkl. moms") 1027 </p> 1028 } 1029 <div class="basic_listview-delivery only-grid"> 1030 @if (!string.IsNullOrEmpty(relatedABC) && relatedABC != "C") 1031 { 1032 if (Pageview.User != null) 1033 { 1034 <p class="stockstatus" alt="@relatedABC"> 1035 @if (relatedABC == "A") 1036 { 1037 <svg> 1038 <use xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="/Files/dist/icons/icons.svg#truck"></use> 1039 </svg> 1040 <span>@Translate("ABC A Text", "Kort leveringstid")</span> 1041 } 1042 @if (relatedABC == "B") 1043 { 1044 <svg> 1045 <use xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="/Files/dist/icons/icons.svg#truck"></use> 1046 </svg> 1047 <span>@Translate("ABC B Text", "Forvent leveringstid")</span> 1048 } 1049 </p> 1050 } 1051 } 1052 @if (relatedMinPurchase > 1) 1053 { 1054 <p class="minQty"> 1055 <svg> 1056 <use xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="/Files/dist/icons/icons.svg#info-circle"></use> 1057 </svg> 1058 <span> 1059 @Translate("product_minPurchase", "Sælges kun i hele kolli á:") @relatedMinPurchase @relatedUnitId.ToLower() 1060 </span> 1061 </p> 1062 1063 } 1064 </div> 1065 <div class="basic_listview-buttons"> 1066 <div class="@(B2C ? "b2c" : "b2b")"> 1067 @if ((B2C || Pageview.User != null) && relatedProduct.VariantCount == 0) 1068 { 1069 <add-to-basket-rounding class="addtobasketrounding-plp" 1070 ref="basket" 1071 button-class="btn @actionColor btn-icon icon-only" 1072 product-id="@relatedProduct.Id" 1073 variant-id="@relatedProduct.VariantId" 1074 language-id="@relatedProduct.LanguageId" 1075 min-purchase="@relatedMinPurchase" 1076 escape-min-purch="@relatedEscapeMinPurch" 1077 :is-cool-down-product="@relatedIsCoolDown.ToString().ToLower()" 1078 :has-montage="false" 1079 :missing-variant="false" 1080 unit-of-measure="@relatedUnitId" 1081 :is-b2c="@B2C.ToString().ToLower()"> 1082 </add-to-basket-rounding> 1083 } 1084 else 1085 { 1086 <a class="btn @actionColor" href="@url.PathAndQuery"> 1087 @Translate("Show product", "Vis vare") 1088 </a> 1089 } 1090 </div> 1091 </div> 1092 </div> 1093 </footer> 1094 </article> 1095 } 1096 </div> 1097 </template> 1098 </section> 1099 } 1100 </section> 1101 1102 1103 } 1104 1105 <section class="basic_pim-specs" id="descspec"> 1106 <div class="basic_pim-spec" style="min-width: 50%" id="desc"> 1107 <h2>@Translate(basicPimPrefix + "Description", "Description")</h2> 1108 <div itemprop="description"> 1109 @Model.LongDescription 1110 </div> 1111 </div> 1112 @if (listedSpecs.Any()) 1113 { 1114 <div class="basic_pim-spec"> 1115 <header id="spec"> 1116 <h2>@Translate(basicPimPrefix + "Specifications", "Specifications")</h2> 1117 </header> 1118 <main> 1119 @if (isExtendedPdp) 1120 { 1121 <div> 1122 @if (!string.IsNullOrEmpty(documentationSecurityPaper.Value) || !string.IsNullOrEmpty(documentationProductPaper.Value) || !string.IsNullOrEmpty(documentationLink.Value)) 1123 { 1124 <ul class="list-inline list-docs"> 1125 @RenderDocumentation(documentationSecurityPaper) 1126 @RenderDocumentation(documentationProductPaper) 1127 @RenderDocumentation(documentationLink) 1128 </ul> 1129 } 1130 <div class="spec-list basic_filter"> 1131 <div class="basic_filter-groups"> 1132 @foreach (var item in specs.Where(a => extendedFields.Contains(a.Key)).GroupBy(x => x.Group2Order).OrderBy(x => x.Key)) 1133 { 1134 var collapse = "v-b-toggle.collapse-" + item.Key; 1135 1136 <p class="basic_filter-group" area-expanded="false" @collapse> 1137 <strong style="font-size: 16px">@item.First().Group2</strong> 1138 <svg> 1139 <use xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="/Files/dist/icons/icons.svg#chevron-right"></use> 1140 </svg> 1141 </p> 1142 1143 <b-collapse id="collapse-@item.Key" class="mt-2"> 1144 1145 <ul class="list-unstyled list-tabled"> 1146 @foreach (var group in item) 1147 { 1148 <li style="max-height: 30px"> 1149 @{ 1150 double result; 1151 string value = group.Value; 1152 if (double.TryParse(group.Value, NumberStyles.AllowDecimalPoint, CultureInfo.InvariantCulture, out result) && value.Contains('.')) 1153 { 1154 value = value.Replace('.', ','); 1155 } 1156 <span style="font-weight: 500"><nobr>@group.Caption</nobr></span> 1157 <span>@value @group.Unit</span> 1158 } 1159 </li> 1160 } 1161 </ul> 1162 1163 </b-collapse> 1164 } 1165 </div> 1166 </div> 1167 </div> 1168 1169 } 1170 else 1171 { 1172 <div> 1173 @if (!string.IsNullOrEmpty(documentationSecurityPaper.Value) || !string.IsNullOrEmpty(documentationProductPaper.Value) || !string.IsNullOrEmpty(documentationLink.Value)) 1174 { 1175 <ul class="list-inline list-docs"> 1176 @RenderDocumentation(documentationSecurityPaper) 1177 @RenderDocumentation(documentationProductPaper) 1178 @RenderDocumentation(documentationLink) 1179 </ul> 1180 } 1181 <table class="table table-darker table-striped table-split"> 1182 <tbody> 1183 @foreach (var specKey in listedSpecs) 1184 { 1185 var specValues = specs.GetAllByKey(specKey).ToList(); 1186 var count = specValues.Count; 1187 <tr> 1188 <th>@specValues.First().Caption</th> 1189 <td> 1190 @if (count > 1) 1191 { 1192 <ul class="list-unstyled"> 1193 @foreach (var spec in specValues) 1194 { 1195 bool valueBool; 1196 var value = spec.Value; 1197 if (bool.TryParse(value, out valueBool)) 1198 { 1199 value = valueBool ? Translate("spec_yes", "Ja") : Translate("spec_no", "Nej"); 1200 } 1201 1202 double result; 1203 if (double.TryParse(value, NumberStyles.AllowDecimalPoint, CultureInfo.InvariantCulture, out result) && value.Contains('.')) 1204 { 1205 value = value.Replace('.', ','); 1206 } 1207 1208 <li>@value @spec.Unit</li> 1209 } 1210 </ul> 1211 } 1212 else 1213 { 1214 bool valueBool; 1215 var value = specValues.First().Value; 1216 if (bool.TryParse(value, out valueBool)) 1217 { 1218 value = valueBool ? Translate("spec_yes", "Ja") : Translate("spec_no", "Nej"); 1219 } 1220 1221 double result; 1222 if (double.TryParse(value, NumberStyles.AllowDecimalPoint, CultureInfo.InvariantCulture, out result) && value.Contains('.')) 1223 { 1224 value = value.Replace('.', ','); 1225 } 1226 1227 <span>@value @specValues.First().Unit </span> 1228 } 1229 </td> 1230 </tr> 1231 } 1232 </tbody> 1233 </table> 1234 </div> 1235 if (!string.IsNullOrEmpty(energyLabel)) 1236 { 1237 <div class="text-center wrap-energy" id="energylabel"> 1238 <img src="@energyLabel" class="img-fluid energylabel" alt="@Model.Number"/><br/> 1239 <a href="@energyLabel" class="iconed"> 1240 @Translate(basicPimPrefix + "Download energy mark", "Download") 1241 </a> 1242 </div> 1243 } 1244 } 1245 </main> 1246 1247 </div> 1248 if (isExtendedPdp && !string.IsNullOrEmpty(energyLabel)) 1249 { 1250 <div class="basic_pim-spec text-center wrap-energy" style="max-width: 210px; margin-top: -20px" id="energylabel"> 1251 @*<ul class="list-inline list-docs"> 1252 <li class="list-inline-item"> 1253 <a href="@energyLabel" class="iconed"> 1254 <svg class="dark"> 1255 <use xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="/Files/dist/icons/icons.svg#file-pdf"></use> 1256 </svg> 1257 @Translate(basicPimPrefix + "Download energy mark", "Download") 1258 </a> 1259 </li> 1260 </ul>*@ 1261 <img src="@energyLabel" class="img-fluid energylabel" alt="@Model.Number"/><br/> 1262 <a href="@energyLabel" class="iconed"> 1263 @Translate(basicPimPrefix + "Download energy mark", "Download") 1264 </a> 1265 </div> 1266 } 1267 } 1268 </section> 1269 @if (isExtendedPdp) 1270 { 1271 @*<section class="basic_pim-features" id="features"> 1272 <div class="fea"> 1273 <h2>Features</h2> 1274 <ul class="list-unstyled list-features"> 1275 <li> 1276 <img src="https://picsum.photos/210/140" alt="featureTitle" class="img-fluid" /> 1277 <div> 1278 <h5>Madlavningstermometer</h5> 1279 <p> 1280 Universal termometer til brød, kager og alle typer kød. Med det integrerede madlavningstermometer kan du måle kernetemperaturen af din ret under tilberedningen. 1281 Så får du perfekte resultater hver gang. Madlavningstermometeret er ideel til både stegning og bagning. Visse modeller har madlavningstermometer med autosluk: 1282 Ovnen slukker automatisk, når indstillede kernetemperatur er opnået. Derved undgås unødig overtilberedning. 1283 </p> 1284 </div> 1285 </li> 1286 <li> 1287 <img src="https://picsum.photos/210/140" alt="featureTitle" class="img-fluid" /> 1288 <div> 1289 <h5>Madlavningstermometer</h5> 1290 <p> 1291 Universal termometer til brød, kager og alle typer kød. Med det integrerede madlavningstermometer kan du måle kernetemperaturen af din ret under tilberedningen. 1292 Så får du perfekte resultater hver gang. Madlavningstermometeret er ideel til både stegning og bagning. 1293 </p> 1294 </div> 1295 </li> 1296 <li> 1297 <img src="https://picsum.photos/210/140" alt="featureTitle" class="img-fluid" /> 1298 <div> 1299 <h5>Madlavningstermometer</h5> 1300 <p> 1301 Med det integrerede madlavningstermometer kan du måle kernetemperaturen af din ret under tilberedningen. 1302 Visse modeller har madlavningstermometer med autosluk: 1303 Ovnen slukker automatisk, når indstillede kernetemperatur er opnået. Derved undgås unødig overtilberedning. 1304 </p> 1305 </div> 1306 </li> 1307 </ul> 1308 </div> 1309 </section>*@ 1310 } 1311 @if (!showRelatedFirst.Equals(true)) 1312 { 1313 <section class="basic_view-related-wrap"> 1314 @if (spareParts != null && spareParts.Any()) 1315 { 1316 <section class="basic_listview basic_view-related"> 1317 <template> 1318 <header> 1319 <h2> 1320 @Translate(basicPimPrefix + "Spare parts", "Spare parts") 1321 </h2> 1322 </header> 1323 <div class="basic_listview-grid related"> 1324 @foreach (var sparePartRelation in spareParts) 1325 { 1326 var sparePart = sparePartRelation.Product; 1327 var url = urlService.GetProductUri(sparePart.Id, sparePart.VariantId); 1328 var sparePartUnitId = sparePart.GetUnitId(); 1329 var sparePartProductImage = sparePart.GetPrimaryImage(); 1330 1331 if (string.IsNullOrEmpty(sparePartProductImage)) 1332 { 1333 sparePartProductImage = "/Files/Images/Default.png"; 1334 } 1335 var sparePartListPrice = sparePart.GetListPrice(); 1336 var sparePartMinPurchase = sparePart.GetMinPurchase(); 1337 var sparePartEscapeMinPurch = sparePart.GetEscapeMinPurch(); 1338 var sparePartABC = sparePart.GetAbcCategory(); 1339 var sparePartDescriptions = sparePart.ProductFieldValues.Where(a => a.GetFieldName().Contains("Desc")).ToList(); 1340 var sparePartIsCampaign = sparePart.IsCampaign(); 1341 var sparePartPriceWithVat = sparePart.Price.PriceWithVAT.ToString("#.00"); 1342 var sparePartAltText = sparePart.GetAltText(); 1343 var sparePartIsCoolDown = sparePart.GetIsMainProductCoolDown(); 1344 1345 <article class="basic_view-related--product" ppp="@sparePart.Id"> 1346 <div class="innerwrap"> 1347 <a href="@url.PathAndQuery"> 1348 <figure> 1349 <img src="@Pageview.CdnWrap($"/Admin/Public/GetImage.ashx?Width=250&amp;Height=130&amp;Compression=85&amp;Crop=5&amp;Image={sparePartProductImage}")" 1350 alt="@sparePartAltText" 1351 itemprop="image" 1352 class="img-fluid"/> 1353 </figure> 1354 </a> 1355 <header> 1356 <div> 1357 <a href="@url.PathAndQuery" itemprop="url"> 1358 <h1 itemprop="name">@sparePart.Name</h1> 1359 <p itemprop="description"> 1360 @if (sparePartDescriptions.Any()) 1361 { 1362 <span> 1363 @foreach (var i in sparePartDescriptions) 1364 { 1365 @i.Value 1366 } 1367 </span> 1368 } 1369 </p> 1370 </a> 1371 <p class="sku"><span itemprop="sku">@Translate(basicPimPrefix + "Product Number", "Product Number") @sparePart.Number</span></p> 1372 </div> 1373 </header> 1374 </div> 1375 <footer> 1376 <div class="basic_listview-pricing"> 1377 @if (Pageview.User != null) 1378 { 1379 <async-price class-type="asyncprice-plp" 1380 default-price-without-vat="@sparePart.Price.PriceWithoutVAT" 1381 product-id="@sparePart.Id" 1382 :is-cool-down-product="@sparePartIsCoolDown.ToString().ToLower()" 1383 :variant-id="variantId" 1384 unit-of-measure="@sparePartUnitId" 1385 :list-price="@JsonConvert.SerializeObject(sparePartListPrice)" 1386 is-campaign="@sparePartIsCampaign" 1387 @@update-stock="setLiveStock"> 1388 </async-price> 1389 } 1390 else if (B2C) 1391 { 1392 <p class="listprice" v-if="showListPrice(@sparePartListPrice, @sparePart.Price.PriceWithVAT)"> 1393 @Translate("product_listPrice", "Vejledende pris:") <span>@sparePartListPrice.ToString("#.00")</span> 1394 </p> 1395 <p class="price"> 1396 <template v-if="'@sparePartIsCampaign' == 'True'"> 1397 <span class="price-campaigntext">@Translate(basicPimPrefix + "Campaign_price", "Kampagnepris")</span> 1398 </template> 1399 <span itemprop="price" class="price-actual" content="@sparePartPriceWithVat"> 1400 @sparePartPriceWithVat 1401 </span><span itemprop="priceCurrency" content="@Context.Currency.Code" class="hide"></span> 1402 </p> 1403 <p class="priceper"> 1404 @Translate("product_pricePer", "Pris pr.") @unit.ToLower() @Translate("product_inclVat", "inkl. moms") 1405 </p> 1406 } 1407 <div class="basic_listview-delivery only-grid"> 1408 @if (!string.IsNullOrEmpty(sparePartABC)) 1409 { 1410 if (Pageview.User != null) 1411 { 1412 <p class="stockstatus" alt="@sparePartABC"> 1413 @if (sparePartABC == "A") 1414 { 1415 <svg> 1416 <use xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="/Files/dist/icons/icons.svg#truck"></use> 1417 </svg> 1418 <span>@Translate("ABC A Text", "Kort leveringstid")</span> 1419 } 1420 @if (sparePartABC == "B") 1421 { 1422 <svg> 1423 <use xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="/Files/dist/icons/icons.svg#truck"></use> 1424 </svg> 1425 <span>@Translate("ABC B Text", "Forvent leveringstid")</span> 1426 } 1427 </p> 1428 } 1429 } 1430 @if (sparePartMinPurchase > 1) 1431 { 1432 <p class="minQty"> 1433 <svg> 1434 <use xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="/Files/dist/icons/icons.svg#info-circle"></use> 1435 </svg> 1436 <span> 1437 @Translate("product_minPurchase", "Sælges kun i hele kolli á:") @sparePartMinPurchase @sparePartUnitId.ToLower() 1438 </span> 1439 </p> 1440 1441 } 1442 </div> 1443 <div class="basic_listview-buttons"> 1444 <div class="@(B2C ? "b2c" : "b2b")"> 1445 @if ((B2C || Pageview.User != null) && sparePart.VariantCount == 0) 1446 { 1447 <add-to-basket-rounding class="addtobasketrounding-plp" 1448 button-class="btn @actionColor btn-icon icon-only" 1449 product-id="@sparePart.Id" 1450 variant-id="@sparePart.VariantId" 1451 language-id="@sparePart.LanguageId" 1452 min-purchase="@sparePartMinPurchase" 1453 escape-min-purch="@sparePartEscapeMinPurch" 1454 :is-cool-down-product="@sparePartIsCoolDown.ToString().ToLower()" 1455 :has-montage="false" 1456 :missing-variant="false" 1457 unit-of-measure="@sparePartUnitId" 1458 :is-b2c="@B2C.ToString().ToLower()"> 1459 </add-to-basket-rounding> 1460 } 1461 else 1462 { 1463 <a class="btn @actionColor" href="@url.PathAndQuery"> 1464 @Translate("Show product", "Vis vare") 1465 </a> 1466 } 1467 </div> 1468 </div> 1469 </div> 1470 </footer> 1471 </article> 1472 } 1473 </div> 1474 </template> 1475 </section> 1476 } 1477 1478 @if (relatedProducts != null && relatedProducts.Any()) 1479 { 1480 <section class="basic_listview basic_view-related" id="related-products"> 1481 <template> 1482 <header> 1483 <h2> 1484 @Translate(basicPimPrefix + "Related Products", "Related Products") 1485 </h2> 1486 </header> 1487 <div class="basic_listview-grid related"> 1488 @foreach (var related in relatedProducts) 1489 { 1490 var relatedProduct = related.Product; 1491 var url = urlService.GetProductUri(relatedProduct.Id, relatedProduct.VariantId); 1492 var relatedUnitId = relatedProduct.GetUnitId(); 1493 var relatedProductImage = relatedProduct.GetPrimaryImage(); 1494 1495 if (string.IsNullOrEmpty(relatedProductImage)) 1496 { 1497 relatedProductImage = "/Files/Images/Default.png"; 1498 } 1499 var relatedListPrice = relatedProduct.GetListPrice(); 1500 var relatedMinPurchase = relatedProduct.GetMinPurchase(); 1501 var relatedEscapeMinPurch = relatedProduct.GetEscapeMinPurch(); 1502 var relatedABC = relatedProduct.GetAbcCategory(); 1503 var relatedProductDescriptions = relatedProduct.ProductFieldValues.Where(a => a.GetFieldName().Contains("Desc")).ToList(); 1504 var relatedIsCampaign = relatedProduct.IsCampaign(); 1505 var relatedPriceWithVat = relatedProduct.Price.PriceWithVAT.ToString("#.00"); 1506 var relatedAltText = relatedProduct.GetAltText(); 1507 var relatedProductIsCoolDown = relatedProduct.GetIsMainProductCoolDown(); 1508 1509 <article class="basic_view-related--product" ppp="@relatedProduct.Id"> 1510 <div class="innerwrap"> 1511 <a href="@url.PathAndQuery"> 1512 <figure> 1513 <img src="@Pageview.CdnWrap($"/Admin/Public/GetImage.ashx?Width=250&amp;Height=130&amp;Compression=85&amp;Crop=5&amp;Image={relatedProductImage}")" 1514 alt="@relatedAltText" 1515 itemprop="image" 1516 class="img-fluid"/> 1517 </figure> 1518 </a> 1519 <header> 1520 <div> 1521 <a href="@url.PathAndQuery" itemprop="url"> 1522 <h1 itemprop="name">@relatedProduct.Name</h1> 1523 <p itemprop="description"> 1524 @if (relatedProductDescriptions.Any()) 1525 { 1526 <span> 1527 @foreach (var i in relatedProductDescriptions) 1528 { 1529 @i.Value 1530 } 1531 </span> 1532 } 1533 </p> 1534 </a> 1535 <p class="sku"><span itemprop="sku">@Translate(basicPimPrefix + "Product Number", "Product Number") @relatedProduct.Number</span></p> 1536 1537 <p> 1538 @{ 1539 foreach (var logo in relatedProduct.GetSustainableLogos()) 1540 { 1541 if (!string.IsNullOrEmpty(logo)) 1542 { 1543 var path = "/Files/Images/Graphics/" + logo + ".png"; 1544 <img src="@path" class="img-fluid" style="max-height: 40px; margin-right: 5px"/> 1545 } 1546 } 1547 } 1548 </p> 1549 </div> 1550 </header> 1551 </div> 1552 <footer> 1553 <div class="basic_listview-pricing"> 1554 @if (Pageview.User != null) 1555 { 1556 <async-price class-type="asyncprice-plp" 1557 default-price-without-vat="@relatedProduct.Price.PriceWithoutVAT" 1558 product-id="@relatedProduct.Id" 1559 :variant-id="variantId" 1560 unit-of-measure="@relatedUnitId" 1561 :is-cool-down-product="@relatedProductIsCoolDown.ToString().ToLower()" 1562 :list-price="@JsonConvert.SerializeObject(relatedListPrice)" 1563 is-campaign="@relatedIsCampaign" 1564 @@update-stock="setLiveStock"> 1565 </async-price> 1566 } 1567 else if (B2C) 1568 { 1569 <p class="listprice" v-if="showListPrice(@relatedListPrice, @relatedProduct.Price.PriceWithVAT)"> 1570 @Translate("product_listPrice", "Vejledende pris:") <span>@relatedListPrice.ToString("#.00")</span> 1571 </p> 1572 <p class="price"> 1573 <template v-if="'@relatedIsCampaign' == 'True'"> 1574 <span class="price-campaigntext">@Translate(basicPimPrefix + "Campaign_price", "Kampagnepris")</span> 1575 </template> 1576 <span itemprop="price" class="price-actual" content="@relatedPriceWithVat"> 1577 @relatedPriceWithVat 1578 </span><span itemprop="priceCurrency" content="@Context.Currency.Code" class="hide"></span> 1579 </p> 1580 <p class="priceper"> 1581 @Translate("product_pricePer", "Pris pr.") @unit.ToLower() @Translate("product_inclVat", "inkl. moms") 1582 </p> 1583 } 1584 <div class="basic_listview-delivery only-grid"> 1585 @if (!string.IsNullOrEmpty(relatedABC) && relatedABC != "C") 1586 { 1587 if (Pageview.User != null) 1588 { 1589 <p class="stockstatus" alt="@relatedABC"> 1590 @if (relatedABC == "A") 1591 { 1592 <svg> 1593 <use xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="/Files/dist/icons/icons.svg#truck"></use> 1594 </svg> 1595 <span>@Translate("ABC A Text", "Kort leveringstid")</span> 1596 } 1597 @if (relatedABC == "B") 1598 { 1599 <svg> 1600 <use xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="/Files/dist/icons/icons.svg#truck"></use> 1601 </svg> 1602 <span>@Translate("ABC B Text", "Forvent leveringstid")</span> 1603 } 1604 </p> 1605 } 1606 } 1607 @if (relatedMinPurchase > 1) 1608 { 1609 <p class="minQty"> 1610 <svg> 1611 <use xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="/Files/dist/icons/icons.svg#info-circle"></use> 1612 </svg> 1613 <span> 1614 @Translate("product_minPurchase", "Sælges kun i hele kolli á:") @relatedMinPurchase @relatedUnitId.ToLower() 1615 </span> 1616 </p> 1617 1618 } 1619 </div> 1620 <div class="basic_listview-buttons"> 1621 <div class="@(B2C ? "b2c" : "b2b")"> 1622 @if ((B2C || Pageview.User != null) && relatedProduct.VariantCount == 0) 1623 { 1624 <add-to-basket-rounding class="addtobasketrounding-plp" 1625 ref="basket" 1626 button-class="btn @actionColor btn-icon icon-only" 1627 product-id="@relatedProduct.Id" 1628 variant-id="@relatedProduct.VariantId" 1629 language-id="@relatedProduct.LanguageId" 1630 min-purchase="@relatedMinPurchase" 1631 escape-min-purch="@relatedEscapeMinPurch" 1632 :is-cool-down-product="@relatedProductIsCoolDown.ToString().ToLower()" 1633 :has-montage="false" 1634 :missing-variant="false" 1635 unit-of-measure="@relatedUnitId" 1636 :is-b2c="@B2C.ToString().ToLower()"> 1637 </add-to-basket-rounding> 1638 } 1639 else 1640 { 1641 <a class="btn @actionColor" href="@url.PathAndQuery"> 1642 @Translate("Show product", "Vis vare") 1643 </a> 1644 } 1645 </div> 1646 </div> 1647 </div> 1648 </footer> 1649 </article> 1650 } 1651 </div> 1652 </template> 1653 </section> 1654 } 1655 </section> 1656 1657 1658 } 1659 1660 </div> 1661 </product-details-simple-pim> 1662 @helper RenderDocumentation(ProductSpecification productSpecification) 1663 { 1664 if (string.IsNullOrEmpty(productSpecification.Value)) 1665 { 1666 return; 1667 } 1668 <li class="list-inline-item"> 1669 <a href="@productSpecification.Value" class="iconed"> 1670 <svg class="dark"> 1671 <use xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="/Files/dist/icons/icons.svg#file-pdf"></use> 1672 </svg> 1673 @productSpecification.Key 1674 </a> 1675 </li> 1676 } 1677
Gå til toppen